From: Cheyenne Wills Date: Fri, 22 Jan 2021 14:57:55 +0000 (-0700) Subject: Linux 5.11: Test 32bit compat with in_compat_syscall X-Git-Tag: openafs-devel-1_9_1~32 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=78ef922612bef5f5fd6904896e84b9d2ea802404 Linux 5.11: Test 32bit compat with in_compat_syscall Linux 5.11 removed the TIF_IA32 thread flag with commit: x86: Reclaim TIF_IA32 and TIF_X32 (8d71d2bf6efec) The flag TIF_IA32 was being used by openafs to determine if the task was handling a syscall request from a 32 bit process. Building against a Linux 5.11 kernel results in a build failure as TIF_IA32 is undefined. The function 'in_compat_syscall' was introduced in Linux 4.6 as the preferred method to determine if a syscall needed to handle a compatible call (e.g. 32bit application). To resolve the build problem, use 'in_compat_syscall' if present (Linux 4.6 and later) to determine if the syscall needs to handle a compatibility mode call. Add autoconf check for in_compat_syscall. Notes about in_compat_syscall: In Linux 4.6 'in_compat_syscall' was defined for all architectures with a generic return of 'is_compat_task', but allows architecture specific overriding implementations (x86 and sparc). At 4.6 (and later), the function 'is_compat_task' is defined only for the following architectures to return: Arch Returns ======= ============================== arm64 test_thread_flag(TIF_32BIT); mips test_thread_flag(TIF_32BIT_ADDR) parisc test_ti_thread_flag(task_thread_info(t), TIF_32BIT) powerpc is_32bit_task() s390 test_thread_flag(TIF_31BIT) sparc test_thread_flag(TIF_32BIT) If the Linux kernel is not built with compat mode, is_compat_task and in_compat_syscall is set to always return 0 Linux commit that introduced in_compat_syscall: compat: add in_compat_syscall to ask whether we're in a compat syscall (5180e3e24fd3e8e7) Change-Id: I59deebfe5d8cddaf845b15ef69e65a684a961280 Reviewed-on: https://gerrit.openafs.org/14499 Reviewed-by: Andrew Deason Reviewed-by: Benjamin Kaduk Tested-by: BuildBot --- diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index ecc2d93..fe48781 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -166,7 +166,9 @@ static inline long copyinstr(char *from, char *to, int count, int *length) { static inline int afs_in_compat_syscall(void) { -# if defined(AFS_SPARC64_LINUX26_ENV) +# if defined(HAVE_LINUX_IN_COMPAT_SYSCALL) + return in_compat_syscall(); +# elif 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; diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4 index 4651b5b..0ca3e44 100644 --- a/src/cf/linux-kernel-func.m4 +++ b/src/cf/linux-kernel-func.m4 @@ -160,6 +160,12 @@ AC_CHECK_LINUX_FUNC([lru_cache_add_file], [#include ], [lru_cache_add_file(NULL);]) +dnl Linux 4.6 introduced in_compat_syscall as replacement for is_compat_task +dnl for certain platforms. +AC_CHECK_LINUX_FUNC([in_compat_syscall], + [#include ], + [in_compat_syscall();]) + dnl lru_cache_add exported in Linux 5.8 dnl replaces lru_cache_add_file AC_CHECK_LINUX_FUNC([lru_cache_add],