[PATCH 1/2] drm/panthor: Fix IO-page mmap() for 32-bit userspace on 64-bit kernel
Boris Brezillon
boris.brezillon at collabora.com
Mon Mar 25 11:24:47 UTC 2024
On Mon, 25 Mar 2024 11:12:40 +0000
Steven Price <steven.price at arm.com> wrote:
> 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.larumbe at collabora.com>
> > Reported-by: Lukas F. Hartmann <lukas at mntmn.com>
> > Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10835
> > Signed-off-by: Boris Brezillon <boris.brezillon at 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.
I like that. I'll steal your changes for v2 and update the commit
message to reflect the fact we no longer need this
panthor_device_mmio_offset() helper.
> Either way:
>
> Reviewed-by: Steven Price <steven.price at 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);
>
More information about the dri-devel
mailing list