Converting from int to long, back to int and then to unsigned int is
confusing at best.

None of this voodoo is required. Negative syscall numbers including -1
don't need any of this treatment and the low level ASM code already does
the sign extension to 64-bit on a 64-bit kernel.

The only point where signedness matters is the comparison against the
maximum syscall number, but that can be simplified by just using a unsigned
argument for the various syscall invocation functions.

Signed-off-by: Thomas Gleixner <[email protected]>
---
 arch/x86/entry/syscall_32.c    |   26 +++++++++++---------------
 arch/x86/entry/syscall_64.c    |   36 ++++++++++++++----------------------
 arch/x86/include/asm/syscall.h |    2 +-
 3 files changed, 26 insertions(+), 38 deletions(-)

--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -41,6 +41,8 @@ const sys_call_ptr_t sys_call_table[] =
 #endif
 
 #define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs);
+
+/* The unsigned int @nr argument is intentional as it creates denser code in a 
64-bit build */
 static noinline long ia32_sys_call(const struct pt_regs *regs, unsigned int nr)
 {
        switch (nr) {
@@ -49,7 +51,7 @@ static noinline long ia32_sys_call(const
        }
 }
 
-static __always_inline int syscall_32_enter(struct pt_regs *regs)
+static __always_inline long syscall_32_enter(struct pt_regs *regs)
 {
        if (IS_ENABLED(CONFIG_IA32_EMULATION))
                current_thread_info()->status |= TS_COMPAT;
@@ -70,17 +72,11 @@ early_param("ia32_emulation", ia32_emula
 /*
  * Invoke a 32-bit syscall.  Called with IRQs on in CT_STATE_KERNEL.
  */
-static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
+static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, 
unsigned long nr)
 {
-       /*
-        * 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(regs, unr);
+       if (likely(nr < IA32_NR_syscalls)) {
+               nr = array_index_nospec(nr, IA32_NR_syscalls);
+               regs->ax = ia32_sys_call(regs, (unsigned int)nr);
        }
 }
 
@@ -126,7 +122,7 @@ static __always_inline bool int80_is_ext
  */
 __visible noinstr void do_int80_emulation(struct pt_regs *regs)
 {
-       int nr;
+       long nr;
 
        /* Kernel does not use INT $0x80! */
        if (unlikely(!user_mode(regs))) {
@@ -205,7 +201,7 @@ static __always_inline bool int80_is_ext
  */
 DEFINE_FREDENTRY_RAW(int80_emulation)
 {
-       int nr;
+       long nr;
 
        enter_from_user_mode_randomize_stack(regs);
 
@@ -240,7 +236,7 @@ DEFINE_FREDENTRY_RAW(int80_emulation)
 /* Handles int $0x80 on a 32bit kernel */
 __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
 {
-       int nr = syscall_32_enter(regs);
+       long nr = syscall_32_enter(regs);
 
        /*
         * Subtlety here: if ptrace pokes something larger than 2^31-1 into
@@ -260,7 +256,7 @@ DEFINE_FREDENTRY_RAW(int80_emulation)
 
 static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
 {
-       int nr = syscall_32_enter(regs);
+       long nr = syscall_32_enter(regs);
        int res;
 
        enter_from_user_mode_randomize_stack(regs);
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -32,6 +32,8 @@ const sys_call_ptr_t sys_call_table[] =
 #undef  __SYSCALL
 
 #define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
+
+/* The unsigned int @nr argument is intentional as it creates denser code */
 static noinline long x64_sys_call(const struct pt_regs *regs, unsigned int nr)
 {
        switch (nr) {
@@ -52,39 +54,29 @@ static noinline long x32_sys_call(const
 #endif
 }
 
-static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
+static __always_inline bool do_syscall_x64(struct pt_regs *regs, unsigned long 
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 = x64_sys_call(regs, unr);
+       if (likely(nr < NR_syscalls)) {
+               nr = array_index_nospec(nr, NR_syscalls);
+               regs->ax = x64_sys_call(regs, (unsigned int)nr);
                return true;
        }
        return false;
 }
 
-static __always_inline void do_syscall_x32(struct pt_regs *regs, int nr)
+static __always_inline void do_syscall_x32(struct pt_regs *regs, unsigned long 
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(regs, xnr);
+       /* Adjust the starting offset of the table */
+       nr -= __X32_SYSCALL_BIT;
+
+       if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(nr < X32_NR_syscalls)) {
+               nr = array_index_nospec(nr, X32_NR_syscalls);
+               regs->ax = x32_sys_call(regs, (unsigned int)nr);
        }
 }
 
 /* Returns true to return using SYSRET, or false to use IRET */
-__visible noinstr bool do_syscall_64(struct pt_regs *regs, int nr)
+__visible noinstr bool do_syscall_64(struct pt_regs *regs, long nr)
 {
        nr = syscall_enter_from_user_mode_randomize_stack(regs, nr);
 
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -164,7 +164,7 @@ static inline int syscall_get_arch(struc
                ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
 }
 
-bool do_syscall_64(struct pt_regs *regs, int nr);
+bool do_syscall_64(struct pt_regs *regs, long nr);
 void do_int80_emulation(struct pt_regs *regs);
 
 #endif /* CONFIG_X86_32 */


Reply via email to