x86/syscalls: Split the x32 syscalls into their own table
[sfrench/cifs-2.6.git] / arch / x86 / entry / common.c
index 536b574b61613403618c3db62d72c6adac91af98..3f8e22615812bf4d82c3dd6a0e2c878ecf61f3ec 100644 (file)
@@ -285,15 +285,16 @@ __visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
        if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY)
                nr = syscall_trace_enter(regs);
 
-       /*
-        * NB: Native and x32 syscalls are dispatched from the same
-        * table.  The only functional difference is the x32 bit in
-        * regs->orig_ax, which changes the behavior of some syscalls.
-        */
-       nr &= __SYSCALL_MASK;
        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
        }
 
        syscall_return_slowpath(regs);