On 25/03/2024 10:41, Boris Brezillon wrote:
> When mapping an IO region, the pseudo-file offset is dependent on the
> userspace architecture. panthor_device_mmio_offset() abstract that away
> for us by turning a userspace MMIO offset into its kernel equivalent,
> but we were not updating vm_area_struct::vm_pgoff accordingly, leading
> us to attach the MMIO region to the wrong file offset.
> 
> This has implications when we start mixing 64 bit and 32 bit apps, but
> that's only really a problem when we start having more that 2^43 bytes of
> memory allocated, which is very unlikely to happen.
> 
> What's more problematic is the fact this turns our
> unmap_mapping_range(DRM_PANTHOR_USER_MMIO_OFFSET) calls, which are
> supposed to kill the MMIO mapping when entering suspend, into NOPs.
> Which means we either keep the dummy flush_id mapping active at all
> times, or we risk a BUS_FAULT if the MMIO region was mapped, and the
> GPU is suspended after that.
> 
> Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block")
> Reported-by: Adrián Larumbe <adrian.laru...@collabora.com>
> Reported-by: Lukas F. Hartmann <lu...@mntmn.com>
> Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10835
> Signed-off-by: Boris Brezillon <boris.brezil...@collabora.com>

Pesky 32 bit again ;)

Looks fine, although I'm wondering whether you'd consider squashing
something like the below on top? I think it helps contain the 32 bit
specific code to the one place. Either way:

Reviewed-by: Steven Price <steven.pr...@arm.com>

---
diff --git a/drivers/gpu/drm/panthor/panthor_device.c 
b/drivers/gpu/drm/panthor/panthor_device.c
index f7f8184b1992..75276cbeba20 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -392,7 +392,7 @@ static const struct vm_operations_struct 
panthor_mmio_vm_ops = {
 
 int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct 
*vma)
 {
-       u64 offset = panthor_device_mmio_offset((u64)vma->vm_pgoff << 
PAGE_SHIFT);
+       u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
 
        switch (offset) {
        case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
@@ -406,9 +406,6 @@ int panthor_device_mmap_io(struct panthor_device *ptdev, 
struct vm_area_struct *
                return -EINVAL;
        }
 
-       /* Adjust vm_pgoff for 32-bit userspace on 64-bit kernel. */
-       vma->vm_pgoff = offset >> PAGE_SHIFT;
-
        /* Defer actual mapping to the fault handler. */
        vma->vm_private_data = ptdev;
        vma->vm_ops = &panthor_mmio_vm_ops;
diff --git a/drivers/gpu/drm/panthor/panthor_device.h 
b/drivers/gpu/drm/panthor/panthor_device.h
index 8e2922c79aca..99ad576912b3 100644
--- a/drivers/gpu/drm/panthor/panthor_device.h
+++ b/drivers/gpu/drm/panthor/panthor_device.h
@@ -373,30 +373,6 @@ static int panthor_request_ ## __name ## _irq(struct 
panthor_device *ptdev,                        \
                                         pirq);                                 
                \
 }
 
-/**
- * panthor_device_mmio_offset() - Turn a user MMIO offset into a kernel one
- * @offset: Offset to convert.
- *
- * With 32-bit systems being limited by the 32-bit representation of mmap2's
- * pgoffset field, we need to make the MMIO offset arch specific. This function
- * converts a user MMIO offset into something the kernel driver understands.
- *
- * If the kernel and userspace architecture match, the offset is unchanged. If
- * the kernel is 64-bit and userspace is 32-bit, the offset is adjusted to 
match
- * 64-bit offsets. 32-bit kernel with 64-bit userspace is impossible.
- *
- * Return: Adjusted offset.
- */
-static inline u64 panthor_device_mmio_offset(u64 offset)
-{
-#ifdef CONFIG_ARM64
-       if (test_tsk_thread_flag(current, TIF_32BIT))
-               offset += DRM_PANTHOR_USER_MMIO_OFFSET_64BIT - 
DRM_PANTHOR_USER_MMIO_OFFSET_32BIT;
-#endif
-
-       return offset;
-}
-
 extern struct workqueue_struct *panthor_cleanup_wq;
 
 #endif
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c 
b/drivers/gpu/drm/panthor/panthor_drv.c
index 11b3ccd58f85..730dd0c69cb8 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1327,7 +1327,22 @@ static int panthor_mmap(struct file *filp, struct 
vm_area_struct *vma)
        if (!drm_dev_enter(file->minor->dev, &cookie))
                return -ENODEV;
 
-       if (panthor_device_mmio_offset(offset) >= DRM_PANTHOR_USER_MMIO_OFFSET)
+#ifdef CONFIG_ARM64
+       /*
+        * With 32-bit systems being limited by the 32-bit representation of
+        * mmap2's pgoffset field, we need to make the MMIO offset arch
+        * specific. This converts a user MMIO offset into something the kernel
+        * driver understands.
+        */
+       if (test_tsk_thread_flag(current, TIF_32BIT) &&
+           offset >= DRM_PANTHOR_USER_MMIO_OFFSET_32BIT) {
+               offset += DRM_PANTHOR_USER_MMIO_OFFSET_64BIT -
+                         DRM_PANTHOR_USER_MMIO_OFFSET_32BIT;
+               vma->vm_pgoff = offset >> PAGE_SHIFT;
+       }
+#endif
+
+       if (offset >= DRM_PANTHOR_USER_MMIO_OFFSET)
                ret = panthor_device_mmap_io(ptdev, vma);
        else
                ret = drm_gem_mmap(filp, vma);

Reply via email to