On 01-Sep-26 14:57, Dawid Osuchowski wrote:
From: Magdalena Schulfer <[email protected]>

Add a size parameter to ivpu_to_cpu_addr() and validate that the
whole [vpu_addr, vpu_addr + size) range stays within the BO.

Cc: [email protected]
Fixes: 647371a6609d ("accel/ivpu: Add GEM buffer object management")
Signed-off-by: Magdalena Schulfer <[email protected]>
Signed-off-by: Dawid Osuchowski <[email protected]>
---
  drivers/accel/ivpu/ivpu_gem.h | 14 +++++++++++---
  drivers/accel/ivpu/ivpu_ipc.c |  7 ++++---
  2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h
index 0c3350f22b55..b1ae020a4fc2 100644
--- a/drivers/accel/ivpu/ivpu_gem.h
+++ b/drivers/accel/ivpu/ivpu_gem.h
@@ -87,15 +87,23 @@ static inline bool ivpu_bo_is_resident(struct ivpu_bo *bo)
        return !!bo->base.pages;
  }
-static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
+static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u64 vpu_addr, u64 
size)
  {
+       u64 bo_size = ivpu_bo_size(bo);
+       u64 offset;
+
        if (vpu_addr < bo->vpu_addr)
                return NULL;
- if (vpu_addr >= (bo->vpu_addr + ivpu_bo_size(bo)))
+       if (size > bo_size)
+               return NULL;
+
+       offset = vpu_addr - bo->vpu_addr;
+
+       if (offset > bo_size - size)
                return NULL;
- return ivpu_bo_vaddr(bo) + (vpu_addr - bo->vpu_addr);
+       return ivpu_bo_vaddr(bo) + offset;
  }
static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr)
diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c
index 978bc3d8704f..8f69fb133e2e 100644
--- a/drivers/accel/ivpu/ivpu_ipc.c
+++ b/drivers/accel/ivpu/ivpu_ipc.c
@@ -79,7 +79,7 @@ ivpu_ipc_tx_prepare(struct ivpu_device *vdev, struct 
ivpu_ipc_consumer *cons,
                return -ENOMEM;
        }
- tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr);
+       tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr, 
sizeof(*tx_buf));
        if (drm_WARN_ON(&vdev->drm, !tx_buf)) {
                gen_pool_free(ipc->mm_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
                return -EIO;
@@ -420,7 +420,7 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev)
                        return;
                }
- ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr);
+               ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr, 
sizeof(*ipc_hdr));
                if (!ipc_hdr) {
                        ivpu_warn_ratelimited(vdev, "IPC msg 0x%x out of 
range\n", vpu_addr);
                        continue;
@@ -429,7 +429,8 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev)
jsm_msg = NULL;
                if (ipc_hdr->channel != IVPU_IPC_CHAN_BOOT_MSG) {
-                       jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, 
ipc_hdr->data_addr);
+                       jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, 
ipc_hdr->data_addr,
+                                                  sizeof(*jsm_msg));
                        if (!jsm_msg) {
                                ivpu_warn_ratelimited(vdev, "JSM msg 0x%x out of 
range\n",
                                                      ipc_hdr->data_addr);
Reviewed-by: Karol Wachowski <[email protected]>

Reply via email to