Linux: Refactor test for 32bit compat 00/14500/5
authorCheyenne Wills <cwills@sinenomine.net>
Fri, 29 Jan 2021 18:32:36 +0000 (11:32 -0700)
committerBenjamin Kaduk <kaduk@mit.edu>
Sat, 30 Jan 2021 20:28:43 +0000 (15:28 -0500)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/LINUX/osi_ioctl.c
src/afs/LINUX/osi_machdep.h
src/afs/afs_syscall.c

index 9ba076a..7d35567 100644 (file)
@@ -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;
index 4053ac7..ecc2d93 100644 (file)
@@ -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)
index ce6afdf..9414f38 100644 (file)
@@ -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);