aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2011-12-05 19:08:49 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2011-12-05 19:08:49 -0500
commit45db1c6176c8171d9ae6fa6d82e07d115a5950ca (patch)
tree65ce8fcca9ffe02e0ecb83d6aa118ef44d7c86ce
parent392f4b7db82ee592cc62b813e2a127d370dea42a (diff)
x86, um: Use the same style generated syscall tables as native
Now when the native kernel uses a single style of generated system call table, follow suite for UML and implement the same style, all in C. This requires __NR_syscall_max and NR_syscalls to be generated; on native this is done in asm-headers.h but that file is common to all UML architectures; therefore put it in user-headers.h instead which already have accommodations for architecture-specific values. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/um/Makefile3
-rw-r--r--arch/x86/um/sys_call_table_32.S26
-rw-r--r--arch/x86/um/sys_call_table_32.c55
-rw-r--r--arch/x86/um/sys_call_table_64.c31
-rw-r--r--arch/x86/um/user-offsets.c15
5 files changed, 84 insertions, 46 deletions
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index 8fb58400e41..5d065b2222d 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -37,7 +37,8 @@ subarch-$(CONFIG_MODULES) += ../kernel/module.o
37USER_OBJS := bugs_$(BITS).o ptrace_user.o fault.o 37USER_OBJS := bugs_$(BITS).o ptrace_user.o fault.o
38 38
39extra-y += user-offsets.s 39extra-y += user-offsets.s
40$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) 40$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
41 -Iarch/x86/include/generated
41 42
42UNPROFILE_OBJS := stub_segv.o 43UNPROFILE_OBJS := stub_segv.o
43CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) 44CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
diff --git a/arch/x86/um/sys_call_table_32.S b/arch/x86/um/sys_call_table_32.S
deleted file mode 100644
index a7ca80d2dce..00000000000
--- a/arch/x86/um/sys_call_table_32.S
+++ /dev/null
@@ -1,26 +0,0 @@
1#include <linux/linkage.h>
2/* Steal i386 syscall table for our purposes, but with some slight changes.*/
3
4#define sys_iopl sys_ni_syscall
5#define sys_ioperm sys_ni_syscall
6
7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall
9
10#define old_mmap sys_old_mmap
11
12#define ptregs_fork sys_fork
13#define ptregs_execve sys_execve
14#define ptregs_iopl sys_iopl
15#define ptregs_vm86old sys_vm86old
16#define ptregs_clone sys_clone
17#define ptregs_vm86 sys_vm86
18#define ptregs_sigaltstack sys_sigaltstack
19#define ptregs_vfork sys_vfork
20
21.section .rodata,"a"
22
23#include "../kernel/syscall_table_32.S"
24
25ENTRY(syscall_table_size)
26.long .-sys_call_table
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
new file mode 100644
index 00000000000..b897fcae620
--- /dev/null
+++ b/arch/x86/um/sys_call_table_32.c
@@ -0,0 +1,55 @@
1/*
2 * System call table for UML/i386, copied from arch/x86/kernel/syscall_*.c
3 * with some changes for UML.
4 */
5
6#include <linux/linkage.h>
7#include <linux/sys.h>
8#include <linux/cache.h>
9#include <generated/user_constants.h>
10
11#define __NO_STUBS
12
13/*
14 * Below you can see, in terms of #define's, the differences between the x86-64
15 * and the UML syscall table.
16 */
17
18/* Not going to be implemented by UML, since we have no hardware. */
19#define stub_iopl sys_ni_syscall
20#define sys_ioperm sys_ni_syscall
21
22#define sys_vm86old sys_ni_syscall
23#define sys_vm86 sys_ni_syscall
24
25#define old_mmap sys_old_mmap
26
27#define ptregs_fork sys_fork
28#define ptregs_execve sys_execve
29#define ptregs_iopl sys_iopl
30#define ptregs_vm86old sys_vm86old
31#define ptregs_clone sys_clone
32#define ptregs_vm86 sys_vm86
33#define ptregs_sigaltstack sys_sigaltstack
34#define ptregs_vfork sys_vfork
35
36#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ;
37#include <asm/syscalls_32.h>
38
39#undef __SYSCALL_I386
40#define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym,
41
42typedef void (*sys_call_ptr_t)(void);
43
44extern void sys_ni_syscall(void);
45
46sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
47 /*
48 * Smells like a compiler bug -- it doesn't work
49 * when the & below is removed.
50 */
51 [0 ... __NR_syscall_max] = &sys_ni_syscall,
52#include <asm/syscalls_32.h>
53};
54
55int syscall_table_size = sizeof(sys_call_table);
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index 99522f78b16..797a639bcca 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -1,11 +1,12 @@
1/* 1/*
2 * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c 2 * System call table for UML/x86-64, copied from arch/x86/kernel/syscall_*.c
3 * with some changes for UML. 3 * with some changes for UML.
4 */ 4 */
5 5
6#include <linux/linkage.h> 6#include <linux/linkage.h>
7#include <linux/sys.h> 7#include <linux/sys.h>
8#include <linux/cache.h> 8#include <linux/cache.h>
9#include <generated/user_constants.h>
9 10
10#define __NO_STUBS 11#define __NO_STUBS
11 12
@@ -34,31 +35,23 @@
34#define stub_sigaltstack sys_sigaltstack 35#define stub_sigaltstack sys_sigaltstack
35#define stub_rt_sigreturn sys_rt_sigreturn 36#define stub_rt_sigreturn sys_rt_sigreturn
36 37
37#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; 38#define __SYSCALL_64(nr, sym, compat) extern asmlinkage void sym(void) ;
38#undef _ASM_X86_UNISTD_64_H 39#include <asm/syscalls_64.h>
39#include "../../x86/include/asm/unistd_64.h"
40 40
41#undef __SYSCALL 41#undef __SYSCALL_64
42#define __SYSCALL(nr, sym) [ nr ] = sym, 42#define __SYSCALL_64(nr, sym, compat) [ nr ] = sym,
43#undef _ASM_X86_UNISTD_64_H
44 43
45typedef void (*sys_call_ptr_t)(void); 44typedef void (*sys_call_ptr_t)(void);
46 45
47extern void sys_ni_syscall(void); 46extern void sys_ni_syscall(void);
48 47
49/*
50 * We used to have a trick here which made sure that holes in the
51 * x86_64 table were filled in with sys_ni_syscall, but a comment in
52 * unistd_64.h says that holes aren't allowed, so the trick was
53 * removed.
54 * The trick looked like this
55 * [0 ... UM_NR_syscall_max] = &sys_ni_syscall
56 * before including unistd_64.h - the later initializations overwrote
57 * the sys_ni_syscall filler.
58 */
59
60sys_call_ptr_t sys_call_table[] __cacheline_aligned = { 48sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
61#include <asm/unistd_64.h> 49 /*
50 * Smells like a compiler bug -- it doesn't work
51 * when the & below is removed.
52 */
53 [0 ... __NR_syscall_max] = &sys_ni_syscall,
54#include <asm/syscalls_64.h>
62}; 55};
63 56
64int syscall_table_size = sizeof(sys_call_table); 57int syscall_table_size = sizeof(sys_call_table);
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index ca49be8ddd0..5edf4f4bbf5 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -8,6 +8,18 @@
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9#include <asm/types.h> 9#include <asm/types.h>
10 10
11#ifdef __i386__
12#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
13static char syscalls[] = {
14#include <asm/syscalls_32.h>
15};
16#else
17#define __SYSCALL_64(nr, sym, compat) [nr] = 1,
18static char syscalls[] = {
19#include <asm/syscalls_64.h>
20};
21#endif
22
11#define DEFINE(sym, val) \ 23#define DEFINE(sym, val) \
12 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 24 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
13 25
@@ -77,4 +89,7 @@ void foo(void)
77 DEFINE(UM_PROT_READ, PROT_READ); 89 DEFINE(UM_PROT_READ, PROT_READ);
78 DEFINE(UM_PROT_WRITE, PROT_WRITE); 90 DEFINE(UM_PROT_WRITE, PROT_WRITE);
79 DEFINE(UM_PROT_EXEC, PROT_EXEC); 91 DEFINE(UM_PROT_EXEC, PROT_EXEC);
92
93 DEFINE(__NR_syscall_max, sizeof(syscalls) - 1);
94 DEFINE(NR_syscalls, sizeof(syscalls));
80} 95}