Skip to content

Commit 9142be9

Browse files
jpoimboebp3tk0v
authored andcommitted
x86/syscall: Mark exit[_group] syscall handlers __noreturn
The direct-call syscall dispatch function doesn't know that the exit() and exit_group() syscall handlers don't return, so the call sites aren't optimized accordingly. Fix that by marking the exit syscall declarations __noreturn. Fixes the following warnings: vmlinux.o: warning: objtool: x64_sys_call+0x2804: __x64_sys_exit() is missing a __noreturn annotation vmlinux.o: warning: objtool: ia32_sys_call+0x29b6: __ia32_sys_exit_group() is missing a __noreturn annotation Fixes: 1e3ad78 ("x86/syscall: Don't force use of indirect calls for system calls") Closes: https://lkml.kernel.org/lkml/6dba9b32-db2c-4e6d-9500-7a08852f17a3@paulmck-laptop Reported-by: Paul E. McKenney <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Tested-by: Paul E. McKenney <[email protected]> Link: https://lore.kernel.org/r/5d8882bc077d8eadcc7fd1740b56dfb781f12288.1719381528.git.jpoimboe@kernel.org
1 parent f266106 commit 9142be9

File tree

9 files changed

+56
-25
lines changed

9 files changed

+56
-25
lines changed

arch/x86/entry/syscall_32.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
#endif
1515

1616
#define __SYSCALL(nr, sym) extern long __ia32_##sym(const struct pt_regs *);
17-
17+
#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __ia32_##sym(const struct pt_regs *);
1818
#include <asm/syscalls_32.h>
19-
#undef __SYSCALL
19+
#undef __SYSCALL
20+
21+
#undef __SYSCALL_NORETURN
22+
#define __SYSCALL_NORETURN __SYSCALL
2023

