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);
-- 
2.43.0

Reply via email to