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) <hpa@zytor.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20210518191303.4135296-7-hpa@zytor.com
This commit is contained in:
parent
b337b4965e
commit
2978996f62
|
@ -36,49 +36,81 @@
|
|||
#include <asm/irq_stack.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
__visible noinstr void do_syscall_64(struct pt_regs *regs, unsigned long nr)
|
||||
|
||||
static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
|
||||
{
|
||||
/*
|
||||
* Convert negative numbers to very high and thus out of range
|
||||
* numbers for comparisons.
|
||||
*/
|
||||
unsigned int unr = nr;
|
||||
|
||||
if (likely(unr < NR_syscalls)) {
|
||||
unr = array_index_nospec(unr, NR_syscalls);
|
||||
regs->ax = sys_call_table[unr](regs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static __always_inline bool do_syscall_x32(struct pt_regs *regs, int nr)
|
||||
{
|
||||
/*
|
||||
* Adjust the starting offset of the table, and convert numbers
|
||||
* < __X32_SYSCALL_BIT to very high and thus out of range
|
||||
* numbers for comparisons.
|
||||
*/
|
||||
unsigned int xnr = nr - __X32_SYSCALL_BIT;
|
||||
|
||||
if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
|
||||
xnr = array_index_nospec(xnr, X32_NR_syscalls);
|
||||
regs->ax = x32_sys_call_table[xnr](regs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
__visible noinstr void do_syscall_64(struct pt_regs *regs, int nr)
|
||||
{
|
||||
add_random_kstack_offset();
|
||||
nr = syscall_enter_from_user_mode(regs, nr);
|
||||
|
||||
instrumentation_begin();
|
||||
if (likely(nr < NR_syscalls)) {
|
||||
nr = array_index_nospec(nr, NR_syscalls);
|
||||
regs->ax = sys_call_table[nr](regs);
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
} else if (likely((nr & __X32_SYSCALL_BIT) &&
|
||||
(nr & ~__X32_SYSCALL_BIT) < X32_NR_syscalls)) {
|
||||
nr = array_index_nospec(nr & ~__X32_SYSCALL_BIT,
|
||||
X32_NR_syscalls);
|
||||
regs->ax = x32_sys_call_table[nr](regs);
|
||||
#endif
|
||||
} else if (unlikely((int)nr != -1)) {
|
||||
|
||||
if (!do_syscall_x64(regs, nr) && !do_syscall_x32(regs, nr) && nr != -1) {
|
||||
/* Invalid system call, but still a system call. */
|
||||
regs->ax = __x64_sys_ni_syscall(regs);
|
||||
}
|
||||
|
||||
instrumentation_end();
|
||||
syscall_exit_to_user_mode(regs);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
|
||||
static __always_inline unsigned int syscall_32_enter(struct pt_regs *regs)
|
||||
static __always_inline int syscall_32_enter(struct pt_regs *regs)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_IA32_EMULATION))
|
||||
current_thread_info()->status |= TS_COMPAT;
|
||||
|
||||
return (unsigned int)regs->orig_ax;
|
||||
return (int)regs->orig_ax;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL.
|
||||
*/
|
||||
static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs,
|
||||
unsigned int nr)
|
||||
static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
|
||||
{
|
||||
if (likely(nr < IA32_NR_syscalls)) {
|
||||
nr = array_index_nospec(nr, IA32_NR_syscalls);
|
||||
regs->ax = ia32_sys_call_table[nr](regs);
|
||||
} else if (unlikely((int)nr != -1)) {
|
||||
/*
|
||||
* Convert negative numbers to very high and thus out of range
|
||||
* numbers for comparisons.
|
||||
*/
|
||||
unsigned int unr = nr;
|
||||
|
||||
if (likely(unr < IA32_NR_syscalls)) {
|
||||
unr = array_index_nospec(unr, IA32_NR_syscalls);
|
||||
regs->ax = ia32_sys_call_table[unr](regs);
|
||||
} else if (nr != -1) {
|
||||
regs->ax = __ia32_sys_ni_syscall(regs);
|
||||
}
|
||||
}
|
||||
|
@ -86,15 +118,15 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs,
|
|||
/* Handles int $0x80 */
|
||||
__visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int nr = syscall_32_enter(regs);
|
||||
int nr = syscall_32_enter(regs);
|
||||
|
||||
add_random_kstack_offset();
|
||||
/*
|
||||
* Subtlety here: if ptrace pokes something larger than 2^32-1 into
|
||||
* orig_ax, the unsigned int return value truncates it. This may
|
||||
* or may not be necessary, but it matches the old asm behavior.
|
||||
* Subtlety here: if ptrace pokes something larger than 2^31-1 into
|
||||
* orig_ax, the int return value truncates it. This matches
|
||||
* the semantics of syscall_get_nr().
|
||||
*/
|
||||
nr = (unsigned int)syscall_enter_from_user_mode(regs, nr);
|
||||
nr = syscall_enter_from_user_mode(regs, nr);
|
||||
instrumentation_begin();
|
||||
|
||||
do_syscall_32_irqs_on(regs, nr);
|
||||
|
@ -105,7 +137,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
|
|||
|
||||
static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int nr = syscall_32_enter(regs);
|
||||
int nr = syscall_32_enter(regs);
|
||||
int res;
|
||||
|
||||
add_random_kstack_offset();
|
||||
|
@ -140,8 +172,7 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* The case truncates any ptrace induced syscall nr > 2^32 -1 */
|
||||
nr = (unsigned int)syscall_enter_from_user_mode_work(regs, nr);
|
||||
nr = syscall_enter_from_user_mode_work(regs, nr);
|
||||
|
||||
/* Now this is just like a normal syscall. */
|
||||
do_syscall_32_irqs_on(regs, nr);
|
||||
|
|
|
@ -159,7 +159,7 @@ static inline int syscall_get_arch(struct task_struct *task)
|
|||
? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
|
||||
}
|
||||
|
||||
void do_syscall_64(struct pt_regs *regs, unsigned long nr);
|
||||
void do_syscall_64(struct pt_regs *regs, int nr);
|
||||
void do_int80_syscall_32(struct pt_regs *regs);
|
||||
long do_fast_syscall_32(struct pt_regs *regs);
|
||||
|
||||
|
|
Loading…
Reference in New Issue