Commit 1dfb0f47 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-entry-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 entry code related updates from Thomas Gleixner:

 - Consolidate the macros for .byte ... opcode sequences

 - Deduplicate register offset defines in include files

 - Simplify the ia32,x32 compat handling of the related syscall tables
   to get rid of #ifdeffery.

 - Clear all EFLAGS which are not required for syscall handling

 - Consolidate the syscall tables and switch the generation over to the
   generic shell script and remove the CFLAGS tweaks which are not
   longer required.

 - Use 'int' type for system call numbers to match the generic code.

 - Add more selftests for syscalls

* tag 'x86-entry-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/syscalls: Don't adjust CFLAGS for syscall tables
  x86/syscalls: Remove -Wno-override-init for syscall tables
  x86/uml/syscalls: Remove array index from syscall initializers
  x86/syscalls: Clear 'offset' and 'prefix' in case they are set in env
  x86/entry: Use int everywhere for system call numbers
  x86/entry: Treat out of range and gap system calls the same
  x86/entry/64: Sign-extend system calls on entry to int
  selftests/x86/syscall: Add tests under ptrace to syscall_numbering_64
  selftests/x86/syscall: Simplify message reporting in syscall_numbering
  selftests/x86/syscall: Update and extend syscall_numbering_64
  x86/syscalls: Switch to generic syscallhdr.sh
  x86/syscalls: Use __NR_syscalls instead of __NR_syscall_max
  x86/unistd: Define X32_NR_syscalls only for 64-bit kernel
  x86/syscalls: Stop filling syscall arrays with *_sys_ni_syscall
  x86/syscalls: Switch to generic syscalltbl.sh
  x86/entry/x32: Rename __x32_compat_sys_* to __x64_compat_sys_*
