Thank you for your contribution! Sashiko AI review found 3 potential issue(s) 
to consider:

Pre-existing issues:
- [High] Unbalanced `pvr_gem_object_get()` in `pvr_vm_gpuva_remap()` causes a 
permanent memory leak of GEM objects.
- [High] Missing `dma_resv` locking during `drm_gpuva_link()` and 
`drm_gpuva_unlink()` causes data races and list corruption.
- [High] Missing `vm_ctx->lock` acquisition in `pvr_vm_map()` causes concurrent 
execution data races and potential RB tree corruption.
--

--- Patch [1]: [PATCH 1/4] drm/imagination: Fix the vm_bo split mappings are 
linked to ---
commit c145cb50bdcd3046dfd6222a4b0282d9524af76c
Author: Gyeyoung Baek <[email protected]>

drm/imagination: Fix the vm_bo split mappings are linked to

A remap does not map anything new. It splits an existing mapping and
re-creates the parts the request did not cover, and that mapping is handed
to the callback in op->remap.unmap->va, carrying the &drm_gpuvm_bo those
parts belong to.

> diff --git a/drivers/gpu/drm/imagination/pvr_vm.c 
> b/drivers/gpu/drm/imagination/pvr_vm.c
> index 396d349fb6ce4..608e8c0467dce 100644
> --- a/drivers/gpu/drm/imagination/pvr_vm.c
> +++ b/drivers/gpu/drm/imagination/pvr_vm.c
> @@ -434,18 +436,18 @@ pvr_vm_gpuva_remap(struct drm_gpuva_op *op, void 
> *op_ctx)
>  
>       if (op->remap.prev) {
>               pvr_gem_object_get(gem_to_pvr_gem(ctx->prev_va->base.gem.obj));
> -             drm_gpuva_link(&ctx->prev_va->base, ctx->gpuvm_bo);
> +             drm_gpuva_link(&ctx->prev_va->base, vm_bo);

[Severity: High]
This is a pre-existing issue, but does this code permanently leak GEM objects?

During a remap operation, this explicitly calls pvr_gem_object_get() to take
references on the backing GEM objects for the new split mappings (prev_va and
next_va).

However, the teardown paths like pvr_vm_gpuva_unmap() and the unmap phase
of pvr_vm_gpuva_remap() just call drm_gpuva_unlink() and kfree() without a
corresponding pvr_gem_object_put(). Since the DRM GPUVM framework internally
manages GEM object lifetimes through vm_bo structures, are these manual
references redundant and never released?

[Severity: High]
This is another pre-existing issue, but can this cause data races and list
corruption?

pvr_vm does not use DRM_GPUVM_IMMEDIATE_MODE, so it relies on the GEM object's
dma_resv lock to protect gpuva.list operations. When a new mapping overlaps an
existing mapping belonging to a different GEM object, the core calls
pvr_vm_gpuva_remap() or pvr_vm_gpuva_unmap().

These callbacks then invoke drm_gpuva_link() and drm_gpuva_unlink() on the
mappings without holding their GEM object's dma_resv lock. Since pvr_vm_map()
only locks the new GEM object being mapped (via pvr_vm_lock_extra()) and
doesn't populate the GPUVM's extobj list, does this concurrent lockless
modification of gpuva.list result in list corruption?

>               ctx->prev_va = NULL;
>       }
>  
>       if (op->remap.next) {
>               pvr_gem_object_get(gem_to_pvr_gem(ctx->next_va->base.gem.obj));
> -             drm_gpuva_link(&ctx->next_va->base, ctx->gpuvm_bo);
> +             drm_gpuva_link(&ctx->next_va->base, vm_bo);
>               ctx->next_va = NULL;
>       }
>  
> -     drm_gpuva_unlink(op->remap.unmap->va);
> -     kfree(to_pvr_vm_gpuva(op->remap.unmap->va));
> +     drm_gpuva_unlink(unmap_va);
> +     kfree(to_pvr_vm_gpuva(unmap_va));
>  
>       return 0;
>  }

[Severity: High]
This is a pre-existing issue in this file outside of the diff, but does
pvr_vm_map() have a data race that could corrupt the GPUVM RB-tree?

In pvr_vm_unmap(), the driver acquires vm_ctx->lock before searching the
GPUVM's RB-tree via drm_gpuva_find(). However, pvr_vm_map() mutates the RB-tree
via pvr_vm_bind_op_exec() invoking drm_gpuvm_sm_map() but doesn't acquire
vm_ctx->lock:

drivers/gpu/drm/imagination/pvr_vm.c:pvr_vm_map() {
    ...
    err = pvr_vm_bind_op_exec(&bind_op);
    ...
}

While pvr_vm_map() acquires the VM's dma_resv lock, pvr_vm_unmap() does not
hold this lock during its traversal:

drivers/gpu/drm/imagination/pvr_vm.c:pvr_vm_unmap() {
    ...
    va = drm_gpuva_find(&vm_ctx->gpuvm_mgr, device_addr, size);
    ...
}

Since there is no shared lock between the reader and writer of the RB-tree, can
a map operation modify the tree concurrently with an unmap operation's
traversal?

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to