Skip to content

Commit 2978996

Browse files
H. Peter Anvin (Intel)KAGA-KOKO
authored andcommitted
x86/entry: Use int everywhere for system call numbers
System call numbers are defined as int, so use int everywhere for system call numbers. This is strictly a cleanup; it should not change anything user visible; all ABI changes have been done in the preceeding patches. [ tglx: Replaced the unsigned long cast ] Signed-off-by: H. Peter Anvin (Intel) <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b337b49 commit 2978996

File tree

2 files changed

+60
-29
lines changed

2 files changed

+60
-29
lines changed

arch/x86/entry/common.c

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,65 +36,97 @@
3636
#include <asm/irq_stack.h>
3737

3838
#ifdef CONFIG_X86_64
39-
__visible noinstr void do_syscall_64(struct pt_regs *regs, unsigned long nr)
39+
40+
static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
41+
{
42+
/*
43+
* Convert negative numbers to very high and thus out of range
44+
* numbers for comparisons.
45+
*/
46+
unsigned int unr = nr;
47+
48+
if (likely(unr < NR_syscalls)) {
49+
unr = array_index_nospec(unr, NR_syscalls);
50+
regs->ax = sys_call_table[unr](regs);
51+
return true;
52+
}
53+
return false;
54+
}
55+
56+
static __always_inline bool do_syscall_x32(struct pt_regs *regs, int nr)
57+
{
58+
/*
59+
* Adjust the starting offset of the table, and convert numbers
60+
* < __X32_SYSCALL_BIT to very high and thus out of range
61+
* numbers for comparisons.
62+
*/
63+
unsigned int xnr = nr - __X32_SYSCALL_BIT;
64+
65+
if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
66+
xnr = array_index_nospec(xnr, X32_NR_syscalls);
67+
regs->ax = x32_sys_call_table[xnr](regs);
68+
return true;
69+
}
70+
return false;
71+
}
72+
73+
__visible noinstr void do_syscall_64(struct pt_regs *regs, int nr)
4074
{
4175
add_random_kstack_offset();
4276
nr = syscall_enter_from_user_mode(regs, nr);
4377

4478
instrumentation_begin();
45-
if (likely(nr < NR_syscalls)) {
46-
nr = array_index_nospec(nr, NR_syscalls);
47-
regs->ax = sys_call_table[nr](regs);
48-
#ifdef CONFIG_X86_X32_ABI
49-
} else if (likely((nr & __X32_SYSCALL_BIT) &&
50-
(nr & ~__X32_SYSCALL_BIT) < X32_NR_syscalls)) {
51-
nr = array_index_nospec(nr & ~__X32_SYSCALL_BIT,
52-
X32_NR_syscalls);
53-
regs->ax = x32_sys_call_table[nr](regs);
54-
#endif
55-
} else if (unlikely((int)nr != -1)) {
79+
80+
if (!do_syscall_x64(regs, nr) && !do_syscall_x32(regs, nr) && nr != -1) {
81+
/* Invalid system call, but still a system call. */
5682
regs->ax = __x64_sys_ni_syscall(regs);
5783
}
84+
5885
instrumentation_end();
5986
syscall_exit_to_user_mode(regs);
6087
}
6188
#endif
6289

6390
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
64-
static __always_inline unsigned int syscall_32_enter(struct pt_regs *regs)
91+
static __always_inline int syscall_32_enter(struct pt_regs *regs)
6592
{
6693
if (IS_ENABLED(CONFIG_IA32_EMULATION))
6794
current_thread_info()->status |= TS_COMPAT;
6895

69-
return (unsigned int)regs->orig_ax;
96+
return (int)regs->orig_ax;
7097
}
7198

7299
/*
73100
* Invoke a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL.
74101
*/
75-
static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs,
76-
unsigned int nr)
102+
static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
77103
{
78-
if (likely(nr < IA32_NR_syscalls)) {
79-
nr = array_index_nospec(nr, IA32_NR_syscalls);
80-
regs->ax = ia32_sys_call_table[nr](regs);
81-
} else if (unlikely((int)nr != -1)) {
104+
/*
105+
* Convert negative numbers to very high and thus out of range
106+
* numbers for comparisons.
107+
*/
108+
unsigned int unr = nr;
109+
110+
if (likely(unr < IA32_NR_syscalls)) {
111+
unr = array_index_nospec(unr, IA32_NR_syscalls);
112+
regs->ax = ia32_sys_call_table[unr](regs);
113+
} else if (nr != -1) {
82114
regs->ax = __ia32_sys_ni_syscall(regs);
83115
}
84116
}
85117

86118
/* Handles int $0x80 */
87119
__visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
88120
{
89-
unsigned int nr = syscall_32_enter(regs);
121+
int nr = syscall_32_enter(regs);
90122

91123
add_random_kstack_offset();
92124
/*
93-
* Subtlety here: if ptrace pokes something larger than 2^32-1 into
94-
* orig_ax, the unsigned int return value truncates it. This may
95-
* or may not be necessary, but it matches the old asm behavior.
125+
* Subtlety here: if ptrace pokes something larger than 2^31-1 into
126+
* orig_ax, the int return value truncates it. This matches
127+
* the semantics of syscall_get_nr().
96128
*/
97-
nr = (unsigned int)syscall_enter_from_user_mode(regs, nr);
129+
nr = syscall_enter_from_user_mode(regs, nr);
98130
instrumentation_begin();
99131

100132
do_syscall_32_irqs_on(regs, nr);
@@ -105,7 +137,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
105137

106138
static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
107139
{
108-
unsigned int nr = syscall_32_enter(regs);
140+
int nr = syscall_32_enter(regs);
109141
int res;
110142

111143
add_random_kstack_offset();
@@ -140,8 +172,7 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
140172
return false;
141173
}
142174

143-
/* The case truncates any ptrace induced syscall nr > 2^32 -1 */
144-
nr = (unsigned int)syscall_enter_from_user_mode_work(regs, nr);
175+
nr = syscall_enter_from_user_mode_work(regs, nr);
145176

146177
/* Now this is just like a normal syscall. */
147178
do_syscall_32_irqs_on(regs, nr);

arch/x86/include/asm/syscall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ static inline int syscall_get_arch(struct task_struct *task)
159159
? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
160160
}
161161

162-
void do_syscall_64(struct pt_regs *regs, unsigned long nr);
162+
void do_syscall_64(struct pt_regs *regs, int nr);
163163
void do_int80_syscall_32(struct pt_regs *regs);
164164
long do_fast_syscall_32(struct pt_regs *regs);
165165

0 commit comments

Comments
 (0)