On 12/15/2025 6:49 PM, Lizhi Hou wrote:
> Reviewed-by: Lizhi Hou <[email protected]>
Thank you. Applied to drm-misc-next.

Karol>
> On 12/14/25 23:09, Karol Wachowski wrote:
>> Validate scatter-gather table size matches buffer object size before
>> mapping. Break mapping early if the table exceeds buffer size to
>> prevent overwriting existing mappings. Also validate the table is
>> not smaller than buffer size to avoid unmapped regions that trigger
>> MMU translation faults.
>>
>> Log error and fail mapping operation on size mismatch to prevent
>> data corruption from mismatched host memory locations and NPU
>> addresses. Unmap any partially mapped buffer on failure.
>>
>> Signed-off-by: Karol Wachowski <[email protected]>
>> ---
>>   drivers/accel/ivpu/ivpu_gem.c         |  2 +-
>>   drivers/accel/ivpu/ivpu_mmu_context.c | 20 +++++++++++++++++---
>>   drivers/accel/ivpu/ivpu_mmu_context.h |  5 +++--
>>   3 files changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/
>> ivpu_gem.c
>> index ece68f570b7e..98b9ce26962b 100644
>> --- a/drivers/accel/ivpu/ivpu_gem.c
>> +++ b/drivers/accel/ivpu/ivpu_gem.c
>> @@ -95,7 +95,7 @@ int __must_check ivpu_bo_bind(struct ivpu_bo *bo)
>>         if (!bo->mmu_mapped) {
>>           drm_WARN_ON(&vdev->drm, !bo->ctx);
>> -        ret = ivpu_mmu_context_map_sgt(vdev, bo->ctx, bo->vpu_addr, sgt,
>> +        ret = ivpu_mmu_context_map_sgt(vdev, bo->ctx, bo->vpu_addr,
>> sgt, ivpu_bo_size(bo),
>>                              ivpu_bo_is_snooped(bo),
>> ivpu_bo_is_read_only(bo));
>>           if (ret) {
>>               ivpu_err(vdev, "Failed to map BO in MMU: %d\n", ret);
>> diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/
>> ivpu/ivpu_mmu_context.c
>> index 87ad593ef47d..c4014c83e727 100644
>> --- a/drivers/accel/ivpu/ivpu_mmu_context.c
>> +++ b/drivers/accel/ivpu/ivpu_mmu_context.c
>> @@ -429,11 +429,12 @@ static void ivpu_mmu_context_unmap_pages(struct
>> ivpu_mmu_context *ctx, u64 vpu_a
>>   }
>>     int
>> -ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx,
>> -             u64 vpu_addr, struct sg_table *sgt, bool llc_coherent,
>> bool read_only)
>> +ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx, u64 vpu_addr,
>> +             struct sg_table *sgt, size_t bo_size, bool llc_coherent,
>> bool read_only)
>>   {
>>       size_t start_vpu_addr = vpu_addr;
>>       struct scatterlist *sg;
>> +    size_t sgt_size = 0;
>>       int ret;
>>       u64 prot;
>>       u64 i;
>> @@ -462,12 +463,25 @@ ivpu_mmu_context_map_sgt(struct ivpu_device
>> *vdev, struct ivpu_mmu_context *ctx,
>>           ivpu_dbg(vdev, MMU_MAP, "Map ctx: %u dma_addr: 0x%llx
>> vpu_addr: 0x%llx size: %lu\n",
>>                ctx->id, dma_addr, vpu_addr, size);
>>   +        if (sgt_size + size > bo_size) {
>> +            ivpu_err(vdev, "Scatter-gather table size exceeds buffer
>> object size\n");
>> +            ret = -EINVAL;
>> +            goto err_unmap_pages;
>> +        }
>> +
>>           ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr,
>> dma_addr, size, prot);
>>           if (ret) {
>>               ivpu_err(vdev, "Failed to map context pages\n");
>>               goto err_unmap_pages;
>>           }
>>           vpu_addr += size;
>> +        sgt_size += size;
>> +    }
>> +
>> +    if (sgt_size < bo_size) {
>> +        ivpu_err(vdev, "Scatter-gather table size too small to cover
>> buffer object size\n");
>> +        ret = -EINVAL;
>> +        goto err_unmap_pages;
>>       }
>>         if (!ctx->is_cd_valid) {
>> @@ -493,7 +507,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev,
>> struct ivpu_mmu_context *ctx,
>>       return 0;
>>     err_unmap_pages:
>> -    ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, vpu_addr -
>> start_vpu_addr);
>> +    ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, sgt_size);
>>       mutex_unlock(&ctx->lock);
>>       return ret;
>>   }
>> diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/
>> ivpu/ivpu_mmu_context.h
>> index 663a11a9db11..cc02e7bab04e 100644
>> --- a/drivers/accel/ivpu/ivpu_mmu_context.h
>> +++ b/drivers/accel/ivpu/ivpu_mmu_context.h
>> @@ -41,8 +41,9 @@ int ivpu_mmu_context_insert_node(struct
>> ivpu_mmu_context *ctx, const struct ivpu
>>                    u64 size, struct drm_mm_node *node);
>>   void ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx,
>> struct drm_mm_node *node);
>>   -int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx,
>> -                 u64 vpu_addr, struct sg_table *sgt, bool
>> llc_coherent, bool read_only);
>> +int
>> +ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx, u64 vpu_addr,
>> +             struct sg_table *sgt, size_t bo_size, bool llc_coherent,
>> bool read_only);
>>   void ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx,
>>                   u64 vpu_addr, struct sg_table *sgt);
>>   int ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct
>> ivpu_mmu_context *ctx,

Reply via email to