uml: redo the calculation of NR_syscalls

Redo the calculation of NR_syscalls since that disappeared from i386 and
use a similar mechanism on x86_64.

We now figure out the size of the system call table in arch code and stick
that in syscall_table_size. arch/um/kernel/skas/syscall.c defines
NR_syscalls in terms of that since its the only thing that needs to know
how many system calls there are.

The old mechananism that was used on x86_64 is gone.

arch/um/include/sysdep-i386/syscalls.h got some formatting since I was
looking at it.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Jeff Dike and committed by Linus Torvalds f87ea91d 966f1d8f

+25 -19
+3 -2
arch/um/include/sysdep-i386/syscalls.h
··· 1 1 /* 2 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 + * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 3 * Licensed under the GPL 4 4 */ 5 5 ··· 18 18 extern syscall_handler_t *sys_call_table[]; 19 19 20 20 #define EXECUTE_SYSCALL(syscall, regs) \ 21 - ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) 21 + ((long (*)(struct syscall_args)) \ 22 + (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) 22 23 23 24 extern long sys_mmap2(unsigned long addr, unsigned long len, 24 25 unsigned long prot, unsigned long flags,
-9
arch/um/include/sysdep-x86_64/kernel-offsets.h
··· 17 17 #define OFFSET(sym, str, mem) \ 18 18 DEFINE(sym, offsetof(struct str, mem)); 19 19 20 - #define __NO_STUBS 1 21 - #undef __SYSCALL 22 - #undef _ASM_X86_64_UNISTD_H_ 23 - #define __SYSCALL(nr, sym) [nr] = 1, 24 - static char syscalls[] = { 25 - #include <asm/arch/unistd.h> 26 - }; 27 - 28 20 void foo(void) 29 21 { 30 22 #include <common-offsets.h> 31 - DEFINE(UM_NR_syscall_max, sizeof(syscalls) - 1); 32 23 }
-2
arch/um/include/sysdep-x86_64/syscalls.h
··· 30 30 extern syscall_handler_t sys_modify_ldt; 31 31 extern syscall_handler_t sys_arch_prctl; 32 32 33 - #define NR_syscalls (UM_NR_syscall_max + 1) 34 - 35 33 #endif
+3
arch/um/kernel/skas/syscall.c
··· 9 9 #include "sysdep/ptrace.h" 10 10 #include "sysdep/syscalls.h" 11 11 12 + extern int syscall_table_size; 13 + #define NR_syscalls (syscall_table_size / sizeof(void *)) 14 + 12 15 void handle_syscall(struct uml_pt_regs *r) 13 16 { 14 17 struct pt_regs *regs = container_of(r, struct pt_regs, regs);
+5
arch/um/sys-i386/sys_call_table.S
··· 9 9 10 10 #define old_mmap old_mmap_i386 11 11 12 + .section .rodata,"a" 13 + 12 14 #include "../../x86/kernel/syscall_table_32.S" 15 + 16 + ENTRY(syscall_table_size) 17 + .long .-sys_call_table
+14 -6
arch/um/sys-x86_64/syscall_table.c
··· 52 52 53 53 extern void sys_ni_syscall(void); 54 54 55 - sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { 56 - /* 57 - * Smells like a like a compiler bug -- it doesn't work when the & 58 - * below is removed. 59 - */ 60 - [0 ... UM_NR_syscall_max] = &sys_ni_syscall, 55 + /* 56 + * We used to have a trick here which made sure that holes in the 57 + * x86_64 table were filled in with sys_ni_syscall, but a comment in 58 + * unistd_64.h says that holes aren't allowed, so the trick was 59 + * removed. 60 + * The trick looked like this 61 + * [0 ... UM_NR_syscall_max] = &sys_ni_syscall 62 + * before including unistd_64.h - the later initializations overwrote 63 + * the sys_ni_syscall filler. 64 + */ 65 + 66 + sys_call_ptr_t sys_call_table[] __cacheline_aligned = { 61 67 #include <asm-x86/unistd_64.h> 62 68 }; 69 + 70 + int syscall_table_size = sizeof(sys_call_table);