aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengpeng Hou <hppiscas@163.com>2026-09-20 11:43:29 +0800
committerBrajesh Gupta <brajesh.gupta@imgtec.com>2026-09-24 14:59:22 +0530
commit45585c3aa285854face65293acc95eff73063d6d (patch)
tree4b0a0869e755b8ac23b9e73ec2e126a57b282f41
parent0a8224058a5835297dcf4a46bbcd16f77a9fe424 (diff)
drm/imagination: clamp freelist reconstruction requests
The firmware reconstruction count controls accesses to the request's fixed freelist ID array and the copy into the fixed response array. Neither access currently bounds the count to those protocol arrays. Clamp the count to the request capacity, which is shared by the response layout, and use that count consistently for reconstruction and response publication. Keep the firmware recovery exchange instead of dropping an oversized request without a response, as discussed with the firmware maintainer. The issue was found by our static-analysis tool. Fixes: 6eedddab733b ("drm/imagination: Implement free list and HWRT create and destroy ioctls") Assisted-by: gpt 5 Signed-off-by: Pengpeng Hou <hppiscas@163.com> Reviewed-by: Alessio Belle <alessio.belle@imgtec.com> Link: https://patch.msgid.link/20260920034329.16614-1-hppiscas@163.com Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
-rw-r--r--drivers/gpu/drm/imagination/pvr_free_list.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/gpu/drm/imagination/pvr_free_list.c b/drivers/gpu/drm/imagination/pvr_free_list.c
index e85cac83834c..faf5e586d8dc 100644
--- a/drivers/gpu/drm/imagination/pvr_free_list.c
+++ b/drivers/gpu/drm/imagination/pvr_free_list.c
@@ -8,6 +8,7 @@
#include "pvr_vm.h"
#include <drm/drm_gem.h>
+#include <drm/drm_print.h>
#include <linux/slab.h>
#include <linux/xarray.h>
#include <uapi/drm/pvr_drm.h>
@@ -612,13 +613,21 @@ pvr_free_list_process_reconstruct_req(struct pvr_device *pvr_dev,
};
struct rogue_fwif_freelists_reconstruction_data *resp =
&resp_cmd.cmd_data.free_lists_reconstruction_data;
+ u32 count = min_t(u32, req->freelist_count,
+ ARRAY_SIZE(req->freelist_ids));
- for (u32 i = 0; i < req->freelist_count; i++)
+ if (count != req->freelist_count) {
+ drm_warn_once(from_pvr_device(pvr_dev),
+ "Requested reconstruction of %u freelists, limiting to %u\n",
+ req->freelist_count, count);
+ }
+
+ for (u32 i = 0; i < count; i++)
pvr_free_list_reconstruct(pvr_dev, req->freelist_ids[i]);
- resp->freelist_count = req->freelist_count;
+ resp->freelist_count = count;
memcpy(resp->freelist_ids, req->freelist_ids,
- req->freelist_count * sizeof(resp->freelist_ids[0]));
+ count * sizeof(resp->freelist_ids[0]));
WARN_ON(pvr_kccb_send_cmd(pvr_dev, &resp_cmd, NULL));
}