2124
/*
2225
* The sys_call_table[] is no longer used for system calls, but
@@ -28,11 +31,10 @@
2831
const sys_call_ptr_t sys_call_table[] = {
2932
#include <asm/syscalls_32.h>
3033
};
31-
#undef __SYSCALL
34+
#undef __SYSCALL
3235
#endif
3336

3437
#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs);
35-
3638
long ia32_sys_call(const struct pt_regs *regs, unsigned int nr)
3739
{
3840
switch (nr) {

arch/x86/entry/syscall_64.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88
#include <asm/syscall.h>
99

1010
#define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
11+
#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
1112
#include <asm/syscalls_64.h>
12-
#undef __SYSCALL
13+
#undef __SYSCALL
14+
15+
#undef __SYSCALL_NORETURN
16+
#define __SYSCALL_NORETURN __SYSCALL
1317

1418
/*
1519
* The sys_call_table[] is no longer used for system calls, but
@@ -20,10 +24,9 @@
2024
const sys_call_ptr_t sys_call_table[] = {
2125
#include <asm/syscalls_64.h>
2226
};
23-
#undef __SYSCALL
27+
#undef __SYSCALL
2428

2529
#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
26-
2730
long x64_sys_call(const struct pt_regs *regs, unsigned int nr)
2831
{
2932
switch (nr) {

arch/x86/entry/syscall_x32.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
#include <asm/syscall.h>
99

1010
#define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
11+
#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
1112
#include <asm/syscalls_x32.h>
12-
#undef __SYSCALL
13+
#undef __SYSCALL
1314

14-
#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
15+
#undef __SYSCALL_NORETURN
16+
#define __SYSCALL_NORETURN __SYSCALL
1517

18+
#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
1619
long x32_sys_call(const struct pt_regs *regs, unsigned int nr)
1720
{
1821
switch (nr) {

arch/x86/entry/syscalls/syscall_32.tbl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# 32-bit system call numbers and entry vectors
33
#
44
# The format is:
5-
# <number> <abi> <name> <entry point> <compat entry point>
5+
# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
66
#
77
# The __ia32_sys and __ia32_compat_sys stubs are created on-the-fly for
88
# sys_*() system calls and compat_sys_*() compat system calls if
@@ -12,7 +12,7 @@
1212
# The abi is always "i386" for this file.
1313
#
1414
0 i386 restart_syscall sys_restart_syscall
15-
1 i386 exit sys_exit
15+
1 i386 exit sys_exit - noreturn
1616
2 i386 fork sys_fork
1717
3 i386 read sys_read
1818
4 i386 write sys_write
@@ -263,7 +263,7 @@
263263
249 i386 io_cancel sys_io_cancel
264264
250 i386 fadvise64 sys_ia32_fadvise64
265265
# 251 is available for reuse (was briefly sys_set_zone_reclaim)
266-
252 i386 exit_group sys_exit_group
266+
252 i386 exit_group sys_exit_group - noreturn
267267
253 i386 lookup_dcookie
268268
254 i386 epoll_create sys_epoll_create
269269
255 i386 epoll_ctl sys_epoll_ctl

arch/x86/entry/syscalls/syscall_64.tbl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# 64-bit system call numbers and entry vectors
33
#
44
# The format is:
5-
# <number> <abi> <name> <entry point>
5+
# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
66
#
77
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
88
#
@@ -68,7 +68,7 @@
6868
57 common fork sys_fork
6969
58 common vfork sys_vfork
7070
59 64 execve sys_execve
71-
60 common exit sys_exit
71+
60 common exit sys_exit - noreturn
7272
61 common wait4 sys_wait4
7373
62 common kill sys_kill
7474
63 common uname sys_newuname
@@ -239,7 +239,7 @@
239239
228 common clock_gettime sys_clock_gettime
240240
229 common clock_getres sys_clock_getres
241241
230 common clock_nanosleep sys_clock_nanosleep
242-
231 common exit_group sys_exit_group
242+
231 common exit_group sys_exit_group - noreturn
243243
232 common epoll_wait sys_epoll_wait
244244
233 common epoll_ctl sys_epoll_ctl
245245
234 common tgkill sys_tgkill

arch/x86/um/sys_call_table_32.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <linux/cache.h>
1010
#include <asm/syscall.h>
1111

12+
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
13+
unsigned long, unsigned long,
14+
unsigned long, unsigned long);
15+
1216
/*
1317
* Below you can see, in terms of #define's, the differences between the x86-64
1418
* and the UML syscall table.
@@ -22,15 +26,13 @@
2226
#define sys_vm86 sys_ni_syscall
2327

2428
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
29+
#define __SYSCALL_NORETURN __SYSCALL
2530

2631
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
2732
#include <asm/syscalls_32.h>
33+
#undef __SYSCALL
2834

29-
#undef __SYSCALL
3035
#define __SYSCALL(nr, sym) sym,
31-
32-
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
33-
3436
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
3537
#include <asm/syscalls_32.h>
3638
};

arch/x86/um/sys_call_table_64.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <linux/cache.h>
1010
#include <asm/syscall.h>
1111

12+
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
13+
unsigned long, unsigned long,
14+
unsigned long, unsigned long);
15+
1216
/*
1317
* Below you can see, in terms of #define's, the differences between the x86-64
1418
* and the UML syscall table.
@@ -18,14 +22,13 @@
1822
#define sys_iopl sys_ni_syscall
1923
#define sys_ioperm sys_ni_syscall
2024

25+
#define __SYSCALL_NORETURN __SYSCALL
26+
2127
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
2228
#include <asm/syscalls_64.h>
29+
#undef __SYSCALL
2330

24-
#undef __SYSCALL
2531
#define __SYSCALL(nr, sym) sym,
26-
27-
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
28-
2932
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
3033
#include <asm/syscalls_64.h>
3134
};

scripts/syscalltbl.sh

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ nxt=0
5454

5555
grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | {
5656

57-
while read nr abi name native compat ; do
57+
while read nr abi name native compat noreturn; do
5858

5959
if [ $nxt -gt $nr ]; then
6060
echo "error: $infile: syscall table is not sorted or duplicates the same syscall number" >&2
@@ -66,7 +66,21 @@ grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | {
6666
nxt=$((nxt + 1))
6767
done
6868

69-
if [ -n "$compat" ]; then
69+
if [ "$compat" = "-" ]; then
70+
unset compat
71+
fi
72+
73+
if [ -n "$noreturn" ]; then
74+
if [ "$noreturn" != "noreturn" ]; then
75+
echo "error: $infile: invalid string \"$noreturn\" in 'noreturn' column"
76+
exit 1
77+
fi
78+
if [ -n "$compat" ]; then
79+
echo "__SYSCALL_COMPAT_NORETURN($nr, $native, $compat)"
80+
else
81+
echo "__SYSCALL_NORETURN($nr, $native)"
82+
fi
83+
elif [ -n "$compat" ]; then
7084
echo "__SYSCALL_WITH_COMPAT($nr, $native, $compat)"
7185
elif [ -n "$native" ]; then
7286
echo "__SYSCALL($nr, $native)"

tools/objtool/noreturns.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
* Yes, this is unfortunate. A better solution is in the works.
88
*/
99
NORETURN(__fortify_panic)
10+
NORETURN(__ia32_sys_exit)
11+
NORETURN(__ia32_sys_exit_group)
1012
NORETURN(__kunit_abort)
1113
NORETURN(__module_put_and_kthread_exit)
1214
NORETURN(__reiserfs_panic)
1315
NORETURN(__stack_chk_fail)
1416
NORETURN(__tdx_hypercall_failed)
1517
NORETURN(__ubsan_handle_builtin_unreachable)
18+
NORETURN(__x64_sys_exit)
19+
NORETURN(__x64_sys_exit_group)
1620
NORETURN(arch_cpu_idle_dead)
1721
NORETURN(bch2_trans_in_restart_error)
1822
NORETURN(bch2_trans_restart_error)

0 commit comments

Comments
 (0)