On Wed, Aug 14, 2019 at 10:42:28PM +0200, Arnd Bergmann wrote: > For 31-bit s390 user space, we have to pass pointer arguments through > compat_ptr() in the compat_ioctl handler. Seems fair enough, but... > > Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx> > --- > fs/xfs/xfs_ioctl32.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c > index 7fcf7569743f..ad91e81a2fcf 100644 > --- a/fs/xfs/xfs_ioctl32.c > +++ b/fs/xfs/xfs_ioctl32.c > @@ -547,7 +547,7 @@ xfs_file_compat_ioctl( > struct inode *inode = file_inode(filp); > struct xfs_inode *ip = XFS_I(inode); > struct xfs_mount *mp = ip->i_mount; > - void __user *arg = (void __user *)p; > + void __user *arg = compat_ptr(p); > int error; > > trace_xfs_file_compat_ioctl(ip); > @@ -576,7 +576,7 @@ xfs_file_compat_ioctl( > case XFS_IOC_SCRUB_METADATA: > case XFS_IOC_BULKSTAT: > case XFS_IOC_INUMBERS: > - return xfs_file_ioctl(filp, cmd, p); > + return xfs_file_ioctl(filp, cmd, (unsigned long)arg); I don't really like having to sprinkle special casts through the code because of this. Perhaps do something like: static inline unsigned long compat_ptr_mask(unsigned long p) { return (unsigned long)compat_ptr(p); } and then up front you can do: void __user *arg; p = compat_ptr_mask(p); arg = (void __user *)p; and then the rest of the code remains unchanged by now uses p correctly instead of having to change all the code to cast arg back to an unsigned long... Cheers, Dave. -- Dave Chinner david@xxxxxxxxxxxxx