diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-10-29 10:42:04 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-10-29 14:29:26 +1000 |
| commit | 460635aa3d5ddba65ee147e9f864a17d6b2665b1 (patch) | |
| tree | bbde6c9ae4a7b21f9c2a1ac5da51f399a99bf944 /drivers/gpu | |
| parent | af16ecbdf81301e88bb03e114706e0fc7c2a8e42 (diff) | |
| parent | 9a96e169c9267af918d28fb291df948d83112807 (diff) | |
Merge tag 'drm-misc-next-fixes-2026-10-23' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next
Short summary of fixes pull:
panthor:
- Fix bugs in MMU handling
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20261023071453.GA13189@linux.fritz.box
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/panthor/panthor_mmu.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index d75d575473da..86d0b8f9e7d7 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -616,8 +616,7 @@ static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr, return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE); } -static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr, - bool recycle_slot) +static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr) { struct panthor_mmu *mmu = ptdev->mmu; struct panthor_vm *vm = ptdev->mmu->as.slots[as_nr].vm; @@ -628,12 +627,6 @@ static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr, panthor_irq_disable_events(&ptdev->mmu->irq, panthor_mmu_as_fault_mask(ptdev, as_nr)); - /* Flush+invalidate RW caches, invalidate RO ones. */ - ret = panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV, - CACHE_CLEAN | CACHE_INV, CACHE_INV); - if (ret) - return ret; - if (vm && vm->locked_region.size) { /* Unlock the region if there's a lock pending. */ ret = as_send_cmd_and_wait(ptdev, vm->as.id, AS_COMMAND_UNLOCK); @@ -641,17 +634,22 @@ static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr, return ret; } - /* If the slot is going to be used immediately, don't bother changing - * the config. - */ - if (recycle_slot) - return 0; - gpu_write64(mmu->iomem, AS_TRANSTAB(as_nr), 0); gpu_write64(mmu->iomem, AS_MEMATTR(as_nr), 0); gpu_write64(mmu->iomem, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED); - return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE); + ret = as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE); + if (ret) + return ret; + + /* Flush+invalidate RW caches after we've unmapped, to make sure any + * cacheline eviction is effective before we potentially return + * memory pointed by this VM to the system. This needs to be done + * after the UPDATE(UNMAPPED) operation to guarantee that not further + * PT-walk can pull VM data into the cache. + */ + return panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV, + CACHE_CLEAN | CACHE_INV, 0); } static u32 panthor_mmu_fault_mask(struct panthor_device *ptdev, u32 value) @@ -773,7 +771,7 @@ int panthor_vm_active(struct panthor_vm *vm) drm_WARN_ON(&ptdev->base, refcount_read(&lru_vm->as.active_cnt)); as = lru_vm->as.id; - ret = panthor_mmu_as_disable(ptdev, as, true); + ret = panthor_mmu_as_disable(ptdev, as); if (ret) goto out_unlock; @@ -915,7 +913,7 @@ static void panthor_vm_declare_unusable(struct panthor_vm *vm) vm->unusable = true; mutex_lock(&ptdev->mmu->as.slots_lock); if (vm->as.id >= 0 && drm_dev_enter(&ptdev->base, &cookie)) { - panthor_mmu_as_disable(ptdev, vm->as.id, false); + panthor_mmu_as_disable(ptdev, vm->as.id); drm_dev_exit(cookie); } mutex_unlock(&ptdev->mmu->as.slots_lock); @@ -1832,13 +1830,12 @@ static void panthor_vm_unlock_region(struct panthor_vm *vm) if (vm->as.id >= 0) { int ret; - /* flush+invalidate RW caches and invalidate RO ones. + /* flush+invalidate RW caches. * TODO: See if we can use FLUSH_PA_RANGE when the physical * range is narrow enough and the HW supports it. */ ret = panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV, - CACHE_CLEAN | CACHE_INV, - CACHE_INV); + CACHE_CLEAN | CACHE_INV, 0); /* Unlock the region if the flush is effective. */ if (!ret) @@ -1909,7 +1906,7 @@ static void panthor_mmu_irq_handler(struct panthor_irq *pirq, u32 status) ptdev->mmu->as.slots[as].vm->unhandled_fault = true; /* Disable the MMU to kill jobs on this AS. */ - panthor_mmu_as_disable(ptdev, as, false); + panthor_mmu_as_disable(ptdev, as); mutex_unlock(&ptdev->mmu->as.slots_lock); status &= ~mask; @@ -1943,7 +1940,7 @@ void panthor_mmu_suspend(struct panthor_device *ptdev) if (vm) { drm_WARN_ON(&ptdev->base, - panthor_mmu_as_disable(ptdev, i, false)); + panthor_mmu_as_disable(ptdev, i)); panthor_vm_release_as_locked(vm); } } @@ -2068,7 +2065,7 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) int cookie; if (drm_dev_enter(&ptdev->base, &cookie)) { - panthor_mmu_as_disable(ptdev, vm->as.id, false); + panthor_mmu_as_disable(ptdev, vm->as.id); drm_dev_exit(cookie); } @@ -3362,7 +3359,7 @@ void panthor_mmu_unplug(struct panthor_device *ptdev) if (vm) { drm_WARN_ON(&ptdev->base, - panthor_mmu_as_disable(ptdev, i, false)); + panthor_mmu_as_disable(ptdev, i)); panthor_vm_release_as_locked(vm); } } |
