* [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
@ 2026-06-23 9:24 Akash Goel
2026-06-23 9:53 ` Boris Brezillon
0 siblings, 1 reply; 8+ messages in thread
From: Akash Goel @ 2026-06-23 9:24 UTC (permalink / raw)
To: boris.brezillon, liviu.dudau, steven.price
Cc: dri-devel, linux-kernel, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, nd, Akash Goel
This commit fixes the NULL pointer dereference issue that would have
happened on the split of GPU mapping due to partial unmap of an evicted
BO. There is a logic to handle the partial unmap of huge pages when the
GPU mapping is split. That logic was not being completely skipped for
the VMA of an evicted BO and that resulted in a NPD possibility for the
'bo->backing.pages' pointer, which is set to NULL when pages of a
BO are released on eviction.
Following dump was seen when a partial unmap was exercised for an
evicted BO.
Unable to handle kernel paging request at virtual address 0000000000002000
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=00000008842e8000
[0000000000002000] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 0000000096000004 [#1] SMP
<snip>
pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : iova_mapped_as_huge_page+0x20/0x68 [panthor]
lr : panthor_gpuva_sm_step_remap+0x39c/0x498 [panthor]
sp : ffff800086193920
x29: ffff800086193920 x28: ffff800086193a18 x27: ffff800086193b80
x26: 0000000000400000 x25: 0000000000810000 x24: 0000000000400000
x23: ffff000808af1800 x22: 0000000000a00000 x21: ffff800086193a00
x20: ffff000806fd3f00 x19: 0000000000410000 x18: 00000000ffffffff
x17: 0000000000000000 x16: 0000000000000000 x15: ffff800083ce2d83
x14: 0000000000000000 x13: 3120646574636976 x12: 6520303030303138
x11: 2d30303030313420 x10: ffff8000836e6c80 x9 : ffff80007bfc889c
x8 : 3fffffffffffefff x7 : ffff8000836e6c80 x6 : 0000000000000000
x5 : ffff00097ef19088 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 0000000000010000 x1 : 0000000000000400 x0 : 0000000000000000
Call trace:
iova_mapped_as_huge_page+0x20/0x68 [panthor] (P)
op_remap_cb.isra.0+0x70/0xb0
__drm_gpuvm_sm_unmap+0xf8/0x1c0
drm_gpuvm_sm_unmap+0x40/0x60
panthor_vm_exec_op+0xa0/0x168 [panthor]
panthor_vm_bind_exec_sync_op+0x8c/0xb8 [panthor]
panthor_ioctl_vm_bind+0xbc/0x170 [panthor]
drm_ioctl_kernel+0xc0/0x140
drm_ioctl+0x20c/0x500
__arm64_sys_ioctl+0xb4/0x118
invoke_syscall+0x5c/0x120
el0_svc_common.constprop.0+0x48/0xf8
do_el0_svc+0x28/0x40
el0_svc+0x38/0x128
el0t_64_sync_handler+0xa0/0xe8
el0t_64_sync+0x198/0x1a0
Code: 8b030021 cb020021 f940b800 d34cfc21 (f8617801)
---[ end trace 0000000000000000 ]---
Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
Signed-off-by: Akash Goel <akash.goel@arm.com>
---
drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index 31cc57029c12..285e7b9bc100 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
*/
panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
- /*
- * ARM IOMMU page table management code disallows partial unmaps of huge pages,
- * so when a partial unmap is requested, we must first unmap the entire huge
- * page and then remap the difference between the huge page minus the requested
- * unmap region. Calculating the right start address and range for the expanded
- * unmap operation is the responsibility of the following function.
- */
- unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
-
- /* If the range changed, we might have to lock a wider region to guarantee
- * atomicity. panthor_vm_lock_region() bails out early if the new region
- * is already part of the locked region, so no need to do this check here.
- */
if (!unmap_vma->evicted) {
+ /*
+ * ARM IOMMU page table management code disallows partial unmaps of huge pages,
+ * so when a partial unmap is requested, we must first unmap the entire huge
+ * page and then remap the difference between the huge page minus the requested
+ * unmap region. Calculating the right start address and range for the expanded
+ * unmap operation is the responsibility of the following function.
+ */
+ unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
+
+ /* If the range changed, we might have to lock a wider region to guarantee
+ * atomicity. panthor_vm_lock_region() bails out early if the new region
+ * is already part of the locked region, so no need to do this check here.
+ */
panthor_vm_lock_region(vm, unmap_start, unmap_range);
panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
}
--
2.25.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 9:24 [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO Akash Goel
@ 2026-06-23 9:53 ` Boris Brezillon
2026-06-23 11:17 ` Akash Goel
0 siblings, 1 reply; 8+ messages in thread
From: Boris Brezillon @ 2026-06-23 9:53 UTC (permalink / raw)
To: Akash Goel
Cc: liviu.dudau, steven.price, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, daniel, nd
On Tue, 23 Jun 2026 10:24:13 +0100
Akash Goel <akash.goel@arm.com> wrote:
> This commit fixes the NULL pointer dereference issue that would have
> happened on the split of GPU mapping due to partial unmap of an evicted
> BO. There is a logic to handle the partial unmap of huge pages when the
> GPU mapping is split. That logic was not being completely skipped for
> the VMA of an evicted BO and that resulted in a NPD possibility for the
> 'bo->backing.pages' pointer, which is set to NULL when pages of a
> BO are released on eviction.
>
> Following dump was seen when a partial unmap was exercised for an
> evicted BO.
> Unable to handle kernel paging request at virtual address 0000000000002000
> Mem abort info:
> ESR = 0x0000000096000004
> EC = 0x25: DABT (current EL), IL = 32 bits
> SET = 0, FnV = 0
> EA = 0, S1PTW = 0
> FSC = 0x04: level 0 translation fault
> Data abort info:
> ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
> CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> user pgtable: 4k pages, 48-bit VAs, pgdp=00000008842e8000
> [0000000000002000] pgd=0000000000000000, p4d=0000000000000000
> Internal error: Oops: 0000000096000004 [#1] SMP
> <snip>
> pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : iova_mapped_as_huge_page+0x20/0x68 [panthor]
> lr : panthor_gpuva_sm_step_remap+0x39c/0x498 [panthor]
> sp : ffff800086193920
> x29: ffff800086193920 x28: ffff800086193a18 x27: ffff800086193b80
> x26: 0000000000400000 x25: 0000000000810000 x24: 0000000000400000
> x23: ffff000808af1800 x22: 0000000000a00000 x21: ffff800086193a00
> x20: ffff000806fd3f00 x19: 0000000000410000 x18: 00000000ffffffff
> x17: 0000000000000000 x16: 0000000000000000 x15: ffff800083ce2d83
> x14: 0000000000000000 x13: 3120646574636976 x12: 6520303030303138
> x11: 2d30303030313420 x10: ffff8000836e6c80 x9 : ffff80007bfc889c
> x8 : 3fffffffffffefff x7 : ffff8000836e6c80 x6 : 0000000000000000
> x5 : ffff00097ef19088 x4 : 0000000000000000 x3 : 0000000000000000
> x2 : 0000000000010000 x1 : 0000000000000400 x0 : 0000000000000000
> Call trace:
> iova_mapped_as_huge_page+0x20/0x68 [panthor] (P)
> op_remap_cb.isra.0+0x70/0xb0
> __drm_gpuvm_sm_unmap+0xf8/0x1c0
> drm_gpuvm_sm_unmap+0x40/0x60
> panthor_vm_exec_op+0xa0/0x168 [panthor]
> panthor_vm_bind_exec_sync_op+0x8c/0xb8 [panthor]
> panthor_ioctl_vm_bind+0xbc/0x170 [panthor]
> drm_ioctl_kernel+0xc0/0x140
> drm_ioctl+0x20c/0x500
> __arm64_sys_ioctl+0xb4/0x118
> invoke_syscall+0x5c/0x120
> el0_svc_common.constprop.0+0x48/0xf8
> do_el0_svc+0x28/0x40
> el0_svc+0x38/0x128
> el0t_64_sync_handler+0xa0/0xe8
> el0t_64_sync+0x198/0x1a0
> Code: 8b030021 cb020021 f940b800 d34cfc21 (f8617801)
> ---[ end trace 0000000000000000 ]---
>
> Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
> Signed-off-by: Akash Goel <akash.goel@arm.com>
> ---
> drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
> 1 file changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 31cc57029c12..285e7b9bc100 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
> */
> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
>
> - /*
> - * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> - * so when a partial unmap is requested, we must first unmap the entire huge
> - * page and then remap the difference between the huge page minus the requested
> - * unmap region. Calculating the right start address and range for the expanded
> - * unmap operation is the responsibility of the following function.
> - */
> - unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> -
> - /* If the range changed, we might have to lock a wider region to guarantee
> - * atomicity. panthor_vm_lock_region() bails out early if the new region
> - * is already part of the locked region, so no need to do this check here.
> - */
> if (!unmap_vma->evicted) {
> + /*
> + * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> + * so when a partial unmap is requested, we must first unmap the entire huge
> + * page and then remap the difference between the huge page minus the requested
> + * unmap region. Calculating the right start address and range for the expanded
> + * unmap operation is the responsibility of the following function.
> + */
> + unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> +
> + /* If the range changed, we might have to lock a wider region to guarantee
> + * atomicity. panthor_vm_lock_region() bails out early if the new region
> + * is already part of the locked region, so no need to do this check here.
> + */
> panthor_vm_lock_region(vm, unmap_start, unmap_range);
> panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
> }
I think we want something like that instead, so we can keep the
2M alignment for sparse mappings which go recently introduced.
--->8---
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index 5e735995f80d..28844e1e2f81 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -2301,6 +2301,10 @@ iova_mapped_as_huge_page(struct drm_gpuva_op_map *op, u64 addr)
const struct page *pg;
pgoff_t bo_offset;
+ /* Can happen if the BO is evicted. */
+ if (!bo->backing.pages)
+ return false;
+
bo_offset = addr - op->va.addr + op->gem.offset;
pg = bo->backing.pages[bo_offset >> PAGE_SHIFT];
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 9:53 ` Boris Brezillon
@ 2026-06-23 11:17 ` Akash Goel
2026-06-23 12:09 ` Boris Brezillon
0 siblings, 1 reply; 8+ messages in thread
From: Akash Goel @ 2026-06-23 11:17 UTC (permalink / raw)
To: Boris Brezillon
Cc: liviu.dudau, steven.price, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, daniel, nd
Hi Boris
On 6/23/26 10:53, Boris Brezillon wrote:
> On Tue, 23 Jun 2026 10:24:13 +0100
> Akash Goel <akash.goel@arm.com> wrote:
>
>> This commit fixes the NULL pointer dereference issue that would have
>> happened on the split of GPU mapping due to partial unmap of an evicted
>> BO. There is a logic to handle the partial unmap of huge pages when the
>> GPU mapping is split. That logic was not being completely skipped for
>> the VMA of an evicted BO and that resulted in a NPD possibility for the
>> 'bo->backing.pages' pointer, which is set to NULL when pages of a
>> BO are released on eviction.
>>
>>
>> Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
>> Signed-off-by: Akash Goel <akash.goel@arm.com>
>> ---
>> drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
>> 1 file changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
>> index 31cc57029c12..285e7b9bc100 100644
>> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
>> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
>> @@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
>> */
>> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
>>
>> - /*
>> - * ARM IOMMU page table management code disallows partial unmaps of huge pages,
>> - * so when a partial unmap is requested, we must first unmap the entire huge
>> - * page and then remap the difference between the huge page minus the requested
>> - * unmap region. Calculating the right start address and range for the expanded
>> - * unmap operation is the responsibility of the following function.
>> - */
>> - unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
>> -
>> - /* If the range changed, we might have to lock a wider region to guarantee
>> - * atomicity. panthor_vm_lock_region() bails out early if the new region
>> - * is already part of the locked region, so no need to do this check here.
>> - */
>> if (!unmap_vma->evicted) {
>> + /*
>> + * ARM IOMMU page table management code disallows partial unmaps of huge pages,
>> + * so when a partial unmap is requested, we must first unmap the entire huge
>> + * page and then remap the difference between the huge page minus the requested
>> + * unmap region. Calculating the right start address and range for the expanded
>> + * unmap operation is the responsibility of the following function.
>> + */
>> + unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
>> +
>> + /* If the range changed, we might have to lock a wider region to guarantee
>> + * atomicity. panthor_vm_lock_region() bails out early if the new region
>> + * is already part of the locked region, so no need to do this check here.
>> + */
>> panthor_vm_lock_region(vm, unmap_start, unmap_range);
>> panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
>> }
>
>
> I think we want something like that instead, so we can keep the
> 2M alignment for sparse mappings which go recently introduced.
>
Thanks for the suggestion. But sorry I didn't get it.
I see that the patching of 'op->remap.next->gem.offset' would still be
done with my change.
panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
if (!unmap_vma->evicted) {
unmap_hugepage_align(&op->remap, &unmap_start,
IIUC, the 2M alignment is done to avoid a potential partial unmap of 2M
page. But if the VMA is in evicted state then already the unmap would
have happened for the whole virtual range covered by the VMA.
Please can you kindly clarify.
Best regards
Akash
> --->8---
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 5e735995f80d..28844e1e2f81 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -2301,6 +2301,10 @@ iova_mapped_as_huge_page(struct drm_gpuva_op_map *op, u64 addr)
> const struct page *pg;
> pgoff_t bo_offset;
>
> + /* Can happen if the BO is evicted. */
> + if (!bo->backing.pages)
> + return false;
> +
> bo_offset = addr - op->va.addr + op->gem.offset;
> pg = bo->backing.pages[bo_offset >> PAGE_SHIFT];
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 11:17 ` Akash Goel
@ 2026-06-23 12:09 ` Boris Brezillon
2026-06-23 12:41 ` Akash Goel
0 siblings, 1 reply; 8+ messages in thread
From: Boris Brezillon @ 2026-06-23 12:09 UTC (permalink / raw)
To: Akash Goel
Cc: liviu.dudau, steven.price, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, daniel, nd
On Tue, 23 Jun 2026 12:17:51 +0100
Akash Goel <akash.goel@arm.com> wrote:
> Hi Boris
>
> On 6/23/26 10:53, Boris Brezillon wrote:
> > On Tue, 23 Jun 2026 10:24:13 +0100
> > Akash Goel <akash.goel@arm.com> wrote:
> >
> >> This commit fixes the NULL pointer dereference issue that would have
> >> happened on the split of GPU mapping due to partial unmap of an evicted
> >> BO. There is a logic to handle the partial unmap of huge pages when the
> >> GPU mapping is split. That logic was not being completely skipped for
> >> the VMA of an evicted BO and that resulted in a NPD possibility for the
> >> 'bo->backing.pages' pointer, which is set to NULL when pages of a
> >> BO are released on eviction.
> >>
>
> >>
> >> Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
> >> Signed-off-by: Akash Goel <akash.goel@arm.com>
> >> ---
> >> drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
> >> 1 file changed, 13 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> >> index 31cc57029c12..285e7b9bc100 100644
> >> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> >> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> >> @@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
> >> */
> >> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
> >>
> >> - /*
> >> - * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> >> - * so when a partial unmap is requested, we must first unmap the entire huge
> >> - * page and then remap the difference between the huge page minus the requested
> >> - * unmap region. Calculating the right start address and range for the expanded
> >> - * unmap operation is the responsibility of the following function.
> >> - */
> >> - unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> >> -
> >> - /* If the range changed, we might have to lock a wider region to guarantee
> >> - * atomicity. panthor_vm_lock_region() bails out early if the new region
> >> - * is already part of the locked region, so no need to do this check here.
> >> - */
> >> if (!unmap_vma->evicted) {
> >> + /*
> >> + * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> >> + * so when a partial unmap is requested, we must first unmap the entire huge
> >> + * page and then remap the difference between the huge page minus the requested
> >> + * unmap region. Calculating the right start address and range for the expanded
> >> + * unmap operation is the responsibility of the following function.
> >> + */
> >> + unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> >> +
> >> + /* If the range changed, we might have to lock a wider region to guarantee
> >> + * atomicity. panthor_vm_lock_region() bails out early if the new region
> >> + * is already part of the locked region, so no need to do this check here.
> >> + */
> >> panthor_vm_lock_region(vm, unmap_start, unmap_range);
> >> panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
> >> }
> >
> >
> > I think we want something like that instead, so we can keep the
> > 2M alignment for sparse mappings which go recently introduced.
> >
>
> Thanks for the suggestion. But sorry I didn't get it.
>
> I see that the patching of 'op->remap.next->gem.offset' would still be
> done with my change.
>
> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
>
> if (!unmap_vma->evicted) {
> unmap_hugepage_align(&op->remap, &unmap_start,
>
> IIUC, the 2M alignment is done to avoid a potential partial unmap of 2M
> page. But if the VMA is in evicted state then already the unmap would
> have happened for the whole virtual range covered by the VMA.
Nah, you're correct, the patching of the drm_gpuva is independent of the
adjusted unmap range, so we should be good even if we don't adjust this
range for evicted sparse mappings. Sorry for the noise.
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 12:09 ` Boris Brezillon
@ 2026-06-23 12:41 ` Akash Goel
2026-06-23 12:55 ` Boris Brezillon
2026-06-23 14:14 ` Adrián Larumbe
0 siblings, 2 replies; 8+ messages in thread
From: Akash Goel @ 2026-06-23 12:41 UTC (permalink / raw)
To: Boris Brezillon
Cc: liviu.dudau, steven.price, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, daniel, nd
On 6/23/26 13:09, Boris Brezillon wrote:
> On Tue, 23 Jun 2026 12:17:51 +0100
> Akash Goel <akash.goel@arm.com> wrote:
>
>> Hi Boris
>>
>> On 6/23/26 10:53, Boris Brezillon wrote:
>>> On Tue, 23 Jun 2026 10:24:13 +0100
>>> Akash Goel <akash.goel@arm.com> wrote:
>>>
>>>> This commit fixes the NULL pointer dereference issue that would have
>>>> happened on the split of GPU mapping due to partial unmap of an evicted
>>>> BO. There is a logic to handle the partial unmap of huge pages when the
>>>> GPU mapping is split. That logic was not being completely skipped for
>>>> the VMA of an evicted BO and that resulted in a NPD possibility for the
>>>> 'bo->backing.pages' pointer, which is set to NULL when pages of a
>>>> BO are released on eviction.
>>>>
>>
>>>>
>>>> Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
>>>> Signed-off-by: Akash Goel <akash.goel@arm.com>
>>>> ---
>>>> drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
>>>> 1 file changed, 13 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
>>>> index 31cc57029c12..285e7b9bc100 100644
>>>> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
>>>> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
>>>> @@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
>>>> */
>>>> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
>>>>
>>>> - /*
>>>> - * ARM IOMMU page table management code disallows partial unmaps of huge pages,
>>>> - * so when a partial unmap is requested, we must first unmap the entire huge
>>>> - * page and then remap the difference between the huge page minus the requested
>>>> - * unmap region. Calculating the right start address and range for the expanded
>>>> - * unmap operation is the responsibility of the following function.
>>>> - */
>>>> - unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
>>>> -
>>>> - /* If the range changed, we might have to lock a wider region to guarantee
>>>> - * atomicity. panthor_vm_lock_region() bails out early if the new region
>>>> - * is already part of the locked region, so no need to do this check here.
>>>> - */
>>>> if (!unmap_vma->evicted) {
>>>> + /*
>>>> + * ARM IOMMU page table management code disallows partial unmaps of huge pages,
>>>> + * so when a partial unmap is requested, we must first unmap the entire huge
>>>> + * page and then remap the difference between the huge page minus the requested
>>>> + * unmap region. Calculating the right start address and range for the expanded
>>>> + * unmap operation is the responsibility of the following function.
>>>> + */
>>>> + unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
>>>> +
>>>> + /* If the range changed, we might have to lock a wider region to guarantee
>>>> + * atomicity. panthor_vm_lock_region() bails out early if the new region
>>>> + * is already part of the locked region, so no need to do this check here.
>>>> + */
>>>> panthor_vm_lock_region(vm, unmap_start, unmap_range);
>>>> panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
>>>> }
>>>
>>>
>>> I think we want something like that instead, so we can keep the
>>> 2M alignment for sparse mappings which go recently introduced.
>>>
>>
>> Thanks for the suggestion. But sorry I didn't get it.
>>
>> I see that the patching of 'op->remap.next->gem.offset' would still be
>> done with my change.
>>
>> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
>>
>> if (!unmap_vma->evicted) {
>> unmap_hugepage_align(&op->remap, &unmap_start,
>>
>> IIUC, the 2M alignment is done to avoid a potential partial unmap of 2M
>> page. But if the VMA is in evicted state then already the unmap would
>> have happened for the whole virtual range covered by the VMA.
>
> Nah, you're correct, the patching of the drm_gpuva is independent of the
> adjusted unmap range, so we should be good even if we don't adjust this
> range for evicted sparse mappings. Sorry for the noise.
>
No worries. Thanks for confirming.
Since I had a closer look at the code, sorry I have another doubt.
Do we really need the call to 'panthor_fix_sparse_map_offset()' in the
following code block ?. The 'op->remap.next->gem.offset' would already
have been patched before.
if (op->remap.next) {
u64 addr = op->remap.next->va.addr;
u64 size = unmap_start + unmap_range - op->remap.next->va.addr;
if (!unmap_vma->evicted && size > 0) {
struct drm_gpuva_op_map map_op = {
.va.addr = addr,
.va.range = size,
.gem.obj = op->remap.next->gem.obj,
.gem.offset = op->remap.next->gem.offset,
};
panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags);
ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op);
> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Sorry I realized that indentation needs to be fixed in my patch.
Will send a v2 and ad your r-b tag.
Best regards
Akash
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 12:41 ` Akash Goel
@ 2026-06-23 12:55 ` Boris Brezillon
2026-06-23 14:14 ` Adrián Larumbe
1 sibling, 0 replies; 8+ messages in thread
From: Boris Brezillon @ 2026-06-23 12:55 UTC (permalink / raw)
To: Akash Goel, Adrián Larumbe
Cc: liviu.dudau, steven.price, dri-devel, linux-kernel,
maarten.lankhorst, mripard, tzimmermann, airlied, daniel, nd
+Adrian
On Tue, 23 Jun 2026 13:41:12 +0100
Akash Goel <akash.goel@arm.com> wrote:
> On 6/23/26 13:09, Boris Brezillon wrote:
> > On Tue, 23 Jun 2026 12:17:51 +0100
> > Akash Goel <akash.goel@arm.com> wrote:
> >
> >> Hi Boris
> >>
> >> On 6/23/26 10:53, Boris Brezillon wrote:
> >>> On Tue, 23 Jun 2026 10:24:13 +0100
> >>> Akash Goel <akash.goel@arm.com> wrote:
> >>>
> >>>> This commit fixes the NULL pointer dereference issue that would have
> >>>> happened on the split of GPU mapping due to partial unmap of an evicted
> >>>> BO. There is a logic to handle the partial unmap of huge pages when the
> >>>> GPU mapping is split. That logic was not being completely skipped for
> >>>> the VMA of an evicted BO and that resulted in a NPD possibility for the
> >>>> 'bo->backing.pages' pointer, which is set to NULL when pages of a
> >>>> BO are released on eviction.
> >>>>
> >>
> >>>>
> >>>> Fixes: 8e7460eac786 ("drm/panthor: Support partial unmaps of huge pages")
> >>>> Signed-off-by: Akash Goel <akash.goel@arm.com>
> >>>> ---
> >>>> drivers/gpu/drm/panthor/panthor_mmu.c | 26 +++++++++++++-------------
> >>>> 1 file changed, 13 insertions(+), 13 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> >>>> index 31cc57029c12..285e7b9bc100 100644
> >>>> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> >>>> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> >>>> @@ -2358,20 +2358,20 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op,
> >>>> */
> >>>> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
> >>>>
> >>>> - /*
> >>>> - * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> >>>> - * so when a partial unmap is requested, we must first unmap the entire huge
> >>>> - * page and then remap the difference between the huge page minus the requested
> >>>> - * unmap region. Calculating the right start address and range for the expanded
> >>>> - * unmap operation is the responsibility of the following function.
> >>>> - */
> >>>> - unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> >>>> -
> >>>> - /* If the range changed, we might have to lock a wider region to guarantee
> >>>> - * atomicity. panthor_vm_lock_region() bails out early if the new region
> >>>> - * is already part of the locked region, so no need to do this check here.
> >>>> - */
> >>>> if (!unmap_vma->evicted) {
> >>>> + /*
> >>>> + * ARM IOMMU page table management code disallows partial unmaps of huge pages,
> >>>> + * so when a partial unmap is requested, we must first unmap the entire huge
> >>>> + * page and then remap the difference between the huge page minus the requested
> >>>> + * unmap region. Calculating the right start address and range for the expanded
> >>>> + * unmap operation is the responsibility of the following function.
> >>>> + */
> >>>> + unmap_hugepage_align(&op->remap, &unmap_start, &unmap_range);
> >>>> +
> >>>> + /* If the range changed, we might have to lock a wider region to guarantee
> >>>> + * atomicity. panthor_vm_lock_region() bails out early if the new region
> >>>> + * is already part of the locked region, so no need to do this check here.
> >>>> + */
> >>>> panthor_vm_lock_region(vm, unmap_start, unmap_range);
> >>>> panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
> >>>> }
> >>>
> >>>
> >>> I think we want something like that instead, so we can keep the
> >>> 2M alignment for sparse mappings which go recently introduced.
> >>>
> >>
> >> Thanks for the suggestion. But sorry I didn't get it.
> >>
> >> I see that the patching of 'op->remap.next->gem.offset' would still be
> >> done with my change.
> >>
> >> panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags);
> >>
> >> if (!unmap_vma->evicted) {
> >> unmap_hugepage_align(&op->remap, &unmap_start,
> >>
> >> IIUC, the 2M alignment is done to avoid a potential partial unmap of 2M
> >> page. But if the VMA is in evicted state then already the unmap would
> >> have happened for the whole virtual range covered by the VMA.
> >
> > Nah, you're correct, the patching of the drm_gpuva is independent of the
> > adjusted unmap range, so we should be good even if we don't adjust this
> > range for evicted sparse mappings. Sorry for the noise.
> >
>
> No worries. Thanks for confirming.
>
> Since I had a closer look at the code, sorry I have another doubt.
>
> Do we really need the call to 'panthor_fix_sparse_map_offset()' in the
> following code block ?. The 'op->remap.next->gem.offset' would already
> have been patched before.
That's probably not needed, indeed. Adrian to confirm.
>
>
> if (op->remap.next) {
> u64 addr = op->remap.next->va.addr;
> u64 size = unmap_start + unmap_range - op->remap.next->va.addr;
>
> if (!unmap_vma->evicted && size > 0) {
> struct drm_gpuva_op_map map_op = {
> .va.addr = addr,
> .va.range = size,
> .gem.obj = op->remap.next->gem.obj,
> .gem.offset = op->remap.next->gem.offset,
> };
> panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags);
>
> ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op);
>
>
> > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>
> Sorry I realized that indentation needs to be fixed in my patch.
>
> Will send a v2 and ad your r-b tag.
Sounds good.
Thanks,
Boris
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 12:41 ` Akash Goel
2026-06-23 12:55 ` Boris Brezillon
@ 2026-06-23 14:14 ` Adrián Larumbe
2026-06-23 14:58 ` Akash Goel
1 sibling, 1 reply; 8+ messages in thread
From: Adrián Larumbe @ 2026-06-23 14:14 UTC (permalink / raw)
To: Akash Goel
Cc: Boris Brezillon, liviu.dudau, steven.price, dri-devel,
linux-kernel, maarten.lankhorst, mripard, tzimmermann, airlied,
daniel, nd
On 2026-06-23 13:41:12+01:00, Akash Goel wrote:
> On 6/23/26 13:09, Boris Brezillon wrote:
>
> > On Tue, 23 Jun 2026 12:17:51 +0100
> > Akash Goel <akash.goel@arm.com> wrote:
> >
> >
> > Nah, you're correct, the patching of the drm_gpuva is independent of the
> > adjusted unmap range, so we should be good even if we don't adjust this
> > range for evicted sparse mappings. Sorry for the noise.
>
> No worries. Thanks for confirming.
>
> Since I had a closer look at the code, sorry I have another doubt.
>
> Do we really need the call to 'panthor_fix_sparse_map_offset()' in the
> following code block ?. The 'op->remap.next->gem.offset' would already
> have been patched before.
You're right, it's completely unnecessary. Maybe replace it with a comment that says
the right offset had already been adjusted earlier in the function?
Other than that:
Reviewed-by: Adrián Larumbe <adrian.larumbe@collabora.com>
>
> if (op->remap.next) {
> u64 addr = op->remap.next->va.addr;
> u64 size = unmap_start + unmap_range - op->remap.next->va.addr;
>
> if (!unmap_vma->evicted && size > 0) {
> struct drm_gpuva_op_map map_op = {
> .va.addr = addr,
> .va.range = size,
> .gem.obj = op->remap.next->gem.obj,
> .gem.offset = op->remap.next->gem.offset,
> };
> panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags);
>
> ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op);
>
> > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>
> Sorry I realized that indentation needs to be fixed in my patch.
>
> Will send a v2 and ad your r-b tag.
>
> Best regards
> Akash
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO
2026-06-23 14:14 ` Adrián Larumbe
@ 2026-06-23 14:58 ` Akash Goel
0 siblings, 0 replies; 8+ messages in thread
From: Akash Goel @ 2026-06-23 14:58 UTC (permalink / raw)
To: Adrián Larumbe
Cc: Boris Brezillon, liviu.dudau, steven.price, dri-devel,
linux-kernel, maarten.lankhorst, mripard, tzimmermann, airlied,
daniel, nd
On 6/23/26 15:14, Adrián Larumbe wrote:
> On 2026-06-23 13:41:12+01:00, Akash Goel wrote:
>> On 6/23/26 13:09, Boris Brezillon wrote:
>>
>>> On Tue, 23 Jun 2026 12:17:51 +0100
>>> Akash Goel <akash.goel@arm.com> wrote:
>>>
>>>
>>> Nah, you're correct, the patching of the drm_gpuva is independent of the
>>> adjusted unmap range, so we should be good even if we don't adjust this
>>> range for evicted sparse mappings. Sorry for the noise.
>>
>> No worries. Thanks for confirming.
>>
>> Since I had a closer look at the code, sorry I have another doubt.
>>
>> Do we really need the call to 'panthor_fix_sparse_map_offset()' in the
>> following code block ?. The 'op->remap.next->gem.offset' would already
>> have been patched before.
>
> You're right, it's completely unnecessary.
>
Thanks Adrian for confirming.
> Maybe replace it with a comment that says the right offset had
already > been adjusted earlier in the function?
Sure, I can prepare a patch for this.
> Other than that:
>
> Reviewed-by: Adrián Larumbe <adrian.larumbe@collabora.com>
>
Thanks for the review.
Best regards
Akash
>>
>> if (op->remap.next) {
>> u64 addr = op->remap.next->va.addr;
>> u64 size = unmap_start + unmap_range - op->remap.next->va.addr;
>>
>> if (!unmap_vma->evicted && size > 0) {
>> struct drm_gpuva_op_map map_op = {
>> .va.addr = addr,
>> .va.range = size,
>> .gem.obj = op->remap.next->gem.obj,
>> .gem.offset = op->remap.next->gem.offset,
>> };
>> panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags);
>>
>> ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op);
>>
>>> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>>
>> Sorry I realized that indentation needs to be fixed in my patch.
>>
>> Will send a v2 and ad your r-b tag.
>>
>> Best regards
>> Akash
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-23 14:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-23 9:24 [PATCH] drm/panthor: Fix NPD issue on partial unmap of an evicted BO Akash Goel
2026-06-23 9:53 ` Boris Brezillon
2026-06-23 11:17 ` Akash Goel
2026-06-23 12:09 ` Boris Brezillon
2026-06-23 12:41 ` Akash Goel
2026-06-23 12:55 ` Boris Brezillon
2026-06-23 14:14 ` Adrián Larumbe
2026-06-23 14:58 ` Akash Goel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox