From: Cheyenne Wills Date: Fri, 29 Jan 2021 18:32:36 +0000 (-0700) Subject: Linux: Refactor test for 32bit compat X-Git-Tag: openafs-devel-1_9_1~33 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=32cc6b0796495e596262d84c428172a511f757c4 Linux: Refactor test for 32bit compat Refactor the preprocessor checks for determining the method to test for 32bit compatibility (64bit kernel performing work for a 32bit task) into a common inline function, 'afs_in_compat_syscall' that is defined in LINUX/osi_machdep.h. Update osi_ioctl.c and afs_syscall.c to use afs_in_compat_syscall. Add include afs/sysincludes into osi_machdep.h to ensure linux/compat.h is pulled for the functions called in afs_in_compat_syscall. Change-Id: I6610cc19fedd909de8e8941ded05ed1608e52403 Reviewed-on: https://gerrit.openafs.org/14500 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Benjamin Kaduk --- diff --git a/src/afs/LINUX/osi_ioctl.c b/src/afs/LINUX/osi_ioctl.c index 9ba076a..7d35567 100644 --- a/src/afs/LINUX/osi_ioctl.c +++ b/src/afs/LINUX/osi_ioctl.c @@ -43,21 +43,13 @@ afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, { struct afsprocdata sysargs; -#ifdef NEED_IOCTL32 - struct afsprocdata32 sysargs32; -#endif if (cmd != VIOC_SYSCALL && cmd != VIOC_SYSCALL32) return -EINVAL; #ifdef NEED_IOCTL32 -# if defined(AFS_S390X_LINUX26_ENV) - if (test_thread_flag(TIF_31BIT)) -# elif defined(AFS_AMD64_LINUX20_ENV) - if (test_thread_flag(TIF_IA32)) -# else - if (test_thread_flag(TIF_32BIT)) -# endif /* AFS_S390X_LINUX26_ENV */ - { + if (afs_in_compat_syscall()) { + struct afsprocdata32 sysargs32; + if (copy_from_user(&sysargs32, (void *)arg, sizeof(struct afsprocdata32))) return -EFAULT; diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index 4053ac7..ecc2d93 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -76,6 +76,8 @@ #include "h/cred.h" #endif +#include "afs/sysincludes.h" + #if !defined(HAVE_LINUX_TIME_T) typedef time64_t time_t; #endif @@ -156,6 +158,44 @@ static inline long copyinstr(char *from, char *to, int count, int *length) { } #define copyout(F, T, C) (copy_to_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0) +/* + * Test to see for 64/32bit compatibility mode + * Return non-zero if in a 64bit kernel and handing a 32bit syscall + */ +#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) +static inline int +afs_in_compat_syscall(void) +{ +# if defined(AFS_SPARC64_LINUX26_ENV) + return test_thread_flag(TIF_32BIT); +# elif defined(AFS_SPARC64_LINUX24_ENV) + return (current->thread.flags & SPARC_FLAG_32BIT) != 0; +# elif defined(AFS_SPARC64_LINUX20_ENV) + return (current->tss.flags & SPARC_FLAG_32BIT) != 0; +# elif defined(AFS_AMD64_LINUX26_ENV) + return test_thread_flag(TIF_IA32); +# elif defined(AFS_AMD64_LINUX20_ENV) + return (current->thread.flags & THREAD_IA32) != 0; +# elif defined(AFS_PPC64_LINUX26_ENV) +# if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO) + return (current->thread_info->flags & _TIF_32BIT) != 0; +# else + return (task_thread_info(current)->flags & _TIF_32BIT) != 0; +# endif +# elif defined(AFS_PPC64_LINUX20_ENV) + return (current->thread.flags & PPC_FLAG_32BIT) != 0; +# elif defined(AFS_S390X_LINUX26_ENV) + return test_thread_flag(TIF_31BIT); +# elif defined(AFS_S390X_LINUX20_ENV) + return (current->thread.flags & S390_FLAG_31BIT) != 0; +# elif defined(AFS_ARM64_LINUX26_ENV) + return is_compat_task(); +# else +# error afs_in_compat_syscall not done for this linux +# endif +} +#endif /* AFS_LINUX_64BIT_KERNEL */ + /* kernel print statements */ #define printf(args...) printk(args) #define uprintf(args...) printk(args) diff --git a/src/afs/afs_syscall.c b/src/afs/afs_syscall.c index ce6afdf..9414f38 100644 --- a/src/afs/afs_syscall.c +++ b/src/afs/afs_syscall.c @@ -114,40 +114,9 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst) #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */ #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) - struct afs_ioctl32 dst32; - -#ifdef AFS_SPARC64_LINUX26_ENV - if (test_thread_flag(TIF_32BIT)) -#elif defined(AFS_SPARC64_LINUX24_ENV) - if (current->thread.flags & SPARC_FLAG_32BIT) -#elif defined(AFS_SPARC64_LINUX20_ENV) - if (current->tss.flags & SPARC_FLAG_32BIT) - -#elif defined(AFS_AMD64_LINUX26_ENV) - if (test_thread_flag(TIF_IA32)) -#elif defined(AFS_AMD64_LINUX20_ENV) - if (current->thread.flags & THREAD_IA32) - -#elif defined(AFS_PPC64_LINUX26_ENV) -#if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO) - if (current->thread_info->flags & _TIF_32BIT) -#else - if (task_thread_info(current)->flags & _TIF_32BIT) -#endif -#elif defined(AFS_PPC64_LINUX20_ENV) - if (current->thread.flags & PPC_FLAG_32BIT) - -#elif defined(AFS_S390X_LINUX26_ENV) - if (test_thread_flag(TIF_31BIT)) -#elif defined(AFS_S390X_LINUX20_ENV) - if (current->thread.flags & S390_FLAG_31BIT) -#elif defined(AFS_ARM64_LINUX26_ENV) - if (is_compat_task()) + if (afs_in_compat_syscall()) { + struct afs_ioctl32 dst32; -#else -#error pioctl32 not done for this linux -#endif - { AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code); if (!code) afs_ioctl32_to_afs_ioctl(&dst32, dst); @@ -391,40 +360,9 @@ copyin_iparam(caddr_t cmarg, struct iparam *dst) #endif /* AFS_SUN5_64BIT_ENV */ #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) - struct iparam32 dst32; - -#ifdef AFS_SPARC64_LINUX26_ENV - if (test_thread_flag(TIF_32BIT)) -#elif defined(AFS_SPARC64_LINUX24_ENV) - if (current->thread.flags & SPARC_FLAG_32BIT) -#elif defined(AFS_SPARC64_LINUX20_ENV) - if (current->tss.flags & SPARC_FLAG_32BIT) - -#elif defined(AFS_AMD64_LINUX26_ENV) - if (test_thread_flag(TIF_IA32)) -#elif defined(AFS_AMD64_LINUX20_ENV) - if (current->thread.flags & THREAD_IA32) - -#elif defined(AFS_PPC64_LINUX26_ENV) -#if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO) - if (current->thread_info->flags & _TIF_32BIT) -#else - if (task_thread_info(current)->flags & _TIF_32BIT) -#endif -#elif defined(AFS_PPC64_LINUX20_ENV) - if (current->thread.flags & PPC_FLAG_32BIT) - -#elif defined(AFS_S390X_LINUX26_ENV) - if (test_thread_flag(TIF_31BIT)) -#elif defined(AFS_S390X_LINUX20_ENV) - if (current->thread.flags & S390_FLAG_31BIT) -#elif defined(AFS_ARM64_LINUX26_ENV) - if (is_compat_task()) + if (afs_in_compat_syscall()) { + struct iparam32 dst32; -#else -#error iparam32 not done for this linux platform -#endif - { AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code); if (!code) iparam32_to_iparam(&dst32, dst);