summarylogtreecommitdiffstats
path: root/0008-Linux-5.11-Test-32bit-compat-with-in_compat_syscall.patch
blob: 87b7285fed0edd7a6b776abf0d7dc3477e518578 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
From 2d85a5b7a1011386d66cc36512a54e80b6cfa515 Mon Sep 17 00:00:00 2001
From: Cheyenne Wills <cwills@sinenomine.net>
Date: Fri, 22 Jan 2021 07:57:55 -0700
Subject: [PATCH 8/8] 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)

Reviewed-on: https://gerrit.openafs.org/14499
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit 78ef922612bef5f5fd6904896e84b9d2ea802404)

Change-Id: I4eca62f19ae58fd830915feff5098cec2825f099
Reviewed-on: https://gerrit.openafs.org/14511
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Tested-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
---
 src/afs/LINUX/osi_machdep.h | 4 +++-
 src/cf/linux-kernel-func.m4 | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h
index 9ecdaf0bf..066c1885f 100644
--- a/src/afs/LINUX/osi_machdep.h
+++ b/src/afs/LINUX/osi_machdep.h
@@ -167,7 +167,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 e45a30540..5b4060238 100644
--- a/src/cf/linux-kernel-func.m4
+++ b/src/cf/linux-kernel-func.m4
@@ -157,6 +157,12 @@ AC_CHECK_LINUX_FUNC([lru_cache_add_file],
                     [#include <linux/swap.h>],
                     [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 <linux/compat.h>],
+                    [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],
-- 
2.30.1