Re: [PATCH 1/2] drm/panthor: Add vm_bind region with kbo range intersection check
From: Boris Brezillon
Date: Wed Jun 17 2026 - 14:50:20 EST
On Tue, 16 Jun 2026 15:46:43 +0100
Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx> wrote:
> When a VM is created, caller has to specify the range of the address space
> carve-out set aside for mapping kernel BO's. That means vm_bind mappings of
> UM-exposed BO's should not intersect with that region, but at the moment
> we're not checking this.
>
> At first, I thought of giving these values to drm_gpuvm_init() through its
> reserve_{offset, range} arguments, but it turns out that is meant for VM
> address spans that are not managed through the usual drm_gpuvm split/merge
> circuit, so I had no choice but to sort of duplicate that functionality in
> Panthor. That means we also need to keep that interval recorded in the VM.
>
> Signed-off-by: Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx>
> ---
> drivers/gpu/drm/panthor/panthor_mmu.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 31cc57029c12..5625f3d34031 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -301,6 +301,15 @@ struct panthor_vm {
> /** @mm_lock: Lock protecting the @mm field. */
> struct mutex mm_lock;
>
> + /** @kernel_va: VA-range reserved for kernel BOs. */
> + struct {
> + /** @kernel_va.start: Start of the VA-range for kernel BOs. */
> + u64 start;
> +
> + /** @kernel_va.range: Size of the automatic VA-range for kernel BOs. */
> + u64 range;
> + } kernel_va;
We can do with a single user_va_end.
> +
> /** @kernel_auto_va: Automatic VA-range for kernel BOs. */
> struct {
> /** @kernel_auto_va.start: Start of the automatic VA-range for kernel BOs. */
> @@ -1309,6 +1318,24 @@ static int panthor_vm_op_ctx_prealloc_pts(struct panthor_vm_op_ctx *op_ctx)
> return 0;
> }
>
> +static bool
> +panthor_vm_is_kernel_address(struct panthor_vm *vm,
> + const struct drm_panthor_vm_bind_op *op)
Rather than checking if the VA is not in the kernel range, I'd check
that the VA is in the user range, since that's what we want to enforce,
and if we ever decide to carve out extra sections above the user-range
that the UMD is not supposed to access, we would still catch invalid
map/unmap ops.
> +{
> + u32 op_type = op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK;
> + u64 end, kstart, krange, kend;
> +
> + if (op_type == DRM_PANTHOR_VM_BIND_OP_TYPE_SYNC_ONLY)
> + return false;
IIRC, we force op->va and op->size to be zero in that case[1], so no
need for this extra check IMHO.
> +
> + end = op->va + op->size;
> + kstart = vm->kernel_va.start;
> + krange = vm->kernel_va.range;
> + kend = kstart + krange;
> +
> + return krange && op->va < kend && kstart < end;
A single
op->va + op->size <= vm->user_va_end;
would do, at which point I'm not too sure adding a helper makes sense.
> +}
> +
> #define PANTHOR_VM_BIND_OP_MAP_FLAGS \
> (DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | \
> DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | \
> @@ -2891,6 +2918,8 @@ panthor_vm_create(struct panthor_device *ptdev, bool for_mcu,
> } else {
> min_va = 0;
> va_range = full_va_range;
> + vm->kernel_va.start = kernel_va_start;
> + vm->kernel_va.range = kernel_va_size;
> }
>
> mutex_init(&vm->mm_lock);
> @@ -2981,6 +3010,10 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file,
> if (!IS_ALIGNED(op->va | op->size | op->bo_offset, vm_pgsz))
> return -EINVAL;
>
> + /* We don't allow mappings that intersect with kbo's reserved range */
> + if (panthor_vm_is_kernel_address(vm, op))
> + return -EINVAL;
> +
> switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) {
> case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP:
> if (!(op->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE)) {
>
[1]https://elixir.bootlin.com/linux/v7.0.11/source/include/uapi/drm/panthor_drm.h#L588