parents a22c3f61 48f7eee8
...@@ -41,7 +41,7 @@ void handle_syscall(struct uml_pt_regs *r) ...@@ -41,7 +41,7 @@ void handle_syscall(struct uml_pt_regs *r)
goto out; goto out;
syscall = UPT_SYSCALL_NR(r); syscall = UPT_SYSCALL_NR(r);
if (syscall >= 0 && syscall <= __NR_syscall_max) if (syscall >= 0 && syscall < __NR_syscalls)
PT_REGS_SET_SYSCALL_RETURN(regs, PT_REGS_SET_SYSCALL_RETURN(regs,
EXECUTE_SYSCALL(syscall, regs)); EXECUTE_SYSCALL(syscall, regs));
......
...@@ -8,18 +8,8 @@ UBSAN_SANITIZE := n ...@@ -8,18 +8,8 @@ UBSAN_SANITIZE := n
KCOV_INSTRUMENT := n KCOV_INSTRUMENT := n
CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_64.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_32.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_x32.o = $(CC_FLAGS_FTRACE)
CFLAGS_common.o += -fno-stack-protector CFLAGS_common.o += -fno-stack-protector
CFLAGS_syscall_64.o += -fno-stack-protector
CFLAGS_syscall_32.o += -fno-stack-protector
CFLAGS_syscall_x32.o += -fno-stack-protector
CFLAGS_syscall_64.o += $(call cc-option,-Wno-override-init,)
CFLAGS_syscall_32.o += $(call cc-option,-Wno-override-init,)
CFLAGS_syscall_x32.o += $(call cc-option,-Wno-override-init,)
obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
obj-y += common.o obj-y += common.o
......
...@@ -36,61 +36,97 @@ ...@@ -36,61 +36,97 @@
#include <asm/irq_stack.h> #include <asm/irq_stack.h>
#ifdef CONFIG_X86_64 #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(); add_random_kstack_offset();
nr = syscall_enter_from_user_mode(regs, nr); nr = syscall_enter_from_user_mode(regs, nr);
instrumentation_begin(); instrumentation_begin();
if (likely(nr < NR_syscalls)) {
nr = array_index_nospec(nr, NR_syscalls); if (!do_syscall_x64(regs, nr) && !do_syscall_x32(regs, nr) && nr != -1) {
regs->ax = sys_call_table[nr](regs); /* Invalid system call, but still a system call. */
#ifdef CONFIG_X86_X32_ABI regs->ax = __x64_sys_ni_syscall(regs);
} 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
} }
instrumentation_end(); instrumentation_end();
syscall_exit_to_user_mode(regs); syscall_exit_to_user_mode(regs);
} }
#endif #endif
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) #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)) if (IS_ENABLED(CONFIG_IA32_EMULATION))
current_thread_info()->status |= TS_COMPAT; 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. * 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, static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
unsigned int nr)
{ {
if (likely(nr < IA32_NR_syscalls)) { /*
nr = array_index_nospec(nr, IA32_NR_syscalls); * Convert negative numbers to very high and thus out of range
regs->ax = ia32_sys_call_table[nr](regs); * 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);
} }
} }
/* Handles int $0x80 */ /* Handles int $0x80 */
__visible noinstr void do_int80_syscall_32(struct pt_regs *regs) __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(); add_random_kstack_offset();
/* /*
* Subtlety here: if ptrace pokes something larger than 2^32-1 into * Subtlety here: if ptrace pokes something larger than 2^31-1 into
* orig_ax, the unsigned int return value truncates it. This may * orig_ax, the int return value truncates it. This matches
* or may not be necessary, but it matches the old asm behavior. * 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(); instrumentation_begin();
do_syscall_32_irqs_on(regs, nr); do_syscall_32_irqs_on(regs, nr);
...@@ -101,7 +137,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) ...@@ -101,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) 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; int res;
add_random_kstack_offset(); add_random_kstack_offset();
...@@ -136,8 +172,7 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) ...@@ -136,8 +172,7 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
return false; return false;
} }
/* The case truncates any ptrace induced syscall nr > 2^32 -1 */ nr = syscall_enter_from_user_mode_work(regs, nr);
nr = (unsigned int)syscall_enter_from_user_mode_work(regs, nr);
/* Now this is just like a normal syscall. */ /* Now this is just like a normal syscall. */
do_syscall_32_irqs_on(regs, nr); do_syscall_32_irqs_on(regs, nr);
......
...@@ -108,7 +108,8 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL) ...@@ -108,7 +108,8 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL)
/* IRQs are off. */ /* IRQs are off. */
movq %rsp, %rdi movq %rsp, %rdi
movq %rax, %rsi /* Sign extend the lower 32bit as syscall numbers are treated as int */
movslq %eax, %rsi
call do_syscall_64 /* returns with IRQs disabled */ call do_syscall_64 /* returns with IRQs disabled */
/* /*
......
...@@ -5,21 +5,21 @@ ...@@ -5,21 +5,21 @@
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#define __SYSCALL_I386(nr, sym) extern long __ia32_##sym(const struct pt_regs *); #ifdef CONFIG_IA32_EMULATION
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
#else
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#endif
#define __SYSCALL(nr, sym) extern long __ia32_##sym(const struct pt_regs *);
#include <asm/syscalls_32.h> #include <asm/syscalls_32.h>
#undef __SYSCALL_I386 #undef __SYSCALL
#define __SYSCALL_I386(nr, sym) [nr] = __ia32_##sym, #define __SYSCALL(nr, sym) __ia32_##sym,
__visible const sys_call_ptr_t ia32_sys_call_table[__NR_ia32_syscall_max+1] = { __visible const sys_call_ptr_t ia32_sys_call_table[] = {
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.
*/
[0 ... __NR_ia32_syscall_max] = &__ia32_sys_ni_syscall,
#include <asm/syscalls_32.h> #include <asm/syscalls_32.h>
}; };
...@@ -5,23 +5,14 @@ ...@@ -5,23 +5,14 @@
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#define __SYSCALL_X32(nr, sym) #define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
#define __SYSCALL_COMMON(nr, sym) __SYSCALL_64(nr, sym)
#define __SYSCALL_64(nr, sym) extern long __x64_##sym(const struct pt_regs *);
#include <asm/syscalls_64.h> #include <asm/syscalls_64.h>
#undef __SYSCALL_64 #undef __SYSCALL
#define __SYSCALL_64(nr, sym) [nr] = __x64_##sym, #define __SYSCALL(nr, sym) __x64_##sym,
asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { asmlinkage const sys_call_ptr_t sys_call_table[] = {
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.
*/
[0 ... __NR_syscall_max] = &__x64_sys_ni_syscall,
#include <asm/syscalls_64.h> #include <asm/syscalls_64.h>
}; };
...@@ -5,37 +5,14 @@ ...@@ -5,37 +5,14 @@
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
/* #define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
* Reuse the 64-bit entry points for the x32 versions that occupy different #include <asm/syscalls_x32.h>
* slots in the syscall table. #undef __SYSCALL
*/
#define __x32_sys_readv __x64_sys_readv
#define __x32_sys_writev __x64_sys_writev
#define __x32_sys_getsockopt __x64_sys_getsockopt
#define __x32_sys_setsockopt __x64_sys_setsockopt
#define __x32_sys_vmsplice __x64_sys_vmsplice
#define __x32_sys_process_vm_readv __x64_sys_process_vm_readv
#define __x32_sys_process_vm_writev __x64_sys_process_vm_writev
#define __SYSCALL_64(nr, sym) #define __SYSCALL(nr, sym) __x64_##sym,
#define __SYSCALL_X32(nr, sym) extern long __x32_##sym(const struct pt_regs *); asmlinkage const sys_call_ptr_t x32_sys_call_table[] = {
#define __SYSCALL_COMMON(nr, sym) extern long __x64_##sym(const struct pt_regs *); #include <asm/syscalls_x32.h>
#include <asm/syscalls_64.h>
#undef __SYSCALL_X32
#undef __SYSCALL_COMMON
#define __SYSCALL_X32(nr, sym) [nr] = __x32_##sym,
#define __SYSCALL_COMMON(nr, sym) [nr] = __x64_##sym,
asmlinkage const sys_call_ptr_t x32_sys_call_table[__NR_x32_syscall_max+1] = {
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.
*/
[0 ... __NR_x32_syscall_max] = &__x64_sys_ni_syscall,
#include <asm/syscalls_64.h>
}; };
...@@ -9,47 +9,54 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') \ ...@@ -9,47 +9,54 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') \
syscall32 := $(src)/syscall_32.tbl syscall32 := $(src)/syscall_32.tbl
syscall64 := $(src)/syscall_64.tbl syscall64 := $(src)/syscall_64.tbl
syshdr := $(srctree)/$(src)/syscallhdr.sh syshdr := $(srctree)/scripts/syscallhdr.sh
systbl := $(srctree)/$(src)/syscalltbl.sh systbl := $(srctree)/scripts/syscalltbl.sh
offset :=
prefix :=
quiet_cmd_syshdr = SYSHDR $@ quiet_cmd_syshdr = SYSHDR $@
cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \ cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --abis $(abis) --emit-nr \
'$(syshdr_abi_$(basetarget))' \ $(if $(offset),--offset $(offset)) \
'$(syshdr_pfx_$(basetarget))' \ $(if $(prefix),--prefix $(prefix)) \
'$(syshdr_offset_$(basetarget))' $< $@
quiet_cmd_systbl = SYSTBL $@ quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) '$(systbl)' $< $@ cmd_systbl = $(CONFIG_SHELL) $(systbl) --abis $(abis) $< $@
quiet_cmd_hypercalls = HYPERCALLS $@ quiet_cmd_hypercalls = HYPERCALLS $@
cmd_hypercalls = $(CONFIG_SHELL) '$<' $@ $(filter-out $<, $(real-prereqs)) cmd_hypercalls = $(CONFIG_SHELL) '$<' $@ $(filter-out $<, $(real-prereqs))
syshdr_abi_unistd_32 := i386 $(uapi)/unistd_32.h: abis := i386
$(uapi)/unistd_32.h: $(syscall32) $(syshdr) FORCE $(uapi)/unistd_32.h: $(syscall32) $(syshdr) FORCE
$(call if_changed,syshdr) $(call if_changed,syshdr)
syshdr_abi_unistd_32_ia32 := i386 $(out)/unistd_32_ia32.h: abis := i386
syshdr_pfx_unistd_32_ia32 := ia32_ $(out)/unistd_32_ia32.h: prefix := ia32_
$(out)/unistd_32_ia32.h: $(syscall32) $(syshdr) FORCE $(out)/unistd_32_ia32.h: $(syscall32) $(syshdr) FORCE
$(call if_changed,syshdr) $(call if_changed,syshdr)
syshdr_abi_unistd_x32 := common,x32 $(uapi)/unistd_x32.h: abis := common,x32
syshdr_offset_unistd_x32 := __X32_SYSCALL_BIT $(uapi)/unistd_x32.h: offset := __X32_SYSCALL_BIT
$(uapi)/unistd_x32.h: $(syscall64) $(syshdr) FORCE $(uapi)/unistd_x32.h: $(syscall64) $(syshdr) FORCE
$(call if_changed,syshdr) $(call if_changed,syshdr)
syshdr_abi_unistd_64 := common,64 $(uapi)/unistd_64.h: abis := common,64
$(uapi)/unistd_64.h: $(syscall64) $(syshdr) FORCE $(uapi)/unistd_64.h: $(syscall64) $(syshdr) FORCE
$(call if_changed,syshdr) $(call if_changed,syshdr)
syshdr_abi_unistd_64_x32 := x32 $(out)/unistd_64_x32.h: abis := x32
syshdr_pfx_unistd_64_x32 := x32_ $(out)/unistd_64_x32.h: prefix := x32_
$(out)/unistd_64_x32.h: $(syscall64) $(syshdr) FORCE $(out)/unistd_64_x32.h: $(syscall64) $(syshdr) FORCE
$(call if_changed,syshdr) $(call if_changed,syshdr)
$(out)/syscalls_32.h: abis := i386
$(out)/syscalls_32.h: $(syscall32) $(systbl) FORCE $(out)/syscalls_32.h: $(syscall32) $(systbl) FORCE
$(call if_changed,systbl) $(call if_changed,systbl)
$(out)/syscalls_64.h: abis := common,64
$(out)/syscalls_64.h: $(syscall64) $(systbl) FORCE $(out)/syscalls_64.h: $(syscall64) $(systbl) FORCE
$(call if_changed,systbl) $(call if_changed,systbl)
$(out)/syscalls_x32.h: abis := common,x32
$(out)/syscalls_x32.h: $(syscall64) $(systbl) FORCE
$(call if_changed,systbl)
$(out)/xen-hypercalls.h: $(srctree)/scripts/xen-hypercalls.sh FORCE $(out)/xen-hypercalls.h: $(srctree)/scripts/xen-hypercalls.sh FORCE
$(call if_changed,hypercalls) $(call if_changed,hypercalls)
...@@ -60,6 +67,7 @@ uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h ...@@ -60,6 +67,7 @@ uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h
syshdr-y += syscalls_32.h syshdr-y += syscalls_32.h
syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
syshdr-$(CONFIG_X86_64) += syscalls_64.h syshdr-$(CONFIG_X86_64) += syscalls_64.h
syshdr-$(CONFIG_X86_X32) += syscalls_x32.h
syshdr-$(CONFIG_XEN) += xen-hypercalls.h syshdr-$(CONFIG_XEN) += xen-hypercalls.h
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y)) uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
......
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
prefix="$4"
offset="$5"
fileguard=_ASM_X86_`basename "$out" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
echo "#ifndef ${fileguard}"
echo "#define ${fileguard} 1"
echo ""
max=0
while read nr abi name entry ; do
if [ -z "$offset" ]; then
echo "#define __NR_${prefix}${name} $nr"
else
echo "#define __NR_${prefix}${name} ($offset + $nr)"
fi
max=$nr
done
echo ""
echo "#ifdef __KERNEL__"
echo "#define __NR_${prefix}syscall_max $max"
echo "#endif"
echo ""
echo "#endif /* ${fileguard} */"
) > "$out"
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
in="$1"
out="$2"
syscall_macro() {
local abi="$1"
local nr="$2"
local entry="$3"
echo "__SYSCALL_${abi}($nr, $entry)"
}
emit() {
local abi="$1"
local nr="$2"
local entry="$3"
local compat="$4"
if [ "$abi" != "I386" -a -n "$compat" ]; then
echo "a compat entry ($abi: $compat) for a 64-bit syscall makes no sense" >&2
exit 1
fi
if [ -z "$compat" ]; then
if [ -n "$entry" ]; then
syscall_macro "$abi" "$nr" "$entry"
fi
else
echo "#ifdef CONFIG_X86_32"
if [ -n "$entry" ]; then
syscall_macro "$abi" "$nr" "$entry"
fi
echo "#else"
syscall_macro "$abi" "$nr" "$compat"
echo "#endif"
fi
}
grep '^[0-9]' "$in" | sort -n | (
while read nr abi name entry compat; do
abi=`echo "$abi" | tr '[a-z]' '[A-Z]'`
emit "$abi" "$nr" "$entry" "$compat"
done
) > "$out"
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
generated-y += syscalls_32.h generated-y += syscalls_32.h
generated-y += syscalls_64.h generated-y += syscalls_64.h
generated-y += syscalls_x32.h
generated-y += unistd_32_ia32.h generated-y += unistd_32_ia32.h
generated-y += unistd_64_x32.h generated-y += unistd_64_x32.h
generated-y += xen-hypercalls.h generated-y += xen-hypercalls.h
......
...@@ -159,7 +159,7 @@ static inline int syscall_get_arch(struct task_struct *task) ...@@ -159,7 +159,7 @@ static inline int syscall_get_arch(struct task_struct *task)
? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; ? 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); void do_int80_syscall_32(struct pt_regs *regs);
long do_fast_syscall_32(struct pt_regs *regs); long do_fast_syscall_32(struct pt_regs *regs);
......
...@@ -17,7 +17,7 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); ...@@ -17,7 +17,7 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
* __x64_sys_*() - 64-bit native syscall * __x64_sys_*() - 64-bit native syscall
* __ia32_sys_*() - 32-bit native syscall or common compat syscall * __ia32_sys_*() - 32-bit native syscall or common compat syscall
* __ia32_compat_sys_*() - 32-bit compat syscall * __ia32_compat_sys_*() - 32-bit compat syscall
* __x32_compat_sys_*() - 64-bit X32 compat syscall * __x64_compat_sys_*() - 64-bit X32 compat syscall
* *
* The registers are decoded according to the ABI: * The registers are decoded according to the ABI:
* 64-bit: RDI, RSI, RDX, R10, R8, R9 * 64-bit: RDI, RSI, RDX, R10, R8, R9
...@@ -166,17 +166,17 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); ...@@ -166,17 +166,17 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
* with x86_64 obviously do not need such care. * with x86_64 obviously do not need such care.
*/ */
#define __X32_COMPAT_SYS_STUB0(name) \ #define __X32_COMPAT_SYS_STUB0(name) \
__SYS_STUB0(x32, compat_sys_##name) __SYS_STUB0(x64, compat_sys_##name)
#define __X32_COMPAT_SYS_STUBx(x, name, ...) \ #define __X32_COMPAT_SYS_STUBx(x, name, ...) \
__SYS_STUBx(x32, compat_sys##name, \ __SYS_STUBx(x64, compat_sys##name, \
SC_X86_64_REGS_TO_ARGS(x, __VA_ARGS__)) SC_X86_64_REGS_TO_ARGS(x, __VA_ARGS__))
#define __X32_COMPAT_COND_SYSCALL(name) \ #define __X32_COMPAT_COND_SYSCALL(name) \
__COND_SYSCALL(x32, compat_sys_##name) __COND_SYSCALL(x64, compat_sys_##name)
#define __X32_COMPAT_SYS_NI(name) \ #define __X32_COMPAT_SYS_NI(name) \
__SYS_NI(x32, compat_sys_##name) __SYS_NI(x64, compat_sys_##name)
#else /* CONFIG_X86_X32 */ #else /* CONFIG_X86_X32 */
#define __X32_COMPAT_SYS_STUB0(name) #define __X32_COMPAT_SYS_STUB0(name)
#define __X32_COMPAT_SYS_STUBx(x, name, ...) #define __X32_COMPAT_SYS_STUBx(x, name, ...)
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# define __ARCH_WANT_SYS_OLD_MMAP # define __ARCH_WANT_SYS_OLD_MMAP
# define __ARCH_WANT_SYS_OLD_SELECT # define __ARCH_WANT_SYS_OLD_SELECT
# define __NR_ia32_syscall_max __NR_syscall_max # define IA32_NR_syscalls (__NR_syscalls)
# else # else
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
# define __ARCH_WANT_COMPAT_SYS_PWRITEV64 # define __ARCH_WANT_COMPAT_SYS_PWRITEV64
# define __ARCH_WANT_COMPAT_SYS_PREADV64V2 # define __ARCH_WANT_COMPAT_SYS_PREADV64V2
# define __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 # define __ARCH_WANT_COMPAT_SYS_PWRITEV64V2
# define X32_NR_syscalls (__NR_x32_syscalls)
# define IA32_NR_syscalls (__NR_ia32_syscalls)
# endif # endif
# define NR_syscalls (__NR_syscall_max + 1) # define NR_syscalls (__NR_syscalls)
# define X32_NR_syscalls (__NR_x32_syscall_max + 1)
# define IA32_NR_syscalls (__NR_ia32_syscall_max + 1)
# define __ARCH_WANT_NEW_STAT # define __ARCH_WANT_NEW_STAT
# define __ARCH_WANT_OLD_READDIR # define __ARCH_WANT_OLD_READDIR
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <asm/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#define __NO_STUBS #define __NO_STUBS
...@@ -26,20 +25,17 @@ ...@@ -26,20 +25,17 @@
#define old_mmap sys_old_mmap #define old_mmap sys_old_mmap
#define __SYSCALL_I386(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_32.h> #include <asm/syscalls_32.h>
#undef __SYSCALL_I386 #undef __SYSCALL
#define __SYSCALL_I386(nr, sym) [ nr ] = sym, #define __SYSCALL(nr, sym) sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = { const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.
*/
[0 ... __NR_syscall_max] = &sys_ni_syscall,
#include <asm/syscalls_32.h> #include <asm/syscalls_32.h>
}; };
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <asm/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#define __NO_STUBS #define __NO_STUBS
...@@ -36,23 +35,15 @@ ...@@ -36,23 +35,15 @@
#define stub_execveat sys_execveat #define stub_execveat sys_execveat
#define stub_rt_sigreturn sys_rt_sigreturn #define stub_rt_sigreturn sys_rt_sigreturn
#define __SYSCALL_X32(nr, sym) #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#define __SYSCALL_COMMON(nr, sym) __SYSCALL_64(nr, sym)
#define __SYSCALL_64(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_64.h> #include <asm/syscalls_64.h>
#undef __SYSCALL_64 #undef __SYSCALL
#define __SYSCALL_64(nr, sym) [ nr ] = sym, #define __SYSCALL(nr, sym) sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = { const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.
*/
[0 ... __NR_syscall_max] = &sys_ni_syscall,
#include <asm/syscalls_64.h> #include <asm/syscalls_64.h>
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment