summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-10-29 10:42:04 +1000
committerDave Airlie <airlied@redhat.com>2026-10-29 14:29:26 +1000
commit460635aa3d5ddba65ee147e9f864a17d6b2665b1 (patch)
treebbde6c9ae4a7b21f9c2a1ac5da51f399a99bf944 /drivers/gpu
parentaf16ecbdf81301e88bb03e114706e0fc7c2a8e42 (diff)
parent9a96e169c9267af918d28fb291df948d83112807 (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.c45
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);
}
}