From a738669464a1e0d8e7b20f631120192f9cf7cfbd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 19 Jul 2011 13:00:19 +0100 Subject: x86: Unify rwsem assembly implementation Rather than having two functionally identical implementations for 32- and 64-bit configurations, use the previously extended assembly abstractions to fold the rwsem two implementations into a shared one. Signed-off-by: Jan Beulich Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/4E258DF3020000780004E3ED@nat28.tlf.novell.com Signed-off-by: Ingo Molnar --- arch/um/sys-i386/Makefile | 2 +- arch/um/sys-x86_64/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index b1da91c..15587ed 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_BINFMT_ELF) += elfcore.o -subarch-obj-y = lib/semaphore_32.o lib/string_32.o +subarch-obj-y = lib/rwsem.o lib/string_32.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index c1ea9eb..61fc99a 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -9,7 +9,7 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ sysrq.o ksyms.o tls.o subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ - lib/rwsem_64.o + lib/rwsem.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o ldt-y = ../sys-i386/ldt.o -- cgit v1.1 From 497888cf69bf607ac1fe061a6437e0a670b0022f Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Thu, 14 Jul 2011 15:07:13 +0300 Subject: treewide: fix potentially dangerous trailing ';' in #defined values/expressions All these are instances of #define NAME value; or #define NAME(params_opt) value; These of course fail to build when used in contexts like if(foo $OP NAME) while(bar $OP NAME) and may silently generate the wrong code in contexts such as foo = NAME + 1; /* foo = value; + 1; */ bar = NAME - 1; /* bar = value; - 1; */ baz = NAME & quux; /* baz = value; & quux; */ Reported on comp.lang.c, Message-ID: Initial analysis of the dangers provided by Keith Thompson in that thread. There are many more instances of more complicated macros having unnecessary trailing semicolons, but this pile seems to be all of the cases of simple values suffering from the problem. (Thus things that are likely to be found in one of the contexts above, more complicated ones aren't.) Signed-off-by: Phil Carmody Signed-off-by: Jiri Kosina --- arch/um/sys-i386/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 1296473..89a4662 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -58,7 +58,7 @@ static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) unsigned long ret = 0xffff0000; int i; -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) for (i = 0; i < 8; i++) { if (twd & 0x1) { -- cgit v1.1 From a03fc8c375511b6ab43184ab191af3218a919646 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Fri, 22 Jul 2011 20:55:34 +0200 Subject: um: Make rwsem.S depend on CONFIG_RWSEM_XCHGADD_ALGORITHM rwsem.S can only be used with CONFIG_RWSEM_XCHGADD_ALGORITHM. This unbreaks the UML build on i386. Reported-by: Randy Dunlap Acked-by: Randy Dunlap Signed-off-by: Richard Weinberger Cc: Stephen Rothwell Cc: user-mode-linux-devel@lists.sourceforge.net Cc: JBeulich@novell.com Link: http://lkml.kernel.org/r/201107222055.35341.richard@nod.at Signed-off-by: Ingo Molnar --- arch/um/sys-i386/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 15587ed..87b659d 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -8,7 +8,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_BINFMT_ELF) += elfcore.o -subarch-obj-y = lib/rwsem.o lib/string_32.o +subarch-obj-y = lib/string_32.o +subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o -- cgit v1.1 From 7213de044e11856f5c2aee0e43eff8dc507d421c Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:44 -0700 Subject: um: clean up vm-flags.h There is no need to define VM_{STACK,DATA}_DEFAULT_FLAGS as variable. It's also useless to test for TIF_IA32 as 64bit UML has no IA32 emulation. Signed-off-by: Richard Weinberger Acked-by: Randy Dunlap Cc: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/Makefile | 2 +- arch/um/sys-x86_64/mem.c | 16 ---------------- arch/um/sys-x86_64/shared/sysdep/vm-flags.h | 26 ++++---------------------- 3 files changed, 5 insertions(+), 39 deletions(-) delete mode 100644 arch/um/sys-x86_64/mem.c (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 61fc99a..4f95637 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -4,7 +4,7 @@ # Licensed under the GPL # -obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ +obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o \ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ sysrq.o ksyms.o tls.o diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c deleted file mode 100644 index 3f8df8a..0000000 --- a/arch/um/sys-x86_64/mem.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/mman.h" - -unsigned long vm_stack_flags = __VM_STACK_FLAGS; -unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; -unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; -unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; -unsigned long vm_force_exec32 = PROT_EXEC; - diff --git a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h index 3213edf..3978e55 100644 --- a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h +++ b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h @@ -7,27 +7,9 @@ #ifndef __VM_FLAGS_X86_64_H #define __VM_FLAGS_X86_64_H -#define __VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define __VM_STACK_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | \ - VM_MAYEXEC) - -extern unsigned long vm_stack_flags, vm_stack_flags32; -extern unsigned long vm_data_default_flags, vm_data_default_flags32; -extern unsigned long vm_force_exec32; - -#ifdef TIF_IA32 -#define VM_DATA_DEFAULT_FLAGS \ - (test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \ - vm_data_default_flags) - -#define VM_STACK_DEFAULT_FLAGS \ - (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) -#endif - -#define VM_DATA_DEFAULT_FLAGS vm_data_default_flags - -#define VM_STACK_DEFAULT_FLAGS vm_stack_flags +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ + VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #endif -- cgit v1.1 From c0ce5b673457123406f19e616bb8cf20a0c12cb5 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Mon, 25 Jul 2011 17:12:45 -0700 Subject: um, exec: remove redundant set_fs(USER_DS) The address limit is already set in flush_old_exec() so this set_fs(USER_DS) is redundant. Signed-off-by: Mathias Krause Cc: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/exec.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 09bd7b5..939a4a6 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -38,7 +38,6 @@ void flush_thread(void) void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - set_fs(USER_DS); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; } -- cgit v1.1 From 22e9b917ab7ccd98046ad9428fb28967f0744605 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:46 -0700 Subject: um: clean up delay functions Both sys-i386 and sys-x86_64 support now ndelay(). The delay functions are based on arch/x86/lib/delay.c. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/asm/delay.h | 10 +++----- arch/um/sys-i386/delay.c | 59 ++++++++++++++++++++++++++++++++++----------- arch/um/sys-x86_64/delay.c | 54 ++++++++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 32 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h index c71e32b..8a5576d 100644 --- a/arch/um/include/asm/delay.h +++ b/arch/um/include/asm/delay.h @@ -1,20 +1,18 @@ #ifndef __UM_DELAY_H #define __UM_DELAY_H -#define MILLION 1000000 - /* Undefined on purpose */ extern void __bad_udelay(void); +extern void __bad_ndelay(void); extern void __udelay(unsigned long usecs); +extern void __ndelay(unsigned long usecs); extern void __delay(unsigned long loops); #define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ __bad_udelay() : __udelay(n)) -/* It appears that ndelay is not used at all for UML, and has never been - * implemented. */ -extern void __unimplemented_ndelay(void); -#define ndelay(n) __unimplemented_ndelay() +#define ndelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ + __bad_ndelay() : __ndelay(n)) #endif diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c index d623e07..f3fe1a6 100644 --- a/arch/um/sys-i386/delay.c +++ b/arch/um/sys-i386/delay.c @@ -1,29 +1,60 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * Mostly copied from arch/x86/lib/delay.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #include #include #include #include -void __delay(unsigned long time) +void __delay(unsigned long loops) { - /* Stolen from the i386 __loop_delay */ - int d0; - __asm__ __volatile__( - "\tjmp 1f\n" + asm volatile( + "test %0,%0\n" + "jz 3f\n" + "jmp 1f\n" + ".align 16\n" - "1:\tjmp 2f\n" + "1: jmp 2f\n" + ".align 16\n" - "2:\tdecl %0\n\tjns 2b" - :"=&a" (d0) - :"0" (time)); + "2: dec %0\n" + " jnz 2b\n" + "3: dec %0\n" + + : /* we don't need output */ + : "a" (loops) + ); } +EXPORT_SYMBOL(__delay); -void __udelay(unsigned long usecs) +inline void __const_udelay(unsigned long xloops) { - int i, n; + int d0; - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i + * Mostly copied from arch/x86/lib/delay.c * - * Licensed under the GPL + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include +#include #include -#include #include void __delay(unsigned long loops) { - unsigned long i; + asm volatile( + "test %0,%0\n" + "jz 3f\n" + "jmp 1f\n" - for(i = 0; i < loops; i++) - cpu_relax(); + ".align 16\n" + "1: jmp 2f\n" + + ".align 16\n" + "2: dec %0\n" + " jnz 2b\n" + "3: dec %0\n" + + : /* we don't need output */ + : "a" (loops) + ); } +EXPORT_SYMBOL(__delay); -void __udelay(unsigned long usecs) +inline void __const_udelay(unsigned long xloops) { - unsigned long i, n; + int d0; - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i Date: Mon, 25 Jul 2011 17:12:47 -0700 Subject: um: fix _FORTIFY_SOURCE=2 support for kernel modules When UML is compiled with _FORTIFY_SOURCE we have to export all _chk() functions which are used in modules. For now it's only the case for __sprintf_chk(). Tested-by: Florian Fainelli Reported-by: Florian Fainelli Signed-off-by: Richard Weinberger Acked-by: Vitaliy Ivanov Cc: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/user_syms.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/um') diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 05f5ea8..45ffe46 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -113,3 +113,8 @@ EXPORT_SYMBOL(__stack_smash_handler); extern long __guard __attribute__((weak)); EXPORT_SYMBOL(__guard); + +#ifdef _FORTIFY_SOURCE +extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format); +EXPORT_SYMBOL(__sprintf_chk); +#endif -- cgit v1.1 From dd71dc4c335a8957d269ce063b3e80933f3482fc Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:48 -0700 Subject: um: add netpoll support To make netconsole usable on UML, its ethernet driver needs netpoll support. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 47d0c37..22745b4 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -262,6 +262,15 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void uml_net_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + uml_net_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + static void uml_net_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -364,6 +373,9 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = uml_net_poll_controller, +#endif }; /* -- cgit v1.1 From 7fa38e7e9ead2dc7a346db10dd27a40dd83b2a26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 25 Jul 2011 17:12:48 -0700 Subject: um: reinstate kernel version in generated .config Commit 0954828fcbf3 ("kconfig: replace KERNELVERSION usage by the mainmenu's prompt") made the kernel version disappear from the generated .config file when configuring for UML. As UML's Kconfig doesn't have a mainmenu, kconfig falls back to the default string "Linux Kernel Configuration". Add a suitable mainmenu to the main UML Kconfig file to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig.x86 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/um') diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 index 8aae429..d31ecf3 100644 --- a/arch/um/Kconfig.x86 +++ b/arch/um/Kconfig.x86 @@ -1,3 +1,5 @@ +mainmenu "User Mode Linux/$SUBARCH $KERNELVERSION Kernel Configuration" + source "arch/um/Kconfig.common" menu "UML-specific options" -- cgit v1.1 From fbee8d933c775cdb9daac3063659cda38c1776c2 Mon Sep 17 00:00:00 2001 From: Vitaliy Ivanov Date: Mon, 25 Jul 2011 17:12:49 -0700 Subject: uml: drivers/net_user.c memory leak fix Perform memory cleanup on exit. On receiving invalid 'pid' we still should clean 'output' variable. Signed-off-by: Vitaliy Ivanov Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_user.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 9415dd9..5201188 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -228,7 +228,10 @@ static void change(char *dev, char *what, unsigned char *addr, "buffer\n"); pid = change_tramp(argv, output, output_len); - if (pid < 0) return; + if (pid < 0) { + kfree(output); + return; + } if (output != NULL) { printk("%s", output); -- cgit v1.1 From 7a99ae7c57d2de5cad9562bed32addf064521116 Mon Sep 17 00:00:00 2001 From: Vitaliy Ivanov Date: Mon, 25 Jul 2011 17:12:50 -0700 Subject: uml: cow_user.c warning corrections Fix this warning: arch/um/drivers/cow_user.c: In function `absolutize': arch/um/drivers/cow_user.c:189:7: warning: ignoring return value of `chdir', declared with attribute warn_unused_result [richard@nod.at: happens only with -D_FORTIFY_SOURCE=2] Signed-off-by: Vitaliy Ivanov Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/cow_user.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 93f227a..9cbb426 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c @@ -186,7 +186,11 @@ static int absolutize(char *to, int size, char *from) strcat(to, "/"); strcat(to, from); } - chdir(save_cwd); + if (chdir(save_cwd)) { + cow_printf("absolutize : Can't cd to '%s' - " + "errno = %d\n", save_cwd, errno); + return -1; + } return 0; } -- cgit v1.1 From 2fdf2130926f07881c75e3905ece472c37d7703f Mon Sep 17 00:00:00 2001 From: Vitaliy Ivanov Date: Mon, 25 Jul 2011 17:12:50 -0700 Subject: uml: helper.c warning corrections Fix this warning: arch/um/os-Linux/helper.c: In function `helper_child': arch/um/os-Linux/helper.c:38:7: warning: ignoring return value of `write', declared with attribute warn_unused_result [richard@nod.at: happens only with -D_FORTIFY_SOURCE=2] Signed-off-by: Vitaliy Ivanov Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index b6b1096..feff22d 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -28,14 +28,14 @@ static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; - int err; + int err, ret; if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); err = execvp_noalloc(data->buf, argv[0], argv); /* If the exec succeeds, we don't get here */ - write(data->fd, &err, sizeof(err)); + CATCH_EINTR(ret = write(data->fd, &err, sizeof(err))); return 0; } -- cgit v1.1 From 9a8beb93067764344523386e0e5388d3fd78add7 Mon Sep 17 00:00:00 2001 From: Vitaliy Ivanov Date: Mon, 25 Jul 2011 17:12:51 -0700 Subject: uml: drivers/slip_user.c memory leak fix Do not free memory when you failed to allocate it. Signed-off-by: Vitaliy Ivanov Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/slip_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index a1c2d2c..cbacfc4 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -102,7 +102,7 @@ static int slip_tramp(char **argv, int fd) "buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; - goto out_free; + goto out_close; } close(fds[1]); @@ -112,7 +112,6 @@ static int slip_tramp(char **argv, int fd) err = helper_wait(pid); close(fds[0]); -out_free: kfree(output); return err; -- cgit v1.1 From 2a6d0ac182688d4d23357ece744978706c044aad Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Mon, 25 Jul 2011 17:12:52 -0700 Subject: uml: free resources When creating the temp file there's a memory and file descriptor leak upon error. Signed-off-by: Davidlohr Bueso Signed-off-by: Richard Weinberger Reviewed-by: Vitaliy Ivanov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/mem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index e696144..62878cf 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -176,7 +176,7 @@ static int __init make_tempfile(const char *template, char **out_tempname, find_tempdir(); if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN)) - return -1; + goto out; if (template[0] != '/') strcpy(tempname, tempdir); @@ -191,13 +191,15 @@ static int __init make_tempfile(const char *template, char **out_tempname, } if (do_unlink && (unlink(tempname) < 0)) { perror("unlink"); - goto out; + goto close; } if (out_tempname) { *out_tempname = tempname; } else free(tempname); return fd; +close: + close(fd); out: free(tempname); return -1; -- cgit v1.1 From b743ac54e54ca18fb7164a97cc77cf1ccee0b0f7 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:52 -0700 Subject: um: disable scan_elf_aux() on x86_64 Reusing the host's vDSO makes only sense on x86_32. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/Makefile | 4 +++- arch/um/os-Linux/elf_aux.c | 7 +------ arch/um/os-Linux/main.c | 4 ++++ 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index d66f038..b33f4df 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -3,10 +3,12 @@ # Licensed under the GPL # -obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ +obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ +obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o + USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ tty.o tls.o uaccess.o umid.o util.o diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 608784d..9533237 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -14,16 +14,11 @@ #include "mem_user.h" #include -/* Use the one from the kernel - the host may miss it, if having old headers. */ -#if UM_ELF_CLASS == UM_ELFCLASS32 typedef Elf32_auxv_t elf_auxv_t; -#else -typedef Elf64_auxv_t elf_auxv_t; -#endif /* These are initialized very early in boot and never changed */ char * elf_aux_platform; -long elf_aux_hwcap; +extern long elf_aux_hwcap; unsigned long vsyscall_ehdr; unsigned long vsyscall_end; unsigned long __kernel_vsyscall; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index fb2a97a..8471b81 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -21,6 +21,8 @@ #define STACKSIZE (8 * 1024 * 1024) #define THREAD_NAME_LEN (256) +long elf_aux_hwcap; + static void set_stklim(void) { struct rlimit lim; @@ -143,7 +145,9 @@ int __init main(int argc, char **argv, char **envp) install_fatal_handler(SIGINT); install_fatal_handler(SIGTERM); +#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA scan_elf_aux(envp); +#endif do_uml_initcalls(); ret = linux_main(argc, argv); -- cgit v1.1 From 548f0a4e02f6fa33278e77a2a6477cdeb512317f Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:53 -0700 Subject: um: Set __HAVE_ARCH_GATE_AREA for i386 When UML is unable to reuse the host's vDSO FIXADDR_USER_START is zero. To handle this special case correclty we have to implement custom gate area helper methods. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/Makefile | 2 +- arch/um/sys-i386/asm/elf.h | 2 ++ arch/um/sys-i386/mem.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 arch/um/sys-i386/mem.c (limited to 'arch/um') diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 87b659d..3923cfb 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -4,7 +4,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o atomic64_cx8_32.o + sys_call_table.o tls.o atomic64_cx8_32.o mem.o obj-$(CONFIG_BINFMT_ELF) += elfcore.o diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h index d964a41..4230555 100644 --- a/arch/um/sys-i386/asm/elf.h +++ b/arch/um/sys-i386/asm/elf.h @@ -105,6 +105,8 @@ extern unsigned long __kernel_vsyscall; #define FIXADDR_USER_START VSYSCALL_BASE #define FIXADDR_USER_END VSYSCALL_END +#define __HAVE_ARCH_GATE_AREA 1 + /* * Architecture-neutral AT_ values in 0-17, leave some room * for more of them, start the x86-specific ones at 32. diff --git a/arch/um/sys-i386/mem.c b/arch/um/sys-i386/mem.c new file mode 100644 index 0000000..639900a --- /dev/null +++ b/arch/um/sys-i386/mem.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +static struct vm_area_struct gate_vma; + +static int __init gate_vma_init(void) +{ + if (!FIXADDR_USER_START) + return 0; + + gate_vma.vm_mm = NULL; + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; + gate_vma.vm_page_prot = __P101; + + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + gate_vma.vm_flags |= VM_ALWAYSDUMP; + + return 0; +} +__initcall(gate_vma_init); + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return FIXADDR_USER_START ? &gate_vma : NULL; +} + +int in_gate_area_no_mm(unsigned long addr) +{ + if (!FIXADDR_USER_START) + return 0; + + if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) + return 1; + + return 0; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + struct vm_area_struct *vma = get_gate_vma(mm); + + if (!vma) + return 0; + + return (addr >= vma->vm_start) && (addr < vma->vm_end); +} -- cgit v1.1 From fc9a00187ba1300a0baae8e613cc62598e1a7de7 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:54 -0700 Subject: um: set __HAVE_ARCH_GATE_AREA for x86_64 Implement arch_vma_name() and make get_gate_vma(), in_gate_area() and in_gate_area_no_mm() a nop. We need arch_vma_name() to support vDSO. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/Makefile | 2 +- arch/um/sys-x86_64/asm/elf.h | 10 ++++++++++ arch/um/sys-x86_64/mem.c | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 arch/um/sys-x86_64/mem.c (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 4f95637..bf2fe83 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -4,7 +4,7 @@ # Licensed under the GPL # -obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o \ +obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o mem.o \ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ sysrq.o ksyms.o tls.o diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h index d6d5af3..11a2bfb 100644 --- a/arch/um/sys-x86_64/asm/elf.h +++ b/arch/um/sys-x86_64/asm/elf.h @@ -119,4 +119,14 @@ extern long elf_aux_hwcap; #define SET_PERSONALITY(ex) do ; while(0) +#define __HAVE_ARCH_GATE_AREA 1 +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 +struct linux_binprm; +extern int arch_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp); + +extern unsigned long um_vdso_addr; +#define AT_SYSINFO_EHDR 33 +#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) + #endif diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c new file mode 100644 index 0000000..5465187 --- /dev/null +++ b/arch/um/sys-x86_64/mem.c @@ -0,0 +1,26 @@ +#include "linux/mm.h" +#include "asm/page.h" +#include "asm/mman.h" + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm && vma->vm_start == um_vdso_addr) + return "[vdso]"; + + return NULL; +} + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return NULL; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + return 0; +} + +int in_gate_area_no_mm(unsigned long addr) +{ + return 0; +} -- cgit v1.1 From f1c2bb8b9964ed31de988910f8b1cfb586d30091 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:54 -0700 Subject: um: implement a x86_64 vDSO Until now UML had no x86_64 vDSO. So glibc always used the vsyscall page for gettimeday() and friends. Calls to gettimeday() returned falsely the host time and confused some programs. This patch adds a vDSO which turns all __vdso_* calls into a system call so that UML can trap them. As glibc still uses the vsyscall page for static binaries this patch improves the situation only for dynamic binaries. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/Makefile | 2 + arch/um/sys-x86_64/vdso/Makefile | 90 +++++++++++++++++++++++++++++++ arch/um/sys-x86_64/vdso/checkundef.sh | 10 ++++ arch/um/sys-x86_64/vdso/um_vdso.c | 71 ++++++++++++++++++++++++ arch/um/sys-x86_64/vdso/vdso-layout.lds.S | 64 ++++++++++++++++++++++ arch/um/sys-x86_64/vdso/vdso-note.S | 12 +++++ arch/um/sys-x86_64/vdso/vdso.S | 10 ++++ arch/um/sys-x86_64/vdso/vdso.lds.S | 32 +++++++++++ arch/um/sys-x86_64/vdso/vma.c | 74 +++++++++++++++++++++++++ 9 files changed, 365 insertions(+) create mode 100644 arch/um/sys-x86_64/vdso/Makefile create mode 100644 arch/um/sys-x86_64/vdso/checkundef.sh create mode 100644 arch/um/sys-x86_64/vdso/um_vdso.c create mode 100644 arch/um/sys-x86_64/vdso/vdso-layout.lds.S create mode 100644 arch/um/sys-x86_64/vdso/vdso-note.S create mode 100644 arch/um/sys-x86_64/vdso/vdso.S create mode 100644 arch/um/sys-x86_64/vdso/vdso.lds.S create mode 100644 arch/um/sys-x86_64/vdso/vma.c (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index bf2fe83..bd4d1d3 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -8,6 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o mem.o \ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ sysrq.o ksyms.o tls.o +obj-y += vdso/ + subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ lib/rwsem.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/arch/um/sys-x86_64/vdso/Makefile b/arch/um/sys-x86_64/vdso/Makefile new file mode 100644 index 0000000..5dffe6d --- /dev/null +++ b/arch/um/sys-x86_64/vdso/Makefile @@ -0,0 +1,90 @@ +# +# Building vDSO images for x86. +# + +VDSO64-y := y + +vdso-install-$(VDSO64-y) += vdso.so + + +# files to link into the vdso +vobjs-y := vdso-note.o um_vdso.o + +# files to link into kernel +obj-$(VDSO64-y) += vdso.o vma.o + +vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) + +$(obj)/vdso.o: $(obj)/vdso.so + +targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) + +export CPPFLAGS_vdso.lds += -P -C + +VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ + -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 + +$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so + +$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE + $(call if_changed,vdso) + +$(obj)/%.so: OBJCOPYFLAGS := -S +$(obj)/%.so: $(obj)/%.so.dbg FORCE + $(call if_changed,objcopy) + +# +# Don't omit frame pointers for ease of userspace debugging, but do +# optimize sibling calls. +# +CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ + $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ + -fno-omit-frame-pointer -foptimize-sibling-calls + +$(vobjs): KBUILD_CFLAGS += $(CFL) + +# +# vDSO code runs in userspace and -pg doesn't help with profiling anyway. +# +CFLAGS_REMOVE_vdso-note.o = -pg +CFLAGS_REMOVE_um_vdso.o = -pg + +targets += vdso-syms.lds +obj-$(VDSO64-y) += vdso-syms.lds + +# +# Match symbols in the DSO that look like VDSO*; produce a file of constants. +# +sed-vdsosym := -e 's/^00*/0/' \ + -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' +quiet_cmd_vdsosym = VDSOSYM $@ +define cmd_vdsosym + $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +endef + +$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE + $(call if_changed,vdsosym) + +# +# The DSO images are built using a special linker script. +# +quiet_cmd_vdso = VDSO $@ + cmd_vdso = $(CC) -nostdlib -o $@ \ + $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ + -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ + sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' + +VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) +GCOV_PROFILE := n + +# +# Install the unstripped copy of vdso*.so listed in $(vdso-install-y). +# +quiet_cmd_vdso_install = INSTALL $@ + cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ +$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE + @mkdir -p $(MODLIB)/vdso + $(call cmd,vdso_install) + +PHONY += vdso_install $(vdso-install-y) +vdso_install: $(vdso-install-y) diff --git a/arch/um/sys-x86_64/vdso/checkundef.sh b/arch/um/sys-x86_64/vdso/checkundef.sh new file mode 100644 index 0000000..7ee90a9 --- /dev/null +++ b/arch/um/sys-x86_64/vdso/checkundef.sh @@ -0,0 +1,10 @@ +#!/bin/sh +nm="$1" +file="$2" +$nm "$file" | grep '^ *U' > /dev/null 2>&1 +if [ $? -eq 1 ]; then + exit 0 +else + echo "$file: undefined symbols found" >&2 + exit 1 +fi diff --git a/arch/um/sys-x86_64/vdso/um_vdso.c b/arch/um/sys-x86_64/vdso/um_vdso.c new file mode 100644 index 0000000..7c441b5 --- /dev/null +++ b/arch/um/sys-x86_64/vdso/um_vdso.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This vDSO turns all calls into a syscall so that UML can trap them. + */ + + +/* Disable profiling for userspace code */ +#define DISABLE_BRANCH_PROFILING + +#include +#include +#include + +int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) +{ + long ret; + + asm("syscall" : "=a" (ret) : + "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); + + return ret; +} +int clock_gettime(clockid_t, struct timespec *) + __attribute__((weak, alias("__vdso_clock_gettime"))); + +int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + long ret; + + asm("syscall" : "=a" (ret) : + "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); + + return ret; +} +int gettimeofday(struct timeval *, struct timezone *) + __attribute__((weak, alias("__vdso_gettimeofday"))); + +time_t __vdso_time(time_t *t) +{ + long secs; + + asm volatile("syscall" + : "=a" (secs) + : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); + + return secs; +} +int time(time_t *t) __attribute__((weak, alias("__vdso_time"))); + +long +__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) +{ + /* + * UML does not support SMP, we can cheat here. :) + */ + + if (cpu) + *cpu = 0; + if (node) + *node = 0; + + return 0; +} + +long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) + __attribute__((weak, alias("__vdso_getcpu"))); diff --git a/arch/um/sys-x86_64/vdso/vdso-layout.lds.S b/arch/um/sys-x86_64/vdso/vdso-layout.lds.S new file mode 100644 index 0000000..634a2cf --- /dev/null +++ b/arch/um/sys-x86_64/vdso/vdso-layout.lds.S @@ -0,0 +1,64 @@ +/* + * Linker script for vDSO. This is an ELF shared object prelinked to + * its virtual address, and with only one read-only segment. + * This script controls its layout. + */ + +SECTIONS +{ + . = VDSO_PRELINK + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .altinstructions : { *(.altinstructions) } + .altinstr_replacement : { *(.altinstr_replacement) } + + /* + * Align the actual code well away from the non-instruction data. + * This is the best thing for the I-cache. + */ + . = ALIGN(0x100); + + .text : { *(.text*) } :text =0x90909090 +} + +/* + * Very old versions of ld do not recognize this name token; use the constant. + */ +#define PT_GNU_EH_FRAME 0x6474e550 + +/* + * We must supply the ELF program headers explicitly to get just one + * PT_LOAD segment, and set the flags explicitly to make segments read-only. + */ +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; +} diff --git a/arch/um/sys-x86_64/vdso/vdso-note.S b/arch/um/sys-x86_64/vdso/vdso-note.S new file mode 100644 index 0000000..79a071e --- /dev/null +++ b/arch/um/sys-x86_64/vdso/vdso-note.S @@ -0,0 +1,12 @@ +/* + * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. + * Here we can supply some information useful to userland. + */ + +#include +#include +#include + +ELFNOTE_START(Linux, 0, "a") + .long LINUX_VERSION_CODE +ELFNOTE_END diff --git a/arch/um/sys-x86_64/vdso/vdso.S b/arch/um/sys-x86_64/vdso/vdso.S new file mode 100644 index 0000000..ec82c16 --- /dev/null +++ b/arch/um/sys-x86_64/vdso/vdso.S @@ -0,0 +1,10 @@ +#include + +__INITDATA + + .globl vdso_start, vdso_end +vdso_start: + .incbin "arch/um/sys-x86_64/vdso/vdso.so" +vdso_end: + +__FINIT diff --git a/arch/um/sys-x86_64/vdso/vdso.lds.S b/arch/um/sys-x86_64/vdso/vdso.lds.S new file mode 100644 index 0000000..b96b267 --- /dev/null +++ b/arch/um/sys-x86_64/vdso/vdso.lds.S @@ -0,0 +1,32 @@ +/* + * Linker script for 64-bit vDSO. + * We #include the file to define the layout details. + * Here we only choose the prelinked virtual address. + * + * This file defines the version script giving the user-exported symbols in + * the DSO. We can define local symbols here called VDSO* to make their + * values visible using the asm-x86/vdso.h macros from the kernel proper. + */ + +#define VDSO_PRELINK 0xffffffffff700000 +#include "vdso-layout.lds.S" + +/* + * This controls what userland symbols we export from the vDSO. + */ +VERSION { + LINUX_2.6 { + global: + clock_gettime; + __vdso_clock_gettime; + gettimeofday; + __vdso_gettimeofday; + getcpu; + __vdso_getcpu; + time; + __vdso_time; + local: *; + }; +} + +VDSO64_PRELINK = VDSO_PRELINK; diff --git a/arch/um/sys-x86_64/vdso/vma.c b/arch/um/sys-x86_64/vdso/vma.c new file mode 100644 index 0000000..9495c8d --- /dev/null +++ b/arch/um/sys-x86_64/vdso/vma.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +unsigned int __read_mostly vdso_enabled = 1; +unsigned long um_vdso_addr; + +extern unsigned long task_size; +extern char vdso_start[], vdso_end[]; + +static struct page **vdsop; + +static int __init init_vdso(void) +{ + struct page *um_vdso; + + BUG_ON(vdso_end - vdso_start > PAGE_SIZE); + + um_vdso_addr = task_size - PAGE_SIZE; + + vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *)); + if (!vdsop) + goto oom; + + um_vdso = alloc_page(GFP_KERNEL); + if (!um_vdso) { + kfree(vdsop); + + goto oom; + } + + copy_page(page_address(um_vdso), vdso_start); + *vdsop = um_vdso; + + return 0; + +oom: + printk(KERN_ERR "Cannot allocate vdso\n"); + vdso_enabled = 0; + + return -ENOMEM; +} +subsys_initcall(init_vdso); + +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + int err; + struct mm_struct *mm = current->mm; + + if (!vdso_enabled) + return 0; + + down_write(&mm->mmap_sem); + + err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + vdsop); + + up_write(&mm->mmap_sem); + + return err; +} -- cgit v1.1 From 39073db15bf9016003e8a4e607d517f4928b713c Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:55 -0700 Subject: um: adjust size of pid_buf Linux can have pids up to 4*1024*1024. To handle such huge numbers pid_buf needs to be larger. Reported-by: Geert Uytterhoeven Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/harddog_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index b56f8e0..84dce3f 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -32,7 +32,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) { struct dog_data data; int in_fds[2], out_fds[2], pid, n, err; - char pid_buf[sizeof("nnnnn\0")], c; + char pid_buf[sizeof("nnnnnnn\0")], c; char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, NULL }; -- cgit v1.1 From f1c93e4946ae1cc268729451de6335a7e7d2bea9 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jul 2011 17:12:55 -0700 Subject: um: remove dead code GCC 4.6's -Wunused-but-set-variable found some dead code. Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_kern.c | 3 +-- arch/um/drivers/line.c | 3 +-- arch/um/kernel/reboot.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 25e1965..d4191fe 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -543,11 +543,10 @@ int parse_chan_pair(char *str, struct line *line, int device, const struct chan_opts *opts, char **error_out) { struct list_head *chans = &line->chan_list; - struct chan *new, *chan; + struct chan *new; char *in, *out; if (!list_empty(chans)) { - chan = list_entry(chans->next, struct chan, list); free_chan(chans, 0); INIT_LIST_HEAD(chans); } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 35dd0b8..d51c404 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -176,10 +176,9 @@ void line_flush_buffer(struct tty_struct *tty) { struct line *line = tty->driver_data; unsigned long flags; - int err; spin_lock_irqsave(&line->lock, flags); - err = flush_buffer(line); + flush_buffer(line); spin_unlock_irqrestore(&line->lock, flags); } diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 869bec9..4d93dff 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -20,9 +20,8 @@ static void kill_off_processes(void) os_kill_ptraced_process(userspace_pid[0], 1); else { struct task_struct *p; - int pid, me; + int pid; - me = os_getpid(); for_each_process(p) { if (p->mm == NULL) continue; -- cgit v1.1 From 0e9a6cb5e66f4b23e2a8f6b3f00949b7b3125dda Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 26 Jul 2011 16:08:31 -0700 Subject: ptrace: unify show_regs() prototype [ poleg@redhat.com: no need to declare show_regs() in ptrace.h, sched.h does this ] Signed-off-by: Mike Frysinger Cc: Tejun Heo Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/asm/ptrace-generic.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index b7c5bab..ae084ad 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -47,8 +47,6 @@ extern int get_fpregs(struct user_i387_struct __user *buf, extern int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child); -extern void show_regs(struct pt_regs *regs); - extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); -- cgit v1.1 From afc4b13df143122f99a0eb10bfefb216c2806de0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 16 Aug 2011 06:29:01 +0000 Subject: net: remove use of ndo_set_multicast_list in drivers replace it by ndo_set_rx_mode Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- arch/um/drivers/net_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 22745b4..a492e59 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -368,7 +368,7 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_open = uml_net_open, .ndo_stop = uml_net_close, .ndo_start_xmit = uml_net_start_xmit, - .ndo_set_multicast_list = uml_net_set_multicast_list, + .ndo_set_rx_mode = uml_net_set_multicast_list, .ndo_tx_timeout = uml_net_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, -- cgit v1.1 From e5f0bdc7840bdb791247cb98dfc1dab6ea6c7da4 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Wed, 14 Sep 2011 16:21:08 -0700 Subject: um: disable CMPXCHG_DOUBLE as it breaks UML build Commit b789ef518b2 ("slub: Add cmpxchg_double_slab()") tests for cmpxchg_double support in the SLUB code and it breaks UML builds with SLUB. Since UML does not support checking for CPU features, disable CMPXCHG_DOUBLE just like CMPXCHG_LOCAL is disabled for UML. Signed-off-by: Thadeu Lima de Souza Cascardo Reviewed-by: Christoph Lameter Cc: Jeff Dike Cc: Richard Weinberger Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig.x86 | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/um') diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 index d31ecf3..21bebe6 100644 --- a/arch/um/Kconfig.x86 +++ b/arch/um/Kconfig.x86 @@ -10,6 +10,10 @@ config CMPXCHG_LOCAL bool default n +config CMPXCHG_DOUBLE + bool + default n + source "arch/x86/Kconfig.cpu" endmenu -- cgit v1.1 From b40997b872cdb70140f127af6069f00a86b6cf81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Wed, 14 Sep 2011 16:21:20 -0700 Subject: um: drivers/xterm.c: fix a file descriptor leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I could use out_close1, but that seems to be the code path to close the fd returned by os_create_unix_socket, and using it to close the fd returned by mkstemp might lead to some confusion, so I don't do it. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/xterm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/um') diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 8ac7146..2e1de57 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d, err = -errno; printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", errno); + close(fd); return err; } close(fd); -- cgit v1.1 From fbfe9c847edf57ac8232aeafb290f272289893a3 Mon Sep 17 00:00:00 2001 From: Ingo van Lil Date: Wed, 14 Sep 2011 16:21:23 -0700 Subject: um: Save FPU registers between task switches Some time ago Jeff prepared 42daba316557 ("uml: stop saving process FP state") for UML to stop saving the process FP state between task switches. The assumption was that since with SKAS0 every guest process runs inside a host process context the host OS will take care of keeping the proper FP state. Unfortunately this is not true for multi-threaded applications, where all guest threads share a single host process context yet all may use the FPU on their own. Although I haven't verified it I suspect things to be even worse in SKAS3 mode where all guest processes run inside a single host process. The patch reintroduces the saving and restoring of the FP context between task switches. [richard@nod.at: Ingo posted this patch in 2009, sadly it was never applied and got lost. Now in 2011 the problem was reported by Gunnar.] Signed-off-by: Ingo van Lil Signed-off-by: Richard Weinberger Reported-by: Tested-by: Cc: Stanislav Meduna Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/shared/registers.h | 2 +- arch/um/kernel/process.c | 2 +- arch/um/os-Linux/registers.c | 9 ++++++++- arch/um/os-Linux/skas/mem.c | 2 +- arch/um/os-Linux/skas/process.c | 19 ++++++++++++++++++- arch/um/sys-i386/shared/sysdep/ptrace.h | 1 + arch/um/sys-x86_64/shared/sysdep/ptrace.h | 1 + 7 files changed, 31 insertions(+), 5 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index b0b4589..f1e0aa5 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); extern int restore_registers(int pid, struct uml_pt_regs *regs); extern int init_registers(int pid); -extern void get_safe_registers(unsigned long *regs); +extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); extern int put_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fab4371..21c1ae7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, arch_copy_thread(¤t->thread.arch, &p->thread.arch); } else { - get_safe_registers(p->thread.regs.regs.gp); + get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index 830fe6a..b866b9e 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c @@ -8,6 +8,8 @@ #include #include #include "sysdep/ptrace.h" +#include "sysdep/ptrace_user.h" +#include "registers.h" int save_registers(int pid, struct uml_pt_regs *regs) { @@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) /* This is set once at boot time and not changed thereafter */ static unsigned long exec_regs[MAX_REG_NR]; +static unsigned long exec_fp_regs[FP_SIZE]; int init_registers(int pid) { @@ -42,10 +45,14 @@ int init_registers(int pid) return -errno; arch_init_registers(pid); + get_fp_registers(pid, exec_fp_regs); return 0; } -void get_safe_registers(unsigned long *regs) +void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { memcpy(regs, exec_regs, sizeof(exec_regs)); + + if (fp_regs) + memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); } diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index d261f17..e771398 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { - get_safe_registers(syscall_regs); + get_safe_registers(syscall_regs, NULL); syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6e0a22..dee0e8c 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs) if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) fatal_sigsegv(); + if (put_fp_registers(pid, regs->fp)) + fatal_sigsegv(); + /* Now we set local_using_sysemu to be used for one loop */ local_using_sysemu = get_using_sysemu(); @@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs) fatal_sigsegv(); } + if (get_fp_registers(pid, regs->fp)) { + printk(UM_KERN_ERR "userspace - get_fp_registers failed, " + "errno = %d\n", errno); + fatal_sigsegv(); + } + UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if (WIFSTOPPED(status)) { @@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs) } static unsigned long thread_regs[MAX_REG_NR]; +static unsigned long thread_fp_regs[FP_SIZE]; static int __init init_thread_regs(void) { - get_safe_registers(thread_regs); + get_safe_registers(thread_regs, thread_fp_regs); /* Set parent's instruction pointer to start of clone-stub */ thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - @@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid) return err; } + err = put_fp_registers(pid, thread_fp_regs); + if (err < 0) { + printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " + "failed, pid = %d, err = %d\n", pid, err); + return err; + } + /* set a well known return code for detection of child write failure */ child_data->err = 12345678; diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index d50e62e..c398a50 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -53,6 +53,7 @@ extern int sysemu_supported; struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FPX_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h index fdba545..8ee8f8e 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -85,6 +85,7 @@ struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; -- cgit v1.1 From f71f94845e0126884eca8ce57a92e30b189c8e71 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:25 -0700 Subject: um: fix oopsable race in line_close() tty->count is decremented only after ->close() had been called and several tasks can hit it in parallel. As the result, using tty->count to check if you are the last one is broken. We end up leaving line->tty not reset to NULL and the next IRQ on that sucker will blow up trying to dereference pointers from kfree'd struct tty. Fix is obvious: we need to use a counter of our own. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 25 ++++++++++++------------- arch/um/include/shared/line.h | 1 + 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d51c404..c5bff1d 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) * is done under a spinlock. Checking whether the device is in use is * line->tty->count > 1, also under the spinlock. * - * tty->count serves to decide whether the device should be enabled or - * disabled on the host. If it's equal to 1, then we are doing the + * line->count serves to decide whether the device should be enabled or + * disabled on the host. If it's equal to 0, then we are doing the * first open or last close. Otherwise, open and close just return. */ @@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty) goto out_unlock; err = 0; - if (tty->count > 1) + if (line->count++) goto out_unlock; - spin_unlock(&line->count_lock); - + BUG_ON(tty->driver_data); tty->driver_data = line; line->tty = tty; + spin_unlock(&line->count_lock); err = enable_chan(line); - if (err) + if (err) /* line_close() will be called by our caller */ return err; INIT_DELAYED_WORK(&line->task, line_timer_cb); @@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty) chan_window_size(&line->chan_list, &tty->winsize.ws_row, &tty->winsize.ws_col); - return err; + return 0; out_unlock: spin_unlock(&line->count_lock); @@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp) flush_buffer(line); spin_lock(&line->count_lock); - if (!line->valid) - goto out_unlock; + BUG_ON(!line->valid); - if (tty->count > 1) + if (--line->count) goto out_unlock; - spin_unlock(&line->count_lock); - line->tty = NULL; tty->driver_data = NULL; + spin_unlock(&line->count_lock); + if (line->sigio) { unregister_winch(tty); line->sigio = 0; @@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, spin_lock(&line->count_lock); - if (line->tty != NULL) { + if (line->count) { *error_out = "Device is already open"; goto out; } diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h index 72f4f25..63df3ca 100644 --- a/arch/um/include/shared/line.h +++ b/arch/um/include/shared/line.h @@ -33,6 +33,7 @@ struct line_driver { struct line { struct tty_struct *tty; spinlock_t count_lock; + unsigned long count; int valid; char *init_str; -- cgit v1.1 From 45cd5e2d4e632f55af1d6131f33b554c98f8b929 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:28 -0700 Subject: um: winch_interrupt() can happen inside of free_winch() ... so set winch->fd to -1 before doing free_irq(), to avoid having winch_interrupt() come from/during the latter and attempt to do reactivate_fd() on something that's already gone. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index c5bff1d..91bf1894 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -725,6 +725,8 @@ struct winch { static void free_winch(struct winch *winch, int free_irq_ok) { + int fd = winch->fd; + winch->fd = -1; if (free_irq_ok) free_irq(WINCH_IRQ, winch); @@ -732,8 +734,8 @@ static void free_winch(struct winch *winch, int free_irq_ok) if (winch->pid != -1) os_kill_process(winch->pid, 1); - if (winch->fd != -1) - os_close_file(winch->fd); + if (fd != -1) + os_close_file(fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); -- cgit v1.1 From 7cf3cf21aac7d75d27e8e7cd039bd33d19fb300d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:31 -0700 Subject: um: fix free_winch() mess while not doing free_irq() from irq handler is commendable, kfree() on the data passed to said handler before free_irq() is Not Good(tm). Freeing the stack it's being run on is also not nice... Solution: delay actually freeing stuff. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 91bf1894..364c8a1 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -721,43 +721,53 @@ struct winch { int pid; struct tty_struct *tty; unsigned long stack; + struct work_struct work; }; -static void free_winch(struct winch *winch, int free_irq_ok) +static void __free_winch(struct work_struct *work) { - int fd = winch->fd; - winch->fd = -1; - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); - - list_del(&winch->list); + struct winch *winch = container_of(work, struct winch, work); + free_irq(WINCH_IRQ, winch); if (winch->pid != -1) os_kill_process(winch->pid, 1); - if (fd != -1) - os_close_file(fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); } +static void free_winch(struct winch *winch) +{ + int fd = winch->fd; + winch->fd = -1; + if (fd != -1) + os_close_file(fd); + list_del(&winch->list); + __free_winch(&winch->work); +} + static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; struct tty_struct *tty; struct line *line; + int fd = winch->fd; int err; char c; - if (winch->fd != -1) { - err = generic_read(winch->fd, &c, NULL); + if (fd != -1) { + err = generic_read(fd, &c, NULL); if (err < 0) { if (err != -EAGAIN) { + winch->fd = -1; + list_del(&winch->list); + os_close_file(fd); printk(KERN_ERR "winch_interrupt : " "read failed, errno = %d\n", -err); printk(KERN_ERR "fd %d is losing SIGWINCH " "support\n", winch->tty_fd); - free_winch(winch, 0); + INIT_WORK(&winch->work, __free_winch); + schedule_work(&winch->work); return IRQ_HANDLED; } goto out; @@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); if (winch->tty == tty) { - free_winch(winch, 1); + free_winch(winch); break; } } @@ -845,7 +855,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - free_winch(winch, 1); + free_winch(winch); } spin_unlock(&winch_handler_lock); -- cgit v1.1 From 01599cdc2f891415387aed9921909b3e9f27c801 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:34 -0700 Subject: um: PTRACE_[GS]ETFPXREGS had been wired on the wrong subarch It's 32bit-only, not 64bit-only... And while we are at it, it's set_fpxregs(), not set_fpregs()... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ptrace.c | 14 +++++++++++++- arch/um/sys-x86_64/ptrace.c | 14 +------------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index d23b2d3..49fd25a 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -206,5 +206,17 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { - return -EIO; + int ret = -EIO; + void __user *datap = (void __user *) data; + + switch (request) { + case PTRACE_GETFPXREGS: /* Get the child FPU state. */ + ret = get_fpxregs(datap, child); + break; + case PTRACE_SETFPXREGS: /* Set the child FPU state. */ + ret = set_fpxregs(datap, child); + break; + } + + return ret; } diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index f436136..7ed49ac 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -178,17 +178,5 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { - int ret = -EIO; - void __user *datap = (void __user *) data; - - switch (request) { - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - } - - return ret; + return -EIO; } -- cgit v1.1 From f2833aef6a0517e933992c8007f330d0df5d9317 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:37 -0700 Subject: um: clean arch_ptrace() up a bit 1) take subarch-specific stuff to subarch_ptrace() 2) PTRACE_{PEEK,POKE}{TEXT,DATA} is handled by ptrace_request() just fine... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/asm/ptrace-generic.h | 4 ---- arch/um/kernel/ptrace.c | 28 ---------------------------- arch/um/sys-i386/asm/ptrace.h | 5 ----- arch/um/sys-i386/ptrace.c | 18 ++++++++++++------ arch/um/sys-x86_64/ptrace.c | 22 +++++++++++++++++++--- 5 files changed, 31 insertions(+), 46 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index ae084ad..1a7d275 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -42,10 +42,6 @@ extern long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); -extern int set_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 701b672..c9da32b 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -50,23 +50,11 @@ long arch_ptrace(struct task_struct *child, long request, void __user *vp = p; switch (request) { - /* read word at location addr. */ - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: ret = peek_user(child, addr, data); break; - /* write the word at location addr. */ - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: ret = poke_user(child, addr, data); @@ -107,16 +95,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_GETFPREGS - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(vp, child); - break; -#endif -#ifdef PTRACE_SETFPREGS - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(vp, child); - break; -#endif case PTRACE_GET_THREAD_AREA: ret = ptrace_get_thread_area(child, addr, vp); break; @@ -154,12 +132,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_ARCH_PRCTL - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; -#endif default: ret = ptrace_request(child, request, addr, data); if (ret == -EIO) diff --git a/arch/um/sys-i386/asm/ptrace.h b/arch/um/sys-i386/asm/ptrace.h index 0273e4d..5d2a591 100644 --- a/arch/um/sys-i386/asm/ptrace.h +++ b/arch/um/sys-i386/asm/ptrace.h @@ -42,11 +42,6 @@ */ struct user_desc; -extern int get_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *child); -extern int set_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *tsk); - extern int ptrace_get_thread_area(struct task_struct *child, int idx, struct user_desc __user *user_desc); diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 49fd25a..3375c27 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -145,7 +145,7 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long __user *) data); } -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -161,7 +161,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) return n; } -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -174,7 +174,7 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) (unsigned long *) &fpregs); } -int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -190,7 +190,7 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) return n; } -int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -208,15 +208,21 @@ long subarch_ptrace(struct task_struct *child, long request, { int ret = -EIO; void __user *datap = (void __user *) data; - switch (request) { + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(datap, child); + break; + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(datap, child); + break; case PTRACE_GETFPXREGS: /* Get the child FPU state. */ ret = get_fpxregs(datap, child); break; case PTRACE_SETFPXREGS: /* Set the child FPU state. */ ret = set_fpxregs(datap, child); break; + default: + ret = -EIO; } - return ret; } diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 7ed49ac..4005506 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -145,7 +145,7 @@ int is_syscall(unsigned long addr) return instr == 0x050f; } -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -162,7 +162,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) return n; } -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -178,5 +178,21 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { - return -EIO; + int ret = -EIO; + void __user *datap = (void __user *) data; + + switch (request) { + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(datap, child); + break; + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(datap, child); + break; + case PTRACE_ARCH_PRCTL: + /* XXX Calls ptrace on the host - needs some SMP thinking */ + ret = arch_prctl(child, data, (void __user *) addr); + break; + } + + return ret; } -- cgit v1.1 From 2c51a4bc0233487db81706a0189715a59b18e9d6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:38 -0700 Subject: um: fix strrchr() problems richard@nod.at: Fixes: /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/libc.a(strrchr.o): In function `rindex': (.text+0x0): multiple definition of `strrchr' If both STATIC_LINK and UML_NET_VDE are set to "y" libc's strrchr may clash with the kernel implementation. This workaround comes originally from Jeff Dike: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=494995#35 Signed-off-by: Al Viro Signed-off-by: Richard Weinberger Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index fab8121..c0f712c 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -41,7 +41,7 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ -Din6addr_loopback=kernel_in6addr_loopback \ - -Din6addr_any=kernel_in6addr_any + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr KBUILD_AFLAGS += $(ARCH_INCLUDE) -- cgit v1.1 From dcb69290af30f7ef54e03bf82e1be0950f167789 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 16 Aug 2011 15:51:03 -0700 Subject: time: Cleanup old CONFIG_GENERIC_TIME references that snuck in Awhile back I removed all the CONFIG_GENERIC_TIME referecnes as the last of the non-GENERIC_TIME arches were converted. However, due to the functionality being important and around for awhile, there apparently were some out of tree hardware enablement patches that used it and have since been merged. This patch removes the remaining instances of GENERIC_TIME. Singed-off-by: John Stultz --- arch/um/defconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/defconfig b/arch/um/defconfig index 9f7634f..761f5e1 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -13,7 +13,6 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_STACKTRACE_SUPPORT is not set CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_IRQ_RELEASE_METHOD=y CONFIG_HZ=100 -- cgit v1.1 From d118c135489bd835d3c450c7dec3126f9fc4605e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:09 +0100 Subject: um: use subarch-obj instead of copying... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-i386/Makefile | 4 +- arch/um/sys-i386/atomic64_cx8_32.S | 225 ------------------------------------- 2 files changed, 2 insertions(+), 227 deletions(-) delete mode 100644 arch/um/sys-i386/atomic64_cx8_32.S (limited to 'arch/um') diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 3923cfb..e5e56d7 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -4,11 +4,11 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o atomic64_cx8_32.o mem.o + sys_call_table.o tls.o mem.o obj-$(CONFIG_BINFMT_ELF) += elfcore.o -subarch-obj-y = lib/string_32.o +subarch-obj-y = lib/string_32.o lib/atomic64_32.o lib/atomic64_cx8_32.o subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/arch/um/sys-i386/atomic64_cx8_32.S b/arch/um/sys-i386/atomic64_cx8_32.S deleted file mode 100644 index 1e901d3..0000000 --- a/arch/um/sys-i386/atomic64_cx8_32.S +++ /dev/null @@ -1,225 +0,0 @@ -/* - * atomic64_t for 586+ - * - * Copied from arch/x86/lib/atomic64_cx8_32.S - * - * Copyright © 2010 Luca Barbieri - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include - -.macro SAVE reg - pushl_cfi %\reg - CFI_REL_OFFSET \reg, 0 -.endm - -.macro RESTORE reg - popl_cfi %\reg - CFI_RESTORE \reg -.endm - -.macro read64 reg - movl %ebx, %eax - movl %ecx, %edx -/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ - LOCK_PREFIX - cmpxchg8b (\reg) -.endm - -ENTRY(atomic64_read_cx8) - CFI_STARTPROC - - read64 %ecx - ret - CFI_ENDPROC -ENDPROC(atomic64_read_cx8) - -ENTRY(atomic64_set_cx8) - CFI_STARTPROC - -1: -/* we don't need LOCK_PREFIX since aligned 64-bit writes - * are atomic on 586 and newer */ - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_set_cx8) - -ENTRY(atomic64_xchg_cx8) - CFI_STARTPROC - - movl %ebx, %eax - movl %ecx, %edx -1: - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_xchg_cx8) - -.macro addsub_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx - SAVE esi - SAVE edi - - movl %eax, %esi - movl %edx, %edi - movl %ecx, %ebp - - read64 %ebp -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l %esi, %ebx - \insc\()l %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE edi - RESTORE esi - RESTORE ebx - RESTORE ebp - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -addsub_return add add adc -addsub_return sub sub sbb - -.macro incdec_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l $1, %ebx - \insc\()l $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -incdec_return inc add adc -incdec_return dec sub sbb - -ENTRY(atomic64_dec_if_positive_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - subl $1, %ebx - sbb $0, %ecx - js 2f - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -2: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_dec_if_positive_cx8) - -ENTRY(atomic64_add_unless_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx -/* these just push these two parameters on the stack */ - SAVE edi - SAVE esi - - movl %ecx, %ebp - movl %eax, %esi - movl %edx, %edi - - read64 %ebp -1: - cmpl %eax, 0(%esp) - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl %esi, %ebx - adcl %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - - movl $1, %eax -3: - addl $8, %esp - CFI_ADJUST_CFA_OFFSET -8 - RESTORE ebx - RESTORE ebp - ret -4: - cmpl %edx, 4(%esp) - jne 2b - xorl %eax, %eax - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_add_unless_cx8) - -ENTRY(atomic64_inc_not_zero_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - testl %eax, %eax - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl $1, %ebx - adcl $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - movl $1, %eax -3: - RESTORE ebx - ret -4: - testl %edx, %edx - jne 2b - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_inc_not_zero_cx8) -- cgit v1.1 From 78722a445bb253fa6bcbe9d6589f27db78056af6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:19 +0100 Subject: um: switch {rt_,}sigreturn() to set_current_blocked() same story as on x86 native... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-i386/signal.c | 12 ++---------- arch/um/sys-x86_64/signal.c | 6 +----- 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 89a4662..4403b48 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -458,11 +458,7 @@ long sys_sigreturn(struct pt_regs regs) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (copy_sc_from_user(¤t->thread.regs, sc)) goto segfault; @@ -489,11 +485,7 @@ long sys_rt_sigreturn(struct pt_regs regs) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) goto segfault; diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index b6b65c7..581b64d 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -270,11 +270,7 @@ long sys_rt_sigreturn(struct pt_regs *regs) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, &frame->fpstate)) -- cgit v1.1 From 3c916fec12ab614aca5cf6ec09ae3adc6b911193 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:29 +0100 Subject: um: don't rely on sc.fpstate not having been reassigned prior to rt_sigreturn() native rt_sigreturn() doesn't... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-x86_64/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 581b64d..ccfa554 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -44,10 +44,10 @@ void copy_sc(struct uml_pt_regs *regs, void *from) } static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from, - struct _fpstate __user *fpp) + struct sigcontext __user *from) { struct user_i387_struct fp; + void __user *buf; int err = 0; #define GETREG(regs, regno, sc, regname) \ @@ -78,7 +78,11 @@ static int copy_sc_from_user(struct pt_regs *regs, #undef GETREG - err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct)); + err = __get_user(buf, &from->fpstate); + if (err) + return 1; + + err = copy_from_user(&fp, buf, sizeof(struct user_i387_struct)); if (err) return 1; @@ -272,8 +276,7 @@ long sys_rt_sigreturn(struct pt_regs *regs) sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, - &frame->fpstate)) + if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) goto segfault; /* Avoid ERESTART handling */ -- cgit v1.1 From 3d72210bdc1ef67b72ffbd3e74873cae7287f2c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:39 +0100 Subject: um: make copy_sc() static ... and kill it in amd64 - not used. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/kern_util.h | 1 - arch/um/sys-i386/signal.c | 2 +- arch/um/sys-x86_64/signal.c | 30 ------------------------------ 3 files changed, 1 insertion(+), 32 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 3c34122..0f14838 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -21,7 +21,6 @@ extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); extern int do_signal(void); -extern void copy_sc(struct uml_pt_regs *regs, void *from); extern void interrupt_end(void); extern void relay_signal(int sig, struct uml_pt_regs *regs); diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 4403b48..b87195b 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -10,7 +10,7 @@ #include "frame_kern.h" #include "skas.h" -void copy_sc(struct uml_pt_regs *regs, void *from) +static void copy_sc(struct uml_pt_regs *regs, void *from) { struct sigcontext *sc = from; diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index ccfa554..61ad980 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -13,36 +13,6 @@ #include "frame_kern.h" #include "skas.h" -void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - -#define GETREG(regs, regno, sc, regname) \ - (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname - - GETREG(regs, R8, sc, r8); - GETREG(regs, R9, sc, r9); - GETREG(regs, R10, sc, r10); - GETREG(regs, R11, sc, r11); - GETREG(regs, R12, sc, r12); - GETREG(regs, R13, sc, r13); - GETREG(regs, R14, sc, r14); - GETREG(regs, R15, sc, r15); - GETREG(regs, RDI, sc, di); - GETREG(regs, RSI, sc, si); - GETREG(regs, RBP, sc, bp); - GETREG(regs, RBX, sc, bx); - GETREG(regs, RDX, sc, dx); - GETREG(regs, RAX, sc, ax); - GETREG(regs, RCX, sc, cx); - GETREG(regs, RSP, sc, sp); - GETREG(regs, RIP, sc, ip); - GETREG(regs, EFLAGS, sc, flags); - GETREG(regs, CS, sc, cs); - -#undef GETREG -} - static int copy_sc_from_user(struct pt_regs *regs, struct sigcontext __user *from) { -- cgit v1.1 From a955bd611d6426bf7b61cab01f8ddee9cc169736 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:49 +0100 Subject: um: series of __get_user() is costly in sigframe handling It's not x86, where __get_user() is a single dereference; here it's a single ptrace(2) call in host, which obviously costs a lot more. IOW, it's cheaper to do copy_{to,from}_user() once than bother with fields one by one... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-i386/signal.c | 48 +++++++++--------- arch/um/sys-x86_64/signal.c | 118 +++++++++++++++++++++----------------------- 2 files changed, 80 insertions(+), 86 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index b87195b..bcbfb0d 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c @@ -10,28 +10,6 @@ #include "frame_kern.h" #include "skas.h" -static void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - - REGS_GS(regs->gp) = sc->gs; - REGS_FS(regs->gp) = sc->fs; - REGS_ES(regs->gp) = sc->es; - REGS_DS(regs->gp) = sc->ds; - REGS_EDI(regs->gp) = sc->di; - REGS_ESI(regs->gp) = sc->si; - REGS_EBP(regs->gp) = sc->bp; - REGS_SP(regs->gp) = sc->sp; - REGS_EBX(regs->gp) = sc->bx; - REGS_EDX(regs->gp) = sc->dx; - REGS_ECX(regs->gp) = sc->cx; - REGS_EAX(regs->gp) = sc->ax; - REGS_IP(regs->gp) = sc->ip; - REGS_CS(regs->gp) = sc->cs; - REGS_EFLAGS(regs->gp) = sc->flags; - REGS_SS(regs->gp) = sc->ss; -} - /* * FPU tag word conversions. */ @@ -175,7 +153,27 @@ static int copy_sc_from_user(struct pt_regs *regs, return err; pid = userspace_pid[current_thread_info()->cpu]; - copy_sc(®s->regs, &sc); + +#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname + + GETREG(GS, gs); + GETREG(FS, fs); + GETREG(ES, es); + GETREG(DS, ds); + GETREG(EDI, di); + GETREG(ESI, si); + GETREG(EBP, bp); + GETREG(SP, sp); + GETREG(EBX, bx); + GETREG(EDX, dx); + GETREG(ECX, cx); + GETREG(EAX, ax); + GETREG(IP, ip); + GETREG(CS, cs); + GETREG(EFLAGS, flags); + GETREG(SS, ss); + +#undef GETREG if (have_fpx_regs) { struct user_fxsr_struct fpx; @@ -196,8 +194,7 @@ static int copy_sc_from_user(struct pt_regs *regs, -err); return 1; } - } - else { + } else { struct user_i387_struct fp; err = copy_from_user(&fp, sc.fpstate, @@ -224,6 +221,7 @@ static int copy_sc_to_user(struct sigcontext __user *to, struct sigcontext sc; struct faultinfo * fi = ¤t->thread.arch.faultinfo; int err, pid; + memset(&sc, 0, sizeof(struct sigcontext)); sc.gs = REGS_GS(regs->regs.gp); sc.fs = REGS_FS(regs->regs.gp); diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 61ad980..255b2ca 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -16,41 +16,39 @@ static int copy_sc_from_user(struct pt_regs *regs, struct sigcontext __user *from) { + struct sigcontext sc; struct user_i387_struct fp; void __user *buf; - int err = 0; + int err; -#define GETREG(regs, regno, sc, regname) \ - __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= GETREG(regs, R8, from, r8); - err |= GETREG(regs, R9, from, r9); - err |= GETREG(regs, R10, from, r10); - err |= GETREG(regs, R11, from, r11); - err |= GETREG(regs, R12, from, r12); - err |= GETREG(regs, R13, from, r13); - err |= GETREG(regs, R14, from, r14); - err |= GETREG(regs, R15, from, r15); - err |= GETREG(regs, RDI, from, di); - err |= GETREG(regs, RSI, from, si); - err |= GETREG(regs, RBP, from, bp); - err |= GETREG(regs, RBX, from, bx); - err |= GETREG(regs, RDX, from, dx); - err |= GETREG(regs, RAX, from, ax); - err |= GETREG(regs, RCX, from, cx); - err |= GETREG(regs, RSP, from, sp); - err |= GETREG(regs, RIP, from, ip); - err |= GETREG(regs, EFLAGS, from, flags); - err |= GETREG(regs, CS, from, cs); + err = copy_from_user(&sc, from, sizeof(sc)); if (err) - return 1; - + return err; + +#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname + + GETREG(R8, r8); + GETREG(R9, r9); + GETREG(R10, r10); + GETREG(R11, r11); + GETREG(R12, r12); + GETREG(R13, r13); + GETREG(R14, r14); + GETREG(R15, r15); + GETREG(RDI, di); + GETREG(RSI, si); + GETREG(RBP, bp); + GETREG(RBX, bx); + GETREG(RDX, dx); + GETREG(RAX, ax); + GETREG(RCX, cx); + GETREG(SP, sp); + GETREG(IP, ip); + GETREG(EFLAGS, flags); + GETREG(CS, cs); #undef GETREG - err = __get_user(buf, &from->fpstate); - if (err) - return 1; + buf = sc.fpstate; err = copy_from_user(&fp, buf, sizeof(struct user_i387_struct)); if (err) @@ -73,48 +71,46 @@ static int copy_sc_to_user(struct sigcontext __user *to, unsigned long mask, unsigned long sp) { struct faultinfo * fi = ¤t->thread.arch.faultinfo; + struct sigcontext sc; struct user_i387_struct fp; int err = 0; + memset(&sc, 0, sizeof(struct sigcontext)); - err |= __put_user(0, &to->gs); - err |= __put_user(0, &to->fs); - -#define PUTREG(regs, regno, sc, regname) \ - __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) +#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno] - err |= PUTREG(regs, RDI, to, di); - err |= PUTREG(regs, RSI, to, si); - err |= PUTREG(regs, RBP, to, bp); + PUTREG(RDI, di); + PUTREG(RSI, si); + PUTREG(RBP, bp); /* * Must use original RSP, which is passed in, rather than what's in - * the pt_regs, because that's already been updated to point at the * signal frame. */ - err |= __put_user(sp, &to->sp); - err |= PUTREG(regs, RBX, to, bx); - err |= PUTREG(regs, RDX, to, dx); - err |= PUTREG(regs, RCX, to, cx); - err |= PUTREG(regs, RAX, to, ax); - err |= PUTREG(regs, R8, to, r8); - err |= PUTREG(regs, R9, to, r9); - err |= PUTREG(regs, R10, to, r10); - err |= PUTREG(regs, R11, to, r11); - err |= PUTREG(regs, R12, to, r12); - err |= PUTREG(regs, R13, to, r13); - err |= PUTREG(regs, R14, to, r14); - err |= PUTREG(regs, R15, to, r15); - err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ - - err |= __put_user(fi->cr2, &to->cr2); - err |= __put_user(fi->error_code, &to->err); - err |= __put_user(fi->trap_no, &to->trapno); - - err |= PUTREG(regs, RIP, to, ip); - err |= PUTREG(regs, EFLAGS, to, flags); + sc.sp = sp; + PUTREG(RBX, bx); + PUTREG(RDX, dx); + PUTREG(RCX, cx); + PUTREG(RAX, ax); + PUTREG(R8, r8); + PUTREG(R9, r9); + PUTREG(R10, r10); + PUTREG(R11, r11); + PUTREG(R12, r12); + PUTREG(R13, r13); + PUTREG(R14, r14); + PUTREG(R15, r15); + PUTREG(CS, cs); /* XXX x86_64 doesn't do this */ + + sc.cr2 = fi->cr2; + sc.err = fi->error_code; + sc.trapno = fi->trap_no; + + PUTREG(IP, ip); + PUTREG(EFLAGS, flags); #undef PUTREG - err |= __put_user(mask, &to->oldmask); + sc.oldmask = mask; + + err = copy_to_user(to, &sc, sizeof(struct sigcontext)); if (err) return 1; -- cgit v1.1 From 4d45db9c45dc60af40acdb5591c66a8398f84cbe Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:00:59 +0100 Subject: um: switch to -idirafter, get saner kern_constants.h out of that Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index c0f712c..deb0553 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -47,7 +47,7 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ - $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 + $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) @@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(SHARED_HEADERS)/kern_constants.h: $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ + $(Q)echo '#include ' >$@ export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH -- cgit v1.1 From 9f270de8361d9cbbfd79e874de125a02b2d73697 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:09 +0100 Subject: um: kill skas_ptregs.h It's a plain include of user_constants.h and all (2) users are including user_constants.h directly prior to that. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/skas_ptregs.h | 6 ------ arch/um/sys-i386/shared/sysdep/ptrace.h | 2 -- arch/um/sys-x86_64/shared/sysdep/ptrace.h | 2 -- 3 files changed, 10 deletions(-) delete mode 100644 arch/um/include/shared/skas_ptregs.h (limited to 'arch/um') diff --git a/arch/um/include/shared/skas_ptregs.h b/arch/um/include/shared/skas_ptregs.h deleted file mode 100644 index 73db19e..0000000 --- a/arch/um/include/shared/skas_ptregs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SKAS_PT_REGS_ -#define __SKAS_PT_REGS_ - -#include - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index c398a50..c414231 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -24,8 +24,6 @@ void set_using_sysemu(int value); int get_using_sysemu(void); extern int sysemu_supported; -#include "skas_ptregs.h" - #define REGS_IP(r) ((r)[HOST_IP]) #define REGS_SP(r) ((r)[HOST_SP]) #define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h index 8ee8f8e..1a19960 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -14,8 +14,6 @@ #define MAX_REG_OFFSET (UM_FRAME_SIZE) #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) -#include "skas_ptregs.h" - #define REGS_IP(r) ((r)[HOST_IP]) #define REGS_SP(r) ((r)[HOST_SP]) -- cgit v1.1 From 4de1c5f65c7dd4965a2a58b93205b747d7826110 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:19 +0100 Subject: um: take user_constants.h to include/generated Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 5 ++--- arch/um/sys-i386/shared/sysdep/ptrace.h | 2 +- arch/um/sys-i386/shared/sysdep/ptrace_user.h | 2 +- arch/um/sys-i386/shared/sysdep/sc.h | 2 +- arch/um/sys-x86_64/shared/sysdep/ptrace.h | 2 +- arch/um/sys-x86_64/shared/sysdep/ptrace_user.h | 2 +- arch/um/sys-x86_64/shared/sysdep/sc.h | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index deb0553..3aded4e 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -86,7 +86,7 @@ endef KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH) -archprepare: $(SHARED_HEADERS)/user_constants.h +archprepare: include/generated/user_constants.h archprepare: $(SHARED_HEADERS)/kern_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static @@ -119,7 +119,6 @@ endef # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out \ - $(SHARED_HEADERS)/user_constants.h \ $(SHARED_HEADERS)/kern_constants.h archclean: @@ -144,7 +143,7 @@ define filechk_gen-asm-offsets echo ""; ) endef -$(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s +include/generated/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(call filechk,gen-asm-offsets) $(SHARED_HEADERS)/kern_constants.h: diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index c414231..3600699 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -6,7 +6,7 @@ #ifndef __SYSDEP_I386_PTRACE_H #define __SYSDEP_I386_PTRACE_H -#include "user_constants.h" +#include #include "sysdep/faultinfo.h" #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) diff --git a/arch/um/sys-i386/shared/sysdep/ptrace_user.h b/arch/um/sys-i386/shared/sysdep/ptrace_user.h index ef56247..e4398a3 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace_user.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace_user.h @@ -9,7 +9,7 @@ #include #include #include -#include "user_constants.h" +#include #define PT_OFFSET(r) ((r) * sizeof(long)) diff --git a/arch/um/sys-i386/shared/sysdep/sc.h b/arch/um/sys-i386/shared/sysdep/sc.h index c57d178..7b89240 100644 --- a/arch/um/sys-i386/shared/sysdep/sc.h +++ b/arch/um/sys-i386/shared/sysdep/sc.h @@ -1,7 +1,7 @@ #ifndef __SYSDEP_I386_SC_H #define __SYSDEP_I386_SC_H -#include +#include #define SC_OFFSET(sc, field) \ *((unsigned long *) &(((char *) (sc))[HOST_##field])) diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h index 1a19960..ea5d7c1 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -8,7 +8,7 @@ #ifndef __SYSDEP_X86_64_PTRACE_H #define __SYSDEP_X86_64_PTRACE_H -#include "user_constants.h" +#include #include "sysdep/faultinfo.h" #define MAX_REG_OFFSET (UM_FRAME_SIZE) diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h index 4dbccdb..faf9cdd 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h @@ -12,7 +12,7 @@ #include #include #undef __FRAME_OFFSETS -#include "user_constants.h" +#include #define PT_INDEX(off) ((off) / sizeof(unsigned long)) diff --git a/arch/um/sys-x86_64/shared/sysdep/sc.h b/arch/um/sys-x86_64/shared/sysdep/sc.h index 8aee45b..20313a2 100644 --- a/arch/um/sys-x86_64/shared/sysdep/sc.h +++ b/arch/um/sys-x86_64/shared/sysdep/sc.h @@ -5,7 +5,7 @@ * Released under the GPL */ -#include +#include #define SC_OFFSET(sc, field) \ *((unsigned long *) &(((char *) (sc))[HOST_##field])) -- cgit v1.1 From 078073a3d48ce7c140f1538d249da3ac545065a6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:29 +0100 Subject: um: -include user.h for USER_OBJ, trim includes Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/chan_user.c | 2 -- arch/um/drivers/cow_sys.h | 1 - arch/um/drivers/daemon_user.c | 1 - arch/um/drivers/fd.c | 2 -- arch/um/drivers/harddog_user.c | 1 - arch/um/drivers/mconsole_user.c | 2 -- arch/um/drivers/net_user.c | 2 -- arch/um/drivers/pcap_user.c | 2 -- arch/um/drivers/port_user.c | 2 -- arch/um/drivers/pty.c | 2 -- arch/um/drivers/slip_user.c | 2 -- arch/um/drivers/slirp_user.c | 2 -- arch/um/drivers/tty.c | 2 -- arch/um/drivers/ubd_user.c | 1 - arch/um/drivers/umcast_user.c | 2 -- arch/um/drivers/vde_user.c | 2 -- arch/um/drivers/xterm.c | 2 -- arch/um/kernel/skas/clone.c | 1 - arch/um/os-Linux/aio.c | 2 -- arch/um/os-Linux/drivers/ethertap_user.c | 2 -- arch/um/os-Linux/drivers/tuntap_user.c | 2 -- arch/um/os-Linux/elf_aux.c | 1 - arch/um/os-Linux/file.c | 2 -- arch/um/os-Linux/helper.c | 2 -- arch/um/os-Linux/irq.c | 2 -- arch/um/os-Linux/main.c | 1 - arch/um/os-Linux/mem.c | 2 -- arch/um/os-Linux/process.c | 2 -- arch/um/os-Linux/sigio.c | 2 -- arch/um/os-Linux/signal.c | 1 - arch/um/os-Linux/skas/mem.c | 2 -- arch/um/os-Linux/skas/process.c | 2 -- arch/um/os-Linux/start_up.c | 1 - arch/um/os-Linux/sys-i386/registers.c | 2 -- arch/um/os-Linux/sys-i386/task_size.c | 1 - arch/um/os-Linux/sys-i386/tls.c | 1 - arch/um/os-Linux/sys-x86_64/registers.c | 2 -- arch/um/os-Linux/time.c | 2 -- arch/um/os-Linux/tty.c | 2 -- arch/um/os-Linux/umid.c | 2 -- arch/um/os-Linux/util.c | 2 -- arch/um/scripts/Makefile.rules | 2 +- arch/um/sys-i386/Makefile | 2 +- arch/um/sys-i386/bugs.c | 2 -- arch/um/sys-i386/shared/sysdep/stub.h | 1 - arch/um/sys-x86_64/Makefile | 2 +- arch/um/sys-x86_64/shared/sysdep/stub.h | 1 - 47 files changed, 3 insertions(+), 78 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index cfeb3f4..7ed06a7 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -11,10 +11,8 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" void generic_close(int fd, void *unused) { diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index f5701fd..7f2ed0b 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -3,7 +3,6 @@ #include "kern_util.h" #include "os.h" -#include "user.h" #include "um_malloc.h" static inline void *cow_malloc(int size) diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index f8e85e0..a4fd7bc 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -17,7 +17,6 @@ #include "net_user.h" #include "os.h" #include "um_malloc.h" -#include "user.h" enum request_type { REQ_NEW_CONTROL }; diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index f5a981a..5b81d25 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -9,10 +9,8 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct fd_chan { int fd; diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 84dce3f..0345d62 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -7,7 +7,6 @@ #include #include #include "os.h" -#include "user.h" struct dog_data { int stdin; diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f8cf4c8..9920982 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -10,9 +10,7 @@ #include #include #include -#include "kern_constants.h" #include "mconsole.h" -#include "user.h" static struct mconsole_command commands[] = { /* diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 5201188..05090c3 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -12,10 +12,8 @@ #include #include #include "net_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" int tap_open_common(void *dev, char *gate_addr) { diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 5f90358..702a75b 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -9,9 +9,7 @@ #include #include "net_user.h" #include "pcap_user.h" -#include "kern_constants.h" #include "um_malloc.h" -#include "user.h" #define PCAP_FD(p) (*(int *)(p)) diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index b49bf56..7b010b7 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -10,11 +10,9 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "port.h" #include "um_malloc.h" -#include "user.h" struct port_chan { int raw; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 1113911..cff2b75 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -12,10 +12,8 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct pty_chan { void (*announce)(char *dev_name, int dev); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index cbacfc4..932b4d6 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -11,12 +11,10 @@ #include #include #include -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slip.h" #include "um_malloc.h" -#include "user.h" static int slip_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index a0ada8f..db4adb6 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -7,11 +7,9 @@ #include #include #include -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slirp.h" -#include "user.h" static int slirp_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 495858a..a97391f 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -7,10 +7,8 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct tty_chan { char *dev; diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index b591bb9..007b94d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -16,7 +16,6 @@ #include #include #include "asm/types.h" -#include "user.h" #include "ubd_user.h" #include "os.h" #include "cow.h" diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c index 59c56fd..010fa2d 100644 --- a/arch/um/drivers/umcast_user.c +++ b/arch/um/drivers/umcast_user.c @@ -15,11 +15,9 @@ #include #include #include -#include "kern_constants.h" #include "umcast.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" static struct sockaddr_in *new_addr(char *addr, unsigned short port) { diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c index c5c4325..b8c2867 100644 --- a/arch/um/drivers/vde_user.c +++ b/arch/um/drivers/vde_user.c @@ -6,10 +6,8 @@ #include #include #include -#include "kern_constants.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #include "vde.h" static int vde_user_init(void *data, void *dev) diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 2e1de57..969110e 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -11,10 +11,8 @@ #include #include #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" #include "xterm.h" struct xterm_chan { diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 2c8583c..e1fd066 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -8,7 +8,6 @@ #include #include #include "as-layout.h" -#include "kern_constants.h" #include "ptrace_user.h" #include "stub-data.h" #include "sysdep/stub.h" diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 57e3d46..c5d039e 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -11,10 +11,8 @@ #include #include "aio.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct aio_thread_req { enum aio_type type; diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index cc72cb2..db3d648 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -13,11 +13,9 @@ #include #include #include "etap.h" -#include "kern_constants.h" #include "os.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #define MAX_PACKET ETH_MAX_PACKET diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 2448be0..a2aacff 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -13,11 +13,9 @@ #include #include #include -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "tuntap.h" -#include "user.h" static int tuntap_user_init(void *data, void *dev) { diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9533237..d895271 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -12,7 +12,6 @@ #include "init.h" #include "elf_user.h" #include "mem_user.h" -#include typedef Elf32_auxv_t elf_auxv_t; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 140e587..b049a63 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -13,9 +13,7 @@ #include #include #include -#include "kern_constants.h" #include "os.h" -#include "user.h" static void copy_stat(struct uml_stat *dst, const struct stat64 *src) { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index feff22d..cf26c4a 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -10,11 +10,9 @@ #include #include #include -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct helper_data { void (*pre_exec)(void*); diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 0348b97..59c592c 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -9,11 +9,9 @@ #include #include #include "irq_user.h" -#include "kern_constants.h" #include "os.h" #include "process.h" #include "um_malloc.h" -#include "user.h" /* * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 8471b81..7a86dd5 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -12,7 +12,6 @@ #include #include "as-layout.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 62878cf..8e421e1 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -14,9 +14,7 @@ #include #include #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" /* Modified by which_tmpdir, which is called during early boot */ static char *default_tmpdir = "/tmp"; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 0c45dc8..0ced30c 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -13,12 +13,10 @@ #include #include #include "init.h" -#include "kern_constants.h" #include "longjmp.h" #include "os.h" #include "process.h" #include "skas_ptrace.h" -#include "user.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 63d299d..34bb59b 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -11,14 +11,12 @@ #include #include #include -#include "kern_constants.h" #include "kern_util.h" #include "init.h" #include "os.h" #include "process.h" #include "sigio.h" #include "um_malloc.h" -#include "user.h" /* * Protected by sigio_lock(), also used by sigio_cleanup, which is an diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6ae1807..4fc3cd1 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -15,7 +15,6 @@ #include "process.h" #include "sysdep/barrier.h" #include "sysdep/sigcontext.h" -#include "user.h" /* Copied from linux/compiler-gcc.h since we can't include it directly */ #define barrier() __asm__ __volatile__("": : :"memory") diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index e771398..c0afff7 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -9,7 +9,6 @@ #include #include #include "init.h" -#include "kern_constants.h" #include "as-layout.h" #include "mm_id.h" #include "os.h" @@ -17,7 +16,6 @@ #include "ptrace_user.h" #include "registers.h" #include "skas.h" -#include "user.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index dee0e8c..2a72bfc 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -14,7 +14,6 @@ #include #include "as-layout.h" #include "chan_user.h" -#include "kern_constants.h" #include "kern_util.h" #include "mem.h" #include "os.h" @@ -24,7 +23,6 @@ #include "registers.h" #include "skas.h" #include "skas_ptrace.h" -#include "user.h" #include "sysdep/stub.h" int is_skas_winch(int pid, int fd, void *data) diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 02ee9ad..b698680 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -18,7 +18,6 @@ #include #include #include "init.h" -#include "kern_constants.h" #include "os.h" #include "mem_user.h" #include "ptrace_user.h" diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 229f7a5..913d811 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -7,9 +7,7 @@ #include #include #include -#include "kern_constants.h" #include "longjmp.h" -#include "user.h" #include "sysdep/ptrace_user.h" int save_fp_registers(int pid, unsigned long *fp_regs) diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/um/os-Linux/sys-i386/task_size.c index be04c1e..4ce09b8 100644 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ b/arch/um/os-Linux/sys-i386/task_size.c @@ -3,7 +3,6 @@ #include #include #include "longjmp.h" -#include "kern_constants.h" static jmp_buf buf; diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 32ed41e..281e83e 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -5,7 +5,6 @@ #include #include "sysdep/tls.h" -#include "user.h" /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 594d97a..0594d55 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -7,9 +7,7 @@ #include #define __FRAME_OFFSETS #include -#include "kern_constants.h" #include "longjmp.h" -#include "user.h" int save_fp_registers(int pid, unsigned long *fp_regs) { diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6e3359d..995ca30 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -8,11 +8,9 @@ #include #include #include -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "process.h" -#include "user.h" int set_interval(void) { diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c index b09ff66..dd12b99 100644 --- a/arch/um/os-Linux/tty.c +++ b/arch/um/os-Linux/tty.c @@ -7,10 +7,8 @@ #include #include #include -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct grantpt_info { int fd; diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index a27defb..4832eb5 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -13,9 +13,7 @@ #include #include #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" #define UML_DIR "~/.uml/" diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 5803b18..9e3b43b 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -13,9 +13,7 @@ #include #include #include -#include "kern_constants.h" #include "os.h" -#include "user.h" void stack_protections(unsigned long address) { diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 61107b6..3a7efb0 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) + c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index e5e56d7..231bb98 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -15,8 +15,8 @@ subarch-obj-$(CONFIG_MODULES) += kernel/module.o USER_OBJS := bugs.o ptrace_user.o fault.o -USER_OBJS += user-offsets.s extra-y += user-offsets.s +$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) UNPROFILE_OBJS := stub_segv.o CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 2c6d0d7..7058e1f 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c @@ -4,11 +4,9 @@ */ #include -#include "kern_constants.h" #include "kern_util.h" #include "longjmp.h" #include "task.h" -#include "user.h" #include "sysdep/ptrace.h" /* Set during early boot */ diff --git a/arch/um/sys-i386/shared/sysdep/stub.h b/arch/um/sys-i386/shared/sysdep/stub.h index 977dedd..cca14d4 100644 --- a/arch/um/sys-i386/shared/sysdep/stub.h +++ b/arch/um/sys-i386/shared/sysdep/stub.h @@ -11,7 +11,6 @@ #include #include "as-layout.h" #include "stub-data.h" -#include "kern_constants.h" extern void stub_segv_handler(int sig); extern void stub_clone_handler(void); diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index bd4d1d3..0971846 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -18,8 +18,8 @@ ldt-y = ../sys-i386/ldt.o USER_OBJS := ptrace_user.o -USER_OBJS += user-offsets.s extra-y += user-offsets.s +$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) UNPROFILE_OBJS := stub_segv.o CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) diff --git a/arch/um/sys-x86_64/shared/sysdep/stub.h b/arch/um/sys-x86_64/shared/sysdep/stub.h index 3432aa2..922a570 100644 --- a/arch/um/sys-x86_64/shared/sysdep/stub.h +++ b/arch/um/sys-x86_64/shared/sysdep/stub.h @@ -11,7 +11,6 @@ #include #include "as-layout.h" #include "stub-data.h" -#include "kern_constants.h" extern void stub_segv_handler(int sig); extern void stub_clone_handler(void); -- cgit v1.1 From 945581d5bd796a046a42e3ee915bd9ec0c6853ca Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:39 +0100 Subject: um: kill a couple of useless includes of kern_constants.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-x86_64/shared/sysdep/syscalls.h | 1 - arch/um/sys-x86_64/syscall_table.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-x86_64/shared/sysdep/syscalls.h b/arch/um/sys-x86_64/shared/sysdep/syscalls.h index 7cfb0b08..8a7d5e1 100644 --- a/arch/um/sys-x86_64/shared/sysdep/syscalls.h +++ b/arch/um/sys-x86_64/shared/sysdep/syscalls.h @@ -9,7 +9,6 @@ #include #include -#include typedef long syscall_handler_t(void); diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 47d469e..f46de82 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -6,7 +6,6 @@ #include #include #include -#include #define __NO_STUBS -- cgit v1.1 From 9e636452d0714b08e4f8f4c58b76c4b7d15ffffa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:49 +0100 Subject: um: get rid of kern_constants.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 11 +---------- arch/um/include/shared/as-layout.h | 2 +- arch/um/include/shared/task.h | 2 +- arch/um/include/shared/um_malloc.h | 2 +- arch/um/include/shared/user.h | 2 +- 5 files changed, 5 insertions(+), 14 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index 3aded4e..649aebc 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -25,9 +25,6 @@ include $(srctree)/$(ARCH_DIR)/Makefile-skas SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared -ifneq ($(KBUILD_SRC),) -ARCH_INCLUDE += -I$(SHARED_HEADERS) -endif KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so @@ -87,7 +84,6 @@ endef KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH) archprepare: include/generated/user_constants.h -archprepare: $(SHARED_HEADERS)/kern_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib @@ -118,8 +114,7 @@ endef # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. -CLEAN_FILES += linux x.i gmon.out \ - $(SHARED_HEADERS)/kern_constants.h +CLEAN_FILES += linux x.i gmon.out archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ @@ -146,8 +141,4 @@ endef include/generated/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(call filechk,gen-asm-offsets) -$(SHARED_HEADERS)/kern_constants.h: - $(Q)mkdir -p $(dir $@) - $(Q)echo '#include ' >$@ - export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index a92b678..896e166 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -6,7 +6,7 @@ #ifndef __START_H__ #define __START_H__ -#include "kern_constants.h" +#include /* * Stolen from linux/const.h, which can't be directly included since diff --git a/arch/um/include/shared/task.h b/arch/um/include/shared/task.h index 3fe726b..3db6b58 100644 --- a/arch/um/include/shared/task.h +++ b/arch/um/include/shared/task.h @@ -1,7 +1,7 @@ #ifndef __TASK_H #define __TASK_H -#include +#include #define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) #define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) diff --git a/arch/um/include/shared/um_malloc.h b/arch/um/include/shared/um_malloc.h index c554d70..6395fef 100644 --- a/arch/um/include/shared/um_malloc.h +++ b/arch/um/include/shared/um_malloc.h @@ -6,7 +6,7 @@ #ifndef __UM_MALLOC_H__ #define __UM_MALLOC_H__ -#include "kern_constants.h" +#include extern void *uml_kmalloc(int size, int flags); extern void kfree(const void *ptr); diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 293f7c7..2d46f63 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -6,7 +6,7 @@ #ifndef __USER_H__ #define __USER_H__ -#include "kern_constants.h" +#include /* * The usual definition - copied here because the kernel provides its own, -- cgit v1.1 From 16b7c5737d2c46c8772ca11ac219273362a9a29e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:01:59 +0100 Subject: um: trim unused junk from user.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/user.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 2d46f63..58c0581 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -36,9 +36,7 @@ static inline int printk(const char *fmt, ...) } #endif -extern void schedule(void); extern int in_aton(char *str); -extern int open_gdb_chan(void); extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); -- cgit v1.1 From c16d56a37ac6889ae9b199c02e76a03ec8a8c419 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:09 +0100 Subject: um: get rid of sysdep/checksum.h Move those to sys-.../asm/checksum.h, kill include/asm/checksum.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/checksum.h | 6 - arch/um/sys-i386/asm/checksum.h | 201 ++++++++++++++++++++++++++++ arch/um/sys-i386/shared/sysdep/checksum.h | 201 ---------------------------- arch/um/sys-x86_64/asm/checksum.h | 144 ++++++++++++++++++++ arch/um/sys-x86_64/shared/sysdep/checksum.h | 144 -------------------- 5 files changed, 345 insertions(+), 351 deletions(-) delete mode 100644 arch/um/include/asm/checksum.h create mode 100644 arch/um/sys-i386/asm/checksum.h delete mode 100644 arch/um/sys-i386/shared/sysdep/checksum.h create mode 100644 arch/um/sys-x86_64/asm/checksum.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/checksum.h (limited to 'arch/um') diff --git a/arch/um/include/asm/checksum.h b/arch/um/include/asm/checksum.h deleted file mode 100644 index 5b50136..0000000 --- a/arch/um/include/asm/checksum.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CHECKSUM_H -#define __UM_CHECKSUM_H - -#include "sysdep/checksum.h" - -#endif diff --git a/arch/um/sys-i386/asm/checksum.h b/arch/um/sys-i386/asm/checksum.h new file mode 100644 index 0000000..caab742 --- /dev/null +++ b/arch/um/sys-i386/asm/checksum.h @@ -0,0 +1,201 @@ +/* + * Licensed under the GPL + */ + +#ifndef __UM_SYSDEP_CHECKSUM_H +#define __UM_SYSDEP_CHECKSUM_H + +#include "linux/in6.h" +#include "linux/string.h" + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ + +static __inline__ +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) +{ + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +static __inline__ +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) +{ + if (copy_from_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + + return csum_partial(dst, len, sum); +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik , adapted for linux by + * Arnt Gulbrandsen. + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum; + + __asm__ __volatile__( + "movl (%1), %0 ;\n" + "subl $4, %2 ;\n" + "jbe 2f ;\n" + "addl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" +"1: adcl 16(%1), %0 ;\n" + "lea 4(%1), %1 ;\n" + "decl %2 ;\n" + "jne 1b ;\n" + "adcl $0, %0 ;\n" + "movl %0, %2 ;\n" + "shrl $16, %0 ;\n" + "addw %w2, %w0 ;\n" + "adcl $0, %0 ;\n" + "notl %0 ;\n" +"2: ;\n" + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)sum; +} + +/* + * Fold a partial checksum + */ + +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl $0xffff, %0 ;\n" + : "=r" (sum) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) + ); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl %2, %0 ;\n" + "adcl %3, %0 ;\n" + "adcl $0, %0 ;\n" + : "=r" (sum) + : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, + __wsum sum) +{ + __asm__( + "addl 0(%1), %0 ;\n" + "adcl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" + "adcl 0(%2), %0 ;\n" + "adcl 4(%2), %0 ;\n" + "adcl 8(%2), %0 ;\n" + "adcl 12(%2), %0 ;\n" + "adcl %3, %0 ;\n" + "adcl %4, %0 ;\n" + "adcl $0, %0 ;\n" + : "=&r" (sum) + : "r" (saddr), "r" (daddr), + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); + + return csum_fold(sum); +} + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +static __inline__ __wsum csum_and_copy_to_user(const void *src, + void __user *dst, + int len, __wsum sum, int *err_ptr) +{ + if (access_ok(VERIFY_WRITE, dst, len)) { + if (copy_to_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + + return csum_partial(src, len, sum); + } + + if (len) + *err_ptr = -EFAULT; + + return (__force __wsum)-1; /* invalid checksum */ +} + +#endif + diff --git a/arch/um/sys-i386/shared/sysdep/checksum.h b/arch/um/sys-i386/shared/sysdep/checksum.h deleted file mode 100644 index ed47445..0000000 --- a/arch/um/sys-i386/shared/sysdep/checksum.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/in6.h" -#include "linux/string.h" - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - -/* - * the same as csum_partial, but copies from src while it - * checksums, and handles user-space pointer exceptions correctly, when needed. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(dst, len, sum); -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - * By Jorge Cwik , adapted for linux by - * Arnt Gulbrandsen. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - __asm__ __volatile__( - "movl (%1), %0 ;\n" - "subl $4, %2 ;\n" - "jbe 2f ;\n" - "addl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" -"1: adcl 16(%1), %0 ;\n" - "lea 4(%1), %1 ;\n" - "decl %2 ;\n" - "jne 1b ;\n" - "adcl $0, %0 ;\n" - "movl %0, %2 ;\n" - "shrl $16, %0 ;\n" - "addw %w2, %w0 ;\n" - "adcl $0, %0 ;\n" - "notl %0 ;\n" -"2: ;\n" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl $0xffff, %0 ;\n" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl %2, %0 ;\n" - "adcl %3, %0 ;\n" - "adcl $0, %0 ;\n" - : "=r" (sum) - : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - __asm__( - "addl 0(%1), %0 ;\n" - "adcl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" - "adcl 0(%2), %0 ;\n" - "adcl 4(%2), %0 ;\n" - "adcl 8(%2), %0 ;\n" - "adcl 12(%2), %0 ;\n" - "adcl %3, %0 ;\n" - "adcl %4, %0 ;\n" - "adcl $0, %0 ;\n" - : "=&r" (sum) - : "r" (saddr), "r" (daddr), - "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); - - return csum_fold(sum); -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, int *err_ptr) -{ - if (access_ok(VERIFY_WRITE, dst, len)) { - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(src, len, sum); - } - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} - -#endif - diff --git a/arch/um/sys-x86_64/asm/checksum.h b/arch/um/sys-x86_64/asm/checksum.h new file mode 100644 index 0000000..a5be903 --- /dev/null +++ b/arch/um/sys-x86_64/asm/checksum.h @@ -0,0 +1,144 @@ +/* + * Licensed under the GPL + */ + +#ifndef __UM_SYSDEP_CHECKSUM_H +#define __UM_SYSDEP_CHECKSUM_H + +#include "linux/string.h" +#include "linux/in6.h" +#include "asm/uaccess.h" + +extern __wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ + +static __inline__ +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) +{ + memcpy(dst, src, len); + return(csum_partial(dst, len, sum)); +} + +static __inline__ +__wsum csum_partial_copy_from_user(const void __user *src, + void *dst, int len, __wsum sum, + int *err_ptr) +{ + if (copy_from_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + return csum_partial(dst, len, sum); +} + +/** + * csum_fold - Fold and invert a 32bit checksum. + * sum: 32bit unfolded sum + * + * Fold a 32bit running checksum to 16bit and invert it. This is usually + * the last step before putting a checksum into a packet. + * Make sure not to mix with 64bit checksums. + */ +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + " addl %1,%0\n" + " adcl $0xffff,%0" + : "=r" (sum) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) + ); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +/** + * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. + * @saddr: source address + * @daddr: destination address + * @len: length of packet + * @proto: ip protocol of packet + * @sum: initial sum to be added in (32bit unfolded) + * + * Returns the pseudo header checksum the input data. Result is + * 32bit unfolded. + */ +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + asm(" addl %1, %0\n" + " adcl %2, %0\n" + " adcl %3, %0\n" + " adcl $0, %0\n" + : "=r" (sum) + : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/** + * ip_fast_csum - Compute the IPv4 header checksum efficiently. + * iph: ipv4 header + * ihl: length of header / 4 + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum; + + asm( " movl (%1), %0\n" + " subl $4, %2\n" + " jbe 2f\n" + " addl 4(%1), %0\n" + " adcl 8(%1), %0\n" + " adcl 12(%1), %0\n" + "1: adcl 16(%1), %0\n" + " lea 4(%1), %1\n" + " decl %2\n" + " jne 1b\n" + " adcl $0, %0\n" + " movl %0, %2\n" + " shrl $16, %0\n" + " addw %w2, %w0\n" + " adcl $0, %0\n" + " notl %0\n" + "2:" + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)sum; +} + +static inline unsigned add32_with_carry(unsigned a, unsigned b) +{ + asm("addl %2,%0\n\t" + "adcl $0,%0" + : "=r" (a) + : "0" (a), "r" (b)); + return a; +} + +extern __sum16 ip_compute_csum(const void *buff, int len); + +#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/checksum.h b/arch/um/sys-x86_64/shared/sysdep/checksum.h deleted file mode 100644 index a5be903..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/checksum.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/string.h" -#include "linux/in6.h" -#include "asm/uaccess.h" - -extern __wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return(csum_partial(dst, len, sum)); -} - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, - int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - return csum_partial(dst, len, sum); -} - -/** - * csum_fold - Fold and invert a 32bit checksum. - * sum: 32bit unfolded sum - * - * Fold a 32bit running checksum to 16bit and invert it. This is usually - * the last step before putting a checksum into a packet. - * Make sure not to mix with 64bit checksums. - */ -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - " addl %1,%0\n" - " adcl $0xffff,%0" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -/** - * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. - * @saddr: source address - * @daddr: destination address - * @len: length of packet - * @proto: ip protocol of packet - * @sum: initial sum to be added in (32bit unfolded) - * - * Returns the pseudo header checksum the input data. Result is - * 32bit unfolded. - */ -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - asm(" addl %1, %0\n" - " adcl %2, %0\n" - " adcl %3, %0\n" - " adcl $0, %0\n" - : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/** - * ip_fast_csum - Compute the IPv4 header checksum efficiently. - * iph: ipv4 header - * ihl: length of header / 4 - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - asm( " movl (%1), %0\n" - " subl $4, %2\n" - " jbe 2f\n" - " addl 4(%1), %0\n" - " adcl 8(%1), %0\n" - " adcl 12(%1), %0\n" - "1: adcl 16(%1), %0\n" - " lea 4(%1), %1\n" - " decl %2\n" - " jne 1b\n" - " adcl $0, %0\n" - " movl %0, %2\n" - " shrl $16, %0\n" - " addw %w2, %w0\n" - " adcl $0, %0\n" - " notl %0\n" - "2:" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -static inline unsigned add32_with_carry(unsigned a, unsigned b) -{ - asm("addl %2,%0\n\t" - "adcl $0,%0" - : "=r" (a) - : "0" (a), "r" (b)); - return a; -} - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#endif -- cgit v1.1 From ab785c1dd4bef85f308504c83bcf47ce787e1565 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:19 +0100 Subject: um: take vm-flags.h to sys-*/asm Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/page.h | 2 +- arch/um/sys-i386/asm/vm-flags.h | 14 ++++++++++++++ arch/um/sys-i386/shared/sysdep/vm-flags.h | 14 -------------- arch/um/sys-x86_64/asm/vm-flags.h | 15 +++++++++++++++ arch/um/sys-x86_64/shared/sysdep/vm-flags.h | 15 --------------- 5 files changed, 30 insertions(+), 30 deletions(-) create mode 100644 arch/um/sys-i386/asm/vm-flags.h delete mode 100644 arch/um/sys-i386/shared/sysdep/vm-flags.h create mode 100644 arch/um/sys-x86_64/asm/vm-flags.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/vm-flags.h (limited to 'arch/um') diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 4cc9b6c..7cfc3ce 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -19,7 +19,7 @@ struct page; #include -#include +#include /* * These are used to make use of C type-checking.. diff --git a/arch/um/sys-i386/asm/vm-flags.h b/arch/um/sys-i386/asm/vm-flags.h new file mode 100644 index 0000000..e0d24c5 --- /dev/null +++ b/arch/um/sys-i386/asm/vm-flags.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __VM_FLAGS_I386_H +#define __VM_FLAGS_I386_H + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif diff --git a/arch/um/sys-i386/shared/sysdep/vm-flags.h b/arch/um/sys-i386/shared/sysdep/vm-flags.h deleted file mode 100644 index e0d24c5..0000000 --- a/arch/um/sys-i386/shared/sysdep/vm-flags.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_I386_H -#define __VM_FLAGS_I386_H - -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif diff --git a/arch/um/sys-x86_64/asm/vm-flags.h b/arch/um/sys-x86_64/asm/vm-flags.h new file mode 100644 index 0000000..3978e55 --- /dev/null +++ b/arch/um/sys-x86_64/asm/vm-flags.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Copyright 2003 PathScale, Inc. + * Licensed under the GPL + */ + +#ifndef __VM_FLAGS_X86_64_H +#define __VM_FLAGS_X86_64_H + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ + VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h deleted file mode 100644 index 3978e55..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_X86_64_H -#define __VM_FLAGS_X86_64_H - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif -- cgit v1.1 From 412f90ed13c86f066a4ab14ed5bcd0793ef0355d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:29 +0100 Subject: um: Get rid of UPT_SET/UPT_REG macros the only users are arch getreg()/putreg() and it's easier to handle it there instead of playing with macros from hell Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/ptrace-generic.h | 3 - arch/um/sys-i386/ptrace.c | 69 ++++++++++++++++---- arch/um/sys-i386/shared/sysdep/ptrace.h | 53 --------------- arch/um/sys-x86_64/ptrace.c | 103 +++++++++++++++++++++++++----- arch/um/sys-x86_64/shared/sysdep/ptrace.h | 75 ---------------------- 5 files changed, 145 insertions(+), 158 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index 1a7d275..c3b8a04 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -23,9 +23,6 @@ struct pt_regs { #define PT_REGS_IP(r) UPT_IP(&(r)->regs) #define PT_REGS_SP(r) UPT_SP(&(r)->regs) -#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg) -#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val) - #define PT_REGS_SET_SYSCALL_RETURN(r, res) \ UPT_SET_SYSCALL_RETURN(&(r)->regs, res) #define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 3375c27..a174fde 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -50,20 +50,47 @@ int is_syscall(unsigned long addr) /* 1 = access 0 = no access */ #define FLAG_MASK 0x00044dd5 +static const int reg_offsets[] = { + [EBX] = HOST_EBX, + [ECX] = HOST_ECX, + [EDX] = HOST_EDX, + [ESI] = HOST_ESI, + [EDI] = HOST_EDI, + [EBP] = HOST_EBP, + [EAX] = HOST_EAX, + [DS] = HOST_DS, + [ES] = HOST_ES, + [FS] = HOST_FS, + [GS] = HOST_GS, + [EIP] = HOST_IP, + [CS] = HOST_CS, + [EFL] = HOST_EFLAGS, + [UESP] = HOST_SP, + [SS] = HOST_SS, +}; + int putreg(struct task_struct *child, int regno, unsigned long value) { regno >>= 2; switch (regno) { + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EAX: + case EIP: + case UESP: + break; case FS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_FS(&child->thread.regs) = value; - return 0; + break; case GS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_GS(&child->thread.regs) = value; - return 0; + break; case DS: case ES: if (value && (value & 3) != 3) @@ -78,10 +105,15 @@ int putreg(struct task_struct *child, int regno, unsigned long value) break; case EFL: value &= FLAG_MASK; - value |= PT_REGS_EFLAGS(&child->thread.regs); - break; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + case ORIG_EAX: + child->thread.regs.regs.syscall = value; + return 0; + default : + panic("Bad register in putreg() : %d\n", regno); } - PT_REGS_SET(&child->thread.regs, regno, value); + child->thread.regs.regs.gp[reg_offsets[regno]] = value; return 0; } @@ -106,22 +138,35 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { - unsigned long retval = ~0UL; + unsigned long mask = ~0UL; regno >>= 2; switch (regno) { + case ORIG_EAX: + return child->thread.regs.regs.syscall; case FS: case GS: case DS: case ES: case SS: case CS: - retval = 0xffff; - /* fall through */ + mask = 0xffff; + break; + case EIP: + case UESP: + case EAX: + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EFL: + break; default: - retval &= PT_REG(&child->thread.regs, regno); + panic("Bad register in getreg() : %d\n", regno); } - return retval; + return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; } /* read the word at location addr in the USER area. */ diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index 3600699..6096c8f 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -100,59 +100,6 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case EIP: val = UPT_IP(regs); break; \ - case UESP: val = UPT_SP(regs); break; \ - case EAX: val = UPT_EAX(regs); break; \ - case EBX: val = UPT_EBX(regs); break; \ - case ECX: val = UPT_ECX(regs); break; \ - case EDX: val = UPT_EDX(regs); break; \ - case ESI: val = UPT_ESI(regs); break; \ - case EDI: val = UPT_EDI(regs); break; \ - case EBP: val = UPT_EBP(regs); break; \ - case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS: val = UPT_FS(regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFL: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - -#define UPT_SET(regs, reg, val) \ - do { \ - switch(reg){ \ - case EIP: UPT_IP(regs) = val; break; \ - case UESP: UPT_SP(regs) = val; break; \ - case EAX: UPT_EAX(regs) = val; break; \ - case EBX: UPT_EBX(regs) = val; break; \ - case ECX: UPT_ECX(regs) = val; break; \ - case EDX: UPT_EDX(regs) = val; break; \ - case ESI: UPT_ESI(regs) = val; break; \ - case EDI: UPT_EDI(regs) = val; break; \ - case EBP: UPT_EBP(regs) = val; break; \ - case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ - case CS: UPT_CS(regs) = val; break; \ - case SS: UPT_SS(regs) = val; break; \ - case DS: UPT_DS(regs) = val; break; \ - case ES: UPT_ES(regs) = val; break; \ - case FS: UPT_FS(regs) = val; break; \ - case GS: UPT_GS(regs) = val; break; \ - case EFL: UPT_EFLAGS(regs) = val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - } while (0) - #define UPT_SET_SYSCALL_RETURN(r, res) \ REGS_SET_SYSCALL_RETURN((r)->regs, (res)) diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 4005506..44e68e0 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -18,10 +18,39 @@ */ #define FLAG_MASK 0x44dd5UL -int putreg(struct task_struct *child, int regno, unsigned long value) +static const int reg_offsets[] = { - unsigned long tmp; + [R8 >> 3] = HOST_R8, + [R9 >> 3] = HOST_R9, + [R10 >> 3] = HOST_R10, + [R11 >> 3] = HOST_R11, + [R12 >> 3] = HOST_R12, + [R13 >> 3] = HOST_R13, + [R14 >> 3] = HOST_R14, + [R15 >> 3] = HOST_R15, + [RIP >> 3] = HOST_IP, + [RSP >> 3] = HOST_SP, + [RAX >> 3] = HOST_RAX, + [RBX >> 3] = HOST_RBX, + [RCX >> 3] = HOST_RCX, + [RDX >> 3] = HOST_RDX, + [RSI >> 3] = HOST_RSI, + [RDI >> 3] = HOST_RDI, + [RBP >> 3] = HOST_RBP, + [CS >> 3] = HOST_CS, + [SS >> 3] = HOST_SS, + [FS_BASE >> 3] = HOST_FS_BASE, + [GS_BASE >> 3] = HOST_GS_BASE, + [DS >> 3] = HOST_DS, + [ES >> 3] = HOST_ES, + [FS >> 3] = HOST_FS, + [GS >> 3] = HOST_GS, + [EFLAGS >> 3] = HOST_EFLAGS, + [ORIG_RAX >> 3] = HOST_ORIG_RAX, +}; +int putreg(struct task_struct *child, int regno, unsigned long value) +{ #ifdef TIF_IA32 /* * Some code in the 64bit emulation may not be 64bit clean. @@ -31,6 +60,26 @@ int putreg(struct task_struct *child, int regno, unsigned long value) value &= 0xffffffff; #endif switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + break; + case FS: case GS: case DS: @@ -50,12 +99,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value) case EFLAGS: value &= FLAG_MASK; - tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK; - value |= tmp; - break; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + + default: + panic("Bad register in putreg(): %d\n", regno); } - PT_REGS_SET(&child->thread.regs, regno, value); + child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; return 0; } @@ -80,24 +131,46 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { - unsigned long retval = ~0UL; + unsigned long mask = ~0UL; +#ifdef TIF_IA32 + if (test_tsk_thread_flag(child, TIF_IA32)) + mask = 0xffffffff; +#endif switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + case EFLAGS: + case FS_BASE: + case GS_BASE: + break; case FS: case GS: case DS: case ES: case SS: case CS: - retval = 0xffff; - /* fall through */ + mask = 0xffff; + break; default: - retval &= PT_REG(&child->thread.regs, regno); -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - retval &= 0xffffffff; -#endif + panic("Bad register in getreg: %d\n", regno); } - return retval; + return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; } int peek_user(struct task_struct *child, long addr, long data) diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h index ea5d7c1..9ed4597 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -147,81 +147,6 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case R8: val = UPT_R8(regs); break; \ - case R9: val = UPT_R9(regs); break; \ - case R10: val = UPT_R10(regs); break; \ - case R11: val = UPT_R11(regs); break; \ - case R12: val = UPT_R12(regs); break; \ - case R13: val = UPT_R13(regs); break; \ - case R14: val = UPT_R14(regs); break; \ - case R15: val = UPT_R15(regs); break; \ - case RIP: val = UPT_IP(regs); break; \ - case RSP: val = UPT_SP(regs); break; \ - case RAX: val = UPT_RAX(regs); break; \ - case RBX: val = UPT_RBX(regs); break; \ - case RCX: val = UPT_RCX(regs); break; \ - case RDX: val = UPT_RDX(regs); break; \ - case RSI: val = UPT_RSI(regs); break; \ - case RDI: val = UPT_RDI(regs); break; \ - case RBP: val = UPT_RBP(regs); break; \ - case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case FS_BASE: val = UPT_FS_BASE(regs); break; \ - case GS_BASE: val = UPT_GS_BASE(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS : val = UPT_FS (regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFLAGS: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - - -#define UPT_SET(regs, reg, val) \ - ({ unsigned long __upt_val = val; \ - switch(reg){ \ - case R8: UPT_R8(regs) = __upt_val; break; \ - case R9: UPT_R9(regs) = __upt_val; break; \ - case R10: UPT_R10(regs) = __upt_val; break; \ - case R11: UPT_R11(regs) = __upt_val; break; \ - case R12: UPT_R12(regs) = __upt_val; break; \ - case R13: UPT_R13(regs) = __upt_val; break; \ - case R14: UPT_R14(regs) = __upt_val; break; \ - case R15: UPT_R15(regs) = __upt_val; break; \ - case RIP: UPT_IP(regs) = __upt_val; break; \ - case RSP: UPT_SP(regs) = __upt_val; break; \ - case RAX: UPT_RAX(regs) = __upt_val; break; \ - case RBX: UPT_RBX(regs) = __upt_val; break; \ - case RCX: UPT_RCX(regs) = __upt_val; break; \ - case RDX: UPT_RDX(regs) = __upt_val; break; \ - case RSI: UPT_RSI(regs) = __upt_val; break; \ - case RDI: UPT_RDI(regs) = __upt_val; break; \ - case RBP: UPT_RBP(regs) = __upt_val; break; \ - case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ - case CS: UPT_CS(regs) = __upt_val; break; \ - case SS: UPT_SS(regs) = __upt_val; break; \ - case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ - case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ - case DS: UPT_DS(regs) = __upt_val; break; \ - case ES: UPT_ES(regs) = __upt_val; break; \ - case FS: UPT_FS(regs) = __upt_val; break; \ - case GS: UPT_GS(regs) = __upt_val; break; \ - case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - __upt_val; \ - }) - #define UPT_SET_SYSCALL_RETURN(r, res) \ REGS_SET_SYSCALL_RETURN((r)->regs, (res)) -- cgit v1.1 From ad694df534568b6072baebdb784b63c6209fe1cc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:39 +0100 Subject: um: get rid of sysdep/sc.h only sysdep/sigcontext.h uses it and very few definitions are actually used. The rest refers to symbols that don't even exist anymore anyway. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-i386/shared/sysdep/sc.h | 44 -------------------------- arch/um/sys-i386/shared/sysdep/sigcontext.h | 9 +++++- arch/um/sys-x86_64/shared/sysdep/sc.h | 45 --------------------------- arch/um/sys-x86_64/shared/sysdep/sigcontext.h | 8 ++++- 4 files changed, 15 insertions(+), 91 deletions(-) delete mode 100644 arch/um/sys-i386/shared/sysdep/sc.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/sc.h (limited to 'arch/um') diff --git a/arch/um/sys-i386/shared/sysdep/sc.h b/arch/um/sys-i386/shared/sysdep/sc.h deleted file mode 100644 index 7b89240..0000000 --- a/arch/um/sys-i386/shared/sysdep/sc.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __SYSDEP_I386_SC_H -#define __SYSDEP_I386_SC_H - -#include - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_FP_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) -#define SC_FP_OFFSET_PTR(sc, field, type) \ - ((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) - -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX) -#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX) -#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX) -#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX) -#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI) -#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI) -#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW) -#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW) -#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG) -#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF) -#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL) -#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF) -#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL) -#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate) -#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sigcontext.h b/arch/um/sys-i386/shared/sysdep/sigcontext.h index f583c87..3827864 100644 --- a/arch/um/sys-i386/shared/sysdep/sigcontext.h +++ b/arch/um/sys-i386/shared/sysdep/sigcontext.h @@ -6,10 +6,17 @@ #ifndef __SYS_SIGCONTEXT_I386_H #define __SYS_SIGCONTEXT_I386_H -#include "sysdep/sc.h" +#include #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) + +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) + #define GET_FAULTINFO_FROM_SC(fi, sc) \ { \ (fi).cr2 = SC_CR2(sc); \ diff --git a/arch/um/sys-x86_64/shared/sysdep/sc.h b/arch/um/sys-x86_64/shared/sysdep/sc.h deleted file mode 100644 index 20313a2..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/sc.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __SYSDEP_X86_64_SC_H -#define __SYSDEP_X86_64_SC_H - -/* Copyright (C) 2003 - 2004 PathScale, Inc - * Released under the GPL - */ - -#include - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX) -#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX) -#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX) -#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI) -#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI) -#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP) -#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX) -#define SC_R8(sc) SC_OFFSET(sc, SC_R8) -#define SC_R9(sc) SC_OFFSET(sc, SC_R9) -#define SC_R10(sc) SC_OFFSET(sc, SC_R10) -#define SC_R11(sc) SC_OFFSET(sc, SC_R11) -#define SC_R12(sc) SC_OFFSET(sc, SC_R12) -#define SC_R13(sc) SC_OFFSET(sc, SC_R13) -#define SC_R14(sc) SC_OFFSET(sc, SC_R14) -#define SC_R15(sc) SC_OFFSET(sc, SC_R15) -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#if 0 -#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#endif - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h index 0155133..9fb5277 100644 --- a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h +++ b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h @@ -7,7 +7,13 @@ #ifndef __SYSDEP_X86_64_SIGCONTEXT_H #define __SYSDEP_X86_64_SIGCONTEXT_H -#include +#include + +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -- cgit v1.1 From 3655c4d3c4bc105a36080c665b7294f471b0a1de Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:49 +0100 Subject: um: get rid of unused macros in ptrace_user.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-i386/shared/sysdep/ptrace_user.h | 24 ---------------- arch/um/sys-x86_64/shared/sysdep/ptrace_user.h | 39 -------------------------- 2 files changed, 63 deletions(-) (limited to 'arch/um') diff --git a/arch/um/sys-i386/shared/sysdep/ptrace_user.h b/arch/um/sys-i386/shared/sysdep/ptrace_user.h index e4398a3..9d88a79 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace_user.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace_user.h @@ -16,35 +16,11 @@ #define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) #define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) -#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX) -#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX) -#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) -#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) -#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) -#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP) - #define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) -#define REGS_SYSCALL_NR EAX /* This is used before a system call */ -#define REGS_SYSCALL_ARG1 EBX -#define REGS_SYSCALL_ARG2 ECX -#define REGS_SYSCALL_ARG3 EDX -#define REGS_SYSCALL_ARG4 ESI -#define REGS_SYSCALL_ARG5 EDI -#define REGS_SYSCALL_ARG6 EBP - #define REGS_IP_INDEX EIP #define REGS_SP_INDEX UESP -#define PT_IP_OFFSET PT_OFFSET(EIP) -#define PT_IP(regs) ((regs)[EIP]) -#define PT_SP_OFFSET PT_OFFSET(UESP) -#define PT_SP(regs) ((regs)[UESP]) - #define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) -#ifndef FRAME_SIZE -#define FRAME_SIZE (17) -#endif - #endif diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h index faf9cdd..2f1b6e3 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h @@ -19,35 +19,8 @@ #define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) #define PT_SYSCALL_NR_OFFSET (ORIG_RAX) -#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)]) -#define PT_SYSCALL_ARG1_OFFSET (RDI) - -#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)]) -#define PT_SYSCALL_ARG2_OFFSET (RSI) - -#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)]) -#define PT_SYSCALL_ARG3_OFFSET (RDX) - -#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)]) -#define PT_SYSCALL_ARG4_OFFSET (RCX) - -#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)]) -#define PT_SYSCALL_ARG5_OFFSET (R8) - -#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)]) -#define PT_SYSCALL_ARG6_OFFSET (R9) - #define PT_SYSCALL_RET_OFFSET (RAX) -#define PT_IP_OFFSET (RIP) -#define PT_IP(regs) ((regs)[PT_INDEX(RIP)]) - -#define PT_SP_OFFSET (RSP) -#define PT_SP(regs) ((regs)[PT_INDEX(RSP)]) - -#define PT_ORIG_RAX_OFFSET (ORIG_RAX) -#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)]) - /* * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the @@ -57,18 +30,6 @@ #define PTRACE_OLDSETOPTIONS 21 #endif -/* - * These are before the system call, so the system call number is RAX - * rather than ORIG_RAX, and arg4 is R10 rather than RCX - */ -#define REGS_SYSCALL_NR PT_INDEX(RAX) -#define REGS_SYSCALL_ARG1 PT_INDEX(RDI) -#define REGS_SYSCALL_ARG2 PT_INDEX(RSI) -#define REGS_SYSCALL_ARG3 PT_INDEX(RDX) -#define REGS_SYSCALL_ARG4 PT_INDEX(R10) -#define REGS_SYSCALL_ARG5 PT_INDEX(R8) -#define REGS_SYSCALL_ARG6 PT_INDEX(R9) - #define REGS_IP_INDEX PT_INDEX(RIP) #define REGS_SP_INDEX PT_INDEX(RSP) -- cgit v1.1 From 27f85f12639fe821375a69900d96e0fbcc1450bf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:02:59 +0100 Subject: um: merge arch/um/sys-{i386,x86_64}/asm Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 4 +- arch/um/sys-i386/asm/archparam.h | 16 --- arch/um/sys-i386/asm/checksum.h | 201 --------------------------------- arch/um/sys-i386/asm/elf.h | 125 --------------------- arch/um/sys-i386/asm/module.h | 13 --- arch/um/sys-i386/asm/processor.h | 78 ------------- arch/um/sys-i386/asm/ptrace.h | 51 --------- arch/um/sys-i386/asm/vm-flags.h | 14 --- arch/um/sys-x86/asm/archparam.h | 20 ++++ arch/um/sys-x86/asm/checksum.h | 10 ++ arch/um/sys-x86/asm/checksum_32.h | 201 +++++++++++++++++++++++++++++++++ arch/um/sys-x86/asm/checksum_64.h | 144 ++++++++++++++++++++++++ arch/um/sys-x86/asm/elf.h | 221 +++++++++++++++++++++++++++++++++++++ arch/um/sys-x86/asm/module.h | 23 ++++ arch/um/sys-x86/asm/processor.h | 15 +++ arch/um/sys-x86/asm/processor_32.h | 73 ++++++++++++ arch/um/sys-x86/asm/processor_64.h | 51 +++++++++ arch/um/sys-x86/asm/ptrace.h | 5 + arch/um/sys-x86/asm/ptrace_32.h | 51 +++++++++ arch/um/sys-x86/asm/ptrace_64.h | 72 ++++++++++++ arch/um/sys-x86/asm/vm-flags.h | 25 +++++ arch/um/sys-x86_64/asm/archparam.h | 16 --- arch/um/sys-x86_64/asm/checksum.h | 144 ------------------------ arch/um/sys-x86_64/asm/elf.h | 132 ---------------------- arch/um/sys-x86_64/asm/module.h | 20 ---- arch/um/sys-x86_64/asm/processor.h | 56 ---------- arch/um/sys-x86_64/asm/ptrace.h | 72 ------------ arch/um/sys-x86_64/asm/vm-flags.h | 15 --- 28 files changed, 913 insertions(+), 955 deletions(-) delete mode 100644 arch/um/sys-i386/asm/archparam.h delete mode 100644 arch/um/sys-i386/asm/checksum.h delete mode 100644 arch/um/sys-i386/asm/elf.h delete mode 100644 arch/um/sys-i386/asm/module.h delete mode 100644 arch/um/sys-i386/asm/processor.h delete mode 100644 arch/um/sys-i386/asm/ptrace.h delete mode 100644 arch/um/sys-i386/asm/vm-flags.h create mode 100644 arch/um/sys-x86/asm/archparam.h create mode 100644 arch/um/sys-x86/asm/checksum.h create mode 100644 arch/um/sys-x86/asm/checksum_32.h create mode 100644 arch/um/sys-x86/asm/checksum_64.h create mode 100644 arch/um/sys-x86/asm/elf.h create mode 100644 arch/um/sys-x86/asm/module.h create mode 100644 arch/um/sys-x86/asm/processor.h create mode 100644 arch/um/sys-x86/asm/processor_32.h create mode 100644 arch/um/sys-x86/asm/processor_64.h create mode 100644 arch/um/sys-x86/asm/ptrace.h create mode 100644 arch/um/sys-x86/asm/ptrace_32.h create mode 100644 arch/um/sys-x86/asm/ptrace_64.h create mode 100644 arch/um/sys-x86/asm/vm-flags.h delete mode 100644 arch/um/sys-x86_64/asm/archparam.h delete mode 100644 arch/um/sys-x86_64/asm/checksum.h delete mode 100644 arch/um/sys-x86_64/asm/elf.h delete mode 100644 arch/um/sys-x86_64/asm/module.h delete mode 100644 arch/um/sys-x86_64/asm/processor.h delete mode 100644 arch/um/sys-x86_64/asm/ptrace.h delete mode 100644 arch/um/sys-x86_64/asm/vm-flags.h (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index 649aebc..c121870 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -21,10 +21,12 @@ core-y += $(ARCH_DIR)/kernel/ \ MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas include $(srctree)/$(ARCH_DIR)/Makefile-skas +include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared +KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(HEADER_ARCH) KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so @@ -46,8 +48,6 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) - #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) diff --git a/arch/um/sys-i386/asm/archparam.h b/arch/um/sys-i386/asm/archparam.h deleted file mode 100644 index 2a18a88..0000000 --- a/arch/um/sys-i386/asm/archparam.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_I386_H -#define __UM_ARCHPARAM_I386_H - -#ifdef CONFIG_X86_PAE -#define LAST_PKMAP 512 -#else -#define LAST_PKMAP 1024 -#endif - -#endif - diff --git a/arch/um/sys-i386/asm/checksum.h b/arch/um/sys-i386/asm/checksum.h deleted file mode 100644 index caab742..0000000 --- a/arch/um/sys-i386/asm/checksum.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/in6.h" -#include "linux/string.h" - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - -/* - * the same as csum_partial, but copies from src while it - * checksums, and handles user-space pointer exceptions correctly, when needed. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(dst, len, sum); -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - * By Jorge Cwik , adapted for linux by - * Arnt Gulbrandsen. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - __asm__ __volatile__( - "movl (%1), %0 ;\n" - "subl $4, %2 ;\n" - "jbe 2f ;\n" - "addl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" -"1: adcl 16(%1), %0 ;\n" - "lea 4(%1), %1 ;\n" - "decl %2 ;\n" - "jne 1b ;\n" - "adcl $0, %0 ;\n" - "movl %0, %2 ;\n" - "shrl $16, %0 ;\n" - "addw %w2, %w0 ;\n" - "adcl $0, %0 ;\n" - "notl %0 ;\n" -"2: ;\n" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl $0xffff, %0 ;\n" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl %2, %0 ;\n" - "adcl %3, %0 ;\n" - "adcl $0, %0 ;\n" - : "=r" (sum) - : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - __asm__( - "addl 0(%1), %0 ;\n" - "adcl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" - "adcl 0(%2), %0 ;\n" - "adcl 4(%2), %0 ;\n" - "adcl 8(%2), %0 ;\n" - "adcl 12(%2), %0 ;\n" - "adcl %3, %0 ;\n" - "adcl %4, %0 ;\n" - "adcl $0, %0 ;\n" - : "=&r" (sum) - : "r" (saddr), "r" (daddr), - "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); - - return csum_fold(sum); -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, int *err_ptr) -{ - if (access_ok(VERIFY_WRITE, dst, len)) { - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(src, len, sum); - } - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} - -#endif - diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h deleted file mode 100644 index 4230555..0000000 --- a/arch/um/sys-i386/asm/elf.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ -#ifndef __UM_ELF_I386_H -#define __UM_ELF_I386_H - -#include -#include "skas.h" - -#define R_386_NONE 0 -#define R_386_32 1 -#define R_386_PC32 2 -#define R_386_GOT32 3 -#define R_386_PLT32 4 -#define R_386_COPY 5 -#define R_386_GLOB_DAT 6 -#define R_386_JMP_SLOT 7 -#define R_386_RELATIVE 8 -#define R_386_GOTOFF 9 -#define R_386_GOTPC 10 -#define R_386_NUM 11 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) - -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_386 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_EBX(regs) = 0; \ - PT_REGS_ECX(regs) = 0; \ - PT_REGS_EDX(regs) = 0; \ - PT_REGS_ESI(regs) = 0; \ - PT_REGS_EDI(regs) = 0; \ - PT_REGS_EBP(regs) = 0; \ - PT_REGS_EAX(regs) = 0; \ -} while (0) - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -/* Shamelessly stolen from include/asm-i386/elf.h */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ - pr_reg[0] = PT_REGS_EBX(regs); \ - pr_reg[1] = PT_REGS_ECX(regs); \ - pr_reg[2] = PT_REGS_EDX(regs); \ - pr_reg[3] = PT_REGS_ESI(regs); \ - pr_reg[4] = PT_REGS_EDI(regs); \ - pr_reg[5] = PT_REGS_EBP(regs); \ - pr_reg[6] = PT_REGS_EAX(regs); \ - pr_reg[7] = PT_REGS_DS(regs); \ - pr_reg[8] = PT_REGS_ES(regs); \ - /* fake once used fs and gs selectors? */ \ - pr_reg[9] = PT_REGS_DS(regs); \ - pr_reg[10] = PT_REGS_DS(regs); \ - pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ - pr_reg[12] = PT_REGS_IP(regs); \ - pr_reg[13] = PT_REGS_CS(regs); \ - pr_reg[14] = PT_REGS_EFLAGS(regs); \ - pr_reg[15] = PT_REGS_SP(regs); \ - pr_reg[16] = PT_REGS_SS(regs); \ -} while (0); - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -extern char * elf_aux_platform; -#define ELF_PLATFORM (elf_aux_platform) - -#define SET_PERSONALITY(ex) do { } while (0) - -extern unsigned long vsyscall_ehdr; -extern unsigned long vsyscall_end; -extern unsigned long __kernel_vsyscall; - -#define VSYSCALL_BASE vsyscall_ehdr -#define VSYSCALL_END vsyscall_end - -/* - * This is the range that is readable by user mode, and things - * acting like user mode such as get_user_pages. - */ -#define FIXADDR_USER_START VSYSCALL_BASE -#define FIXADDR_USER_END VSYSCALL_END - -#define __HAVE_ARCH_GATE_AREA 1 - -/* - * Architecture-neutral AT_ values in 0-17, leave some room - * for more of them, start the x86-specific ones at 32. - */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -#define ARCH_DLINFO \ -do { \ - if ( vsyscall_ehdr ) { \ - NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ - } \ -} while (0) - -#endif diff --git a/arch/um/sys-i386/asm/module.h b/arch/um/sys-i386/asm/module.h deleted file mode 100644 index 5ead4a0..0000000 --- a/arch/um/sys-i386/asm/module.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __UM_MODULE_I386_H -#define __UM_MODULE_I386_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif diff --git a/arch/um/sys-i386/asm/processor.h b/arch/um/sys-i386/asm/processor.h deleted file mode 100644 index 82a9061..0000000 --- a/arch/um/sys-i386/asm/processor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_I386_H -#define __UM_PROCESSOR_I386_H - -#include "linux/string.h" -#include -#include "asm/segment.h" - -extern int host_has_cmov; - -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - -struct uml_tls_struct { - struct user_desc tls; - unsigned flushed:1; - unsigned present:1; -}; - -struct arch_thread { - struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - unsigned long debugregs[8]; - int debugregs_seq; - struct faultinfo faultinfo; -}; - -#define INIT_ARCH_THREAD { \ - .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \ - { .present = 0, .flushed = 0 } }, \ - .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .faultinfo = { 0, 0, 0 } \ -} - -static inline void arch_flush_thread(struct arch_thread *thread) -{ - /* Clear any TLS still hanging */ - memset(&thread->tls_array, 0, sizeof(thread->tls_array)); -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array)); -} - -#include - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). Stolen - * from asm-i386/processor.h - */ -#define current_text_addr() \ - ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 32 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) -#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) - -#include "asm/processor-generic.h" - -#endif diff --git a/arch/um/sys-i386/asm/ptrace.h b/arch/um/sys-i386/asm/ptrace.h deleted file mode 100644 index 5d2a591..0000000 --- a/arch/um/sys-i386/asm/ptrace.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_I386_H -#define __UM_PTRACE_I386_H - -#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 - -#include "linux/compiler.h" -#include "asm/ptrace-generic.h" - -#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) -#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) -#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) -#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) -#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) -#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) -#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) - -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -#define user_mode(r) UPT_IS_USER(&(r)->regs) - -/* - * Forward declaration to avoid including sysdep/tls.h, which causes a - * circular include, and compilation failures. - */ -struct user_desc; - -extern int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -extern int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -#endif diff --git a/arch/um/sys-i386/asm/vm-flags.h b/arch/um/sys-i386/asm/vm-flags.h deleted file mode 100644 index e0d24c5..0000000 --- a/arch/um/sys-i386/asm/vm-flags.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_I386_H -#define __VM_FLAGS_I386_H - -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif diff --git a/arch/um/sys-x86/asm/archparam.h b/arch/um/sys-x86/asm/archparam.h new file mode 100644 index 0000000..c17cf68 --- /dev/null +++ b/arch/um/sys-x86/asm/archparam.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright 2003 PathScale, Inc. + * Licensed under the GPL + */ + +#ifndef __UM_ARCHPARAM_H +#define __UM_ARCHPARAM_H + +#ifdef CONFIG_X86_32 + +#ifdef CONFIG_X86_PAE +#define LAST_PKMAP 512 +#else +#define LAST_PKMAP 1024 +#endif + +#endif + +#endif diff --git a/arch/um/sys-x86/asm/checksum.h b/arch/um/sys-x86/asm/checksum.h new file mode 100644 index 0000000..b6efe23 --- /dev/null +++ b/arch/um/sys-x86/asm/checksum.h @@ -0,0 +1,10 @@ +#ifndef __UM_CHECKSUM_H +#define __UM_CHECKSUM_H + +#ifdef CONFIG_X86_32 +# include "checksum_32.h" +#else +# include "checksum_64.h" +#endif + +#endif diff --git a/arch/um/sys-x86/asm/checksum_32.h b/arch/um/sys-x86/asm/checksum_32.h new file mode 100644 index 0000000..caab742 --- /dev/null +++ b/arch/um/sys-x86/asm/checksum_32.h @@ -0,0 +1,201 @@ +/* + * Licensed under the GPL + */ + +#ifndef __UM_SYSDEP_CHECKSUM_H +#define __UM_SYSDEP_CHECKSUM_H + +#include "linux/in6.h" +#include "linux/string.h" + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ + +static __inline__ +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) +{ + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +static __inline__ +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) +{ + if (copy_from_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + + return csum_partial(dst, len, sum); +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik , adapted for linux by + * Arnt Gulbrandsen. + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum; + + __asm__ __volatile__( + "movl (%1), %0 ;\n" + "subl $4, %2 ;\n" + "jbe 2f ;\n" + "addl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" +"1: adcl 16(%1), %0 ;\n" + "lea 4(%1), %1 ;\n" + "decl %2 ;\n" + "jne 1b ;\n" + "adcl $0, %0 ;\n" + "movl %0, %2 ;\n" + "shrl $16, %0 ;\n" + "addw %w2, %w0 ;\n" + "adcl $0, %0 ;\n" + "notl %0 ;\n" +"2: ;\n" + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)sum; +} + +/* + * Fold a partial checksum + */ + +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl $0xffff, %0 ;\n" + : "=r" (sum) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) + ); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + __asm__( + "addl %1, %0 ;\n" + "adcl %2, %0 ;\n" + "adcl %3, %0 ;\n" + "adcl $0, %0 ;\n" + : "=r" (sum) + : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, + __wsum sum) +{ + __asm__( + "addl 0(%1), %0 ;\n" + "adcl 4(%1), %0 ;\n" + "adcl 8(%1), %0 ;\n" + "adcl 12(%1), %0 ;\n" + "adcl 0(%2), %0 ;\n" + "adcl 4(%2), %0 ;\n" + "adcl 8(%2), %0 ;\n" + "adcl 12(%2), %0 ;\n" + "adcl %3, %0 ;\n" + "adcl %4, %0 ;\n" + "adcl $0, %0 ;\n" + : "=&r" (sum) + : "r" (saddr), "r" (daddr), + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); + + return csum_fold(sum); +} + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +static __inline__ __wsum csum_and_copy_to_user(const void *src, + void __user *dst, + int len, __wsum sum, int *err_ptr) +{ + if (access_ok(VERIFY_WRITE, dst, len)) { + if (copy_to_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + + return csum_partial(src, len, sum); + } + + if (len) + *err_ptr = -EFAULT; + + return (__force __wsum)-1; /* invalid checksum */ +} + +#endif + diff --git a/arch/um/sys-x86/asm/checksum_64.h b/arch/um/sys-x86/asm/checksum_64.h new file mode 100644 index 0000000..a5be903 --- /dev/null +++ b/arch/um/sys-x86/asm/checksum_64.h @@ -0,0 +1,144 @@ +/* + * Licensed under the GPL + */ + +#ifndef __UM_SYSDEP_CHECKSUM_H +#define __UM_SYSDEP_CHECKSUM_H + +#include "linux/string.h" +#include "linux/in6.h" +#include "asm/uaccess.h" + +extern __wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. + * + * If you use these functions directly please don't forget the + * access_ok(). + */ + +static __inline__ +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) +{ + memcpy(dst, src, len); + return(csum_partial(dst, len, sum)); +} + +static __inline__ +__wsum csum_partial_copy_from_user(const void __user *src, + void *dst, int len, __wsum sum, + int *err_ptr) +{ + if (copy_from_user(dst, src, len)) { + *err_ptr = -EFAULT; + return (__force __wsum)-1; + } + return csum_partial(dst, len, sum); +} + +/** + * csum_fold - Fold and invert a 32bit checksum. + * sum: 32bit unfolded sum + * + * Fold a 32bit running checksum to 16bit and invert it. This is usually + * the last step before putting a checksum into a packet. + * Make sure not to mix with 64bit checksums. + */ +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + " addl %1,%0\n" + " adcl $0xffff,%0" + : "=r" (sum) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) + ); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +/** + * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. + * @saddr: source address + * @daddr: destination address + * @len: length of packet + * @proto: ip protocol of packet + * @sum: initial sum to be added in (32bit unfolded) + * + * Returns the pseudo header checksum the input data. Result is + * 32bit unfolded. + */ +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + asm(" addl %1, %0\n" + " adcl %2, %0\n" + " adcl %3, %0\n" + " adcl $0, %0\n" + : "=r" (sum) + : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/** + * ip_fast_csum - Compute the IPv4 header checksum efficiently. + * iph: ipv4 header + * ihl: length of header / 4 + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum; + + asm( " movl (%1), %0\n" + " subl $4, %2\n" + " jbe 2f\n" + " addl 4(%1), %0\n" + " adcl 8(%1), %0\n" + " adcl 12(%1), %0\n" + "1: adcl 16(%1), %0\n" + " lea 4(%1), %1\n" + " decl %2\n" + " jne 1b\n" + " adcl $0, %0\n" + " movl %0, %2\n" + " shrl $16, %0\n" + " addw %w2, %w0\n" + " adcl $0, %0\n" + " notl %0\n" + "2:" + /* Since the input registers which are loaded with iph and ipl + are modified, we must also specify them as outputs, or gcc + will assume they contain their original values. */ + : "=r" (sum), "=r" (iph), "=r" (ihl) + : "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)sum; +} + +static inline unsigned add32_with_carry(unsigned a, unsigned b) +{ + asm("addl %2,%0\n\t" + "adcl $0,%0" + : "=r" (a) + : "0" (a), "r" (b)); + return a; +} + +extern __sum16 ip_compute_csum(const void *buff, int len); + +#endif diff --git a/arch/um/sys-x86/asm/elf.h b/arch/um/sys-x86/asm/elf.h new file mode 100644 index 0000000..f3b0633 --- /dev/null +++ b/arch/um/sys-x86/asm/elf.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ +#ifndef __UM_ELF_X86_H +#define __UM_ELF_X86_H + +#include +#include "skas.h" + +#ifdef CONFIG_X86_32 + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_NUM 11 + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) \ + (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_386 + +#define ELF_PLAT_INIT(regs, load_addr) do { \ + PT_REGS_EBX(regs) = 0; \ + PT_REGS_ECX(regs) = 0; \ + PT_REGS_EDX(regs) = 0; \ + PT_REGS_ESI(regs) = 0; \ + PT_REGS_EDI(regs) = 0; \ + PT_REGS_EBP(regs) = 0; \ + PT_REGS_EAX(regs) = 0; \ +} while (0) + +/* Shamelessly stolen from include/asm-i386/elf.h */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = PT_REGS_EBX(regs); \ + pr_reg[1] = PT_REGS_ECX(regs); \ + pr_reg[2] = PT_REGS_EDX(regs); \ + pr_reg[3] = PT_REGS_ESI(regs); \ + pr_reg[4] = PT_REGS_EDI(regs); \ + pr_reg[5] = PT_REGS_EBP(regs); \ + pr_reg[6] = PT_REGS_EAX(regs); \ + pr_reg[7] = PT_REGS_DS(regs); \ + pr_reg[8] = PT_REGS_ES(regs); \ + /* fake once used fs and gs selectors? */ \ + pr_reg[9] = PT_REGS_DS(regs); \ + pr_reg[10] = PT_REGS_DS(regs); \ + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ + pr_reg[12] = PT_REGS_IP(regs); \ + pr_reg[13] = PT_REGS_CS(regs); \ + pr_reg[14] = PT_REGS_EFLAGS(regs); \ + pr_reg[15] = PT_REGS_SP(regs); \ + pr_reg[16] = PT_REGS_SS(regs); \ +} while (0); + +extern char * elf_aux_platform; +#define ELF_PLATFORM (elf_aux_platform) + +extern unsigned long vsyscall_ehdr; +extern unsigned long vsyscall_end; +extern unsigned long __kernel_vsyscall; + +/* + * This is the range that is readable by user mode, and things + * acting like user mode such as get_user_pages. + */ +#define FIXADDR_USER_START vsyscall_ehdr +#define FIXADDR_USER_END vsyscall_end + + +/* + * Architecture-neutral AT_ values in 0-17, leave some room + * for more of them, start the x86-specific ones at 32. + */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +#define ARCH_DLINFO \ +do { \ + if ( vsyscall_ehdr ) { \ + NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ + } \ +} while (0) + +#else + +/* x86-64 relocation types, taken from asm-x86_64/elf.h */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ + +#define R_X86_64_NUM 16 + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) \ + ((x)->e_machine == EM_X86_64) + +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_X86_64 + +#define ELF_PLAT_INIT(regs, load_addr) do { \ + PT_REGS_RBX(regs) = 0; \ + PT_REGS_RCX(regs) = 0; \ + PT_REGS_RDX(regs) = 0; \ + PT_REGS_RSI(regs) = 0; \ + PT_REGS_RDI(regs) = 0; \ + PT_REGS_RBP(regs) = 0; \ + PT_REGS_RAX(regs) = 0; \ + PT_REGS_R8(regs) = 0; \ + PT_REGS_R9(regs) = 0; \ + PT_REGS_R10(regs) = 0; \ + PT_REGS_R11(regs) = 0; \ + PT_REGS_R12(regs) = 0; \ + PT_REGS_R13(regs) = 0; \ + PT_REGS_R14(regs) = 0; \ + PT_REGS_R15(regs) = 0; \ +} while (0) + +#define ELF_CORE_COPY_REGS(pr_reg, _regs) \ + (pr_reg)[0] = (_regs)->regs.gp[0]; \ + (pr_reg)[1] = (_regs)->regs.gp[1]; \ + (pr_reg)[2] = (_regs)->regs.gp[2]; \ + (pr_reg)[3] = (_regs)->regs.gp[3]; \ + (pr_reg)[4] = (_regs)->regs.gp[4]; \ + (pr_reg)[5] = (_regs)->regs.gp[5]; \ + (pr_reg)[6] = (_regs)->regs.gp[6]; \ + (pr_reg)[7] = (_regs)->regs.gp[7]; \ + (pr_reg)[8] = (_regs)->regs.gp[8]; \ + (pr_reg)[9] = (_regs)->regs.gp[9]; \ + (pr_reg)[10] = (_regs)->regs.gp[10]; \ + (pr_reg)[11] = (_regs)->regs.gp[11]; \ + (pr_reg)[12] = (_regs)->regs.gp[12]; \ + (pr_reg)[13] = (_regs)->regs.gp[13]; \ + (pr_reg)[14] = (_regs)->regs.gp[14]; \ + (pr_reg)[15] = (_regs)->regs.gp[15]; \ + (pr_reg)[16] = (_regs)->regs.gp[16]; \ + (pr_reg)[17] = (_regs)->regs.gp[17]; \ + (pr_reg)[18] = (_regs)->regs.gp[18]; \ + (pr_reg)[19] = (_regs)->regs.gp[19]; \ + (pr_reg)[20] = (_regs)->regs.gp[20]; \ + (pr_reg)[21] = current->thread.arch.fs; \ + (pr_reg)[22] = 0; \ + (pr_reg)[23] = 0; \ + (pr_reg)[24] = 0; \ + (pr_reg)[25] = 0; \ + (pr_reg)[26] = 0; + +#define ELF_PLATFORM "x86_64" + +/* No user-accessible fixmap addresses, i.e. vsyscall */ +#define FIXADDR_USER_START 0 +#define FIXADDR_USER_END 0 + +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 +struct linux_binprm; +extern int arch_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp); + +extern unsigned long um_vdso_addr; +#define AT_SYSINFO_EHDR 33 +#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) + +#endif + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_i387_struct elf_fpregset_t; + +#define task_pt_regs(t) (&(t)->thread.regs) + +struct task_struct; + +extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); + +#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) + +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) + +extern long elf_aux_hwcap; +#define ELF_HWCAP (elf_aux_hwcap) + +#define SET_PERSONALITY(ex) do ; while(0) +#define __HAVE_ARCH_GATE_AREA 1 + +#endif diff --git a/arch/um/sys-x86/asm/module.h b/arch/um/sys-x86/asm/module.h new file mode 100644 index 0000000..61af80e --- /dev/null +++ b/arch/um/sys-x86/asm/module.h @@ -0,0 +1,23 @@ +#ifndef __UM_MODULE_H +#define __UM_MODULE_H + +/* UML is simple */ +struct mod_arch_specific +{ +}; + +#ifdef CONFIG_X86_32 + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +#else + +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Ehdr Elf64_Ehdr + +#endif + +#endif diff --git a/arch/um/sys-x86/asm/processor.h b/arch/um/sys-x86/asm/processor.h new file mode 100644 index 0000000..d3ac1ce --- /dev/null +++ b/arch/um/sys-x86/asm/processor.h @@ -0,0 +1,15 @@ +#ifndef __UM_PROCESSOR_H +#define __UM_PROCESSOR_H + +/* include faultinfo structure */ +#include + +#ifdef CONFIG_X86_32 +# include "processor_32.h" +#else +# include "processor_64.h" +#endif + +#include + +#endif diff --git a/arch/um/sys-x86/asm/processor_32.h b/arch/um/sys-x86/asm/processor_32.h new file mode 100644 index 0000000..ae0d189 --- /dev/null +++ b/arch/um/sys-x86/asm/processor_32.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_PROCESSOR_I386_H +#define __UM_PROCESSOR_I386_H + +#include +#include +#include + +extern int host_has_cmov; + +struct uml_tls_struct { + struct user_desc tls; + unsigned flushed:1; + unsigned present:1; +}; + +struct arch_thread { + struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; + unsigned long debugregs[8]; + int debugregs_seq; + struct faultinfo faultinfo; +}; + +#define INIT_ARCH_THREAD { \ + .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \ + { .present = 0, .flushed = 0 } }, \ + .debugregs = { [ 0 ... 7 ] = 0 }, \ + .debugregs_seq = 0, \ + .faultinfo = { 0, 0, 0 } \ +} + +static inline void arch_flush_thread(struct arch_thread *thread) +{ + /* Clear any TLS still hanging */ + memset(&thread->tls_array, 0, sizeof(thread->tls_array)); +} + +static inline void arch_copy_thread(struct arch_thread *from, + struct arch_thread *to) +{ + memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array)); +} + +#include + +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static inline void rep_nop(void) +{ + __asm__ __volatile__("rep;nop": : :"memory"); +} + +#define cpu_relax() rep_nop() + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). Stolen + * from asm-i386/processor.h + */ +#define current_text_addr() \ + ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) + +#define ARCH_IS_STACKGROW(address) \ + (address + 32 >= UPT_SP(¤t->thread.regs.regs)) + +#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) +#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) +#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) + +#endif diff --git a/arch/um/sys-x86/asm/processor_64.h b/arch/um/sys-x86/asm/processor_64.h new file mode 100644 index 0000000..6db812b --- /dev/null +++ b/arch/um/sys-x86/asm/processor_64.h @@ -0,0 +1,51 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __UM_PROCESSOR_X86_64_H +#define __UM_PROCESSOR_X86_64_H + +struct arch_thread { + unsigned long debugregs[8]; + int debugregs_seq; + unsigned long fs; + struct faultinfo faultinfo; +}; + +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static inline void rep_nop(void) +{ + __asm__ __volatile__("rep;nop": : :"memory"); +} + +#define cpu_relax() rep_nop() + +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ + .debugregs_seq = 0, \ + .fs = 0, \ + .faultinfo = { 0, 0, 0 } } + +static inline void arch_flush_thread(struct arch_thread *thread) +{ +} + +static inline void arch_copy_thread(struct arch_thread *from, + struct arch_thread *to) +{ + to->fs = from->fs; +} + +#include + +#define current_text_addr() \ + ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) + +#define ARCH_IS_STACKGROW(address) \ + (address + 128 >= UPT_SP(¤t->thread.regs.regs)) + +#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP) +#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP) + +#endif diff --git a/arch/um/sys-x86/asm/ptrace.h b/arch/um/sys-x86/asm/ptrace.h new file mode 100644 index 0000000..c8aca8c --- /dev/null +++ b/arch/um/sys-x86/asm/ptrace.h @@ -0,0 +1,5 @@ +#ifdef CONFIG_X86_32 +# include "ptrace_32.h" +#else +# include "ptrace_64.h" +#endif diff --git a/arch/um/sys-x86/asm/ptrace_32.h b/arch/um/sys-x86/asm/ptrace_32.h new file mode 100644 index 0000000..5d2a591 --- /dev/null +++ b/arch/um/sys-x86/asm/ptrace_32.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __UM_PTRACE_I386_H +#define __UM_PTRACE_I386_H + +#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 + +#include "linux/compiler.h" +#include "asm/ptrace-generic.h" + +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) + +#define PT_REGS_CS(r) UPT_CS(&(r)->regs) +#define PT_REGS_SS(r) UPT_SS(&(r)->regs) +#define PT_REGS_DS(r) UPT_DS(&(r)->regs) +#define PT_REGS_ES(r) UPT_ES(&(r)->regs) +#define PT_REGS_FS(r) UPT_FS(&(r)->regs) +#define PT_REGS_GS(r) UPT_GS(&(r)->regs) + +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) + +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) +#define PT_FIX_EXEC_STACK(sp) do ; while(0) + +#define profile_pc(regs) PT_REGS_IP(regs) + +#define user_mode(r) UPT_IS_USER(&(r)->regs) + +/* + * Forward declaration to avoid including sysdep/tls.h, which causes a + * circular include, and compilation failures. + */ +struct user_desc; + +extern int ptrace_get_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc); + +extern int ptrace_set_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc); + +#endif diff --git a/arch/um/sys-x86/asm/ptrace_64.h b/arch/um/sys-x86/asm/ptrace_64.h new file mode 100644 index 0000000..83d8c47 --- /dev/null +++ b/arch/um/sys-x86/asm/ptrace_64.h @@ -0,0 +1,72 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __UM_PTRACE_X86_64_H +#define __UM_PTRACE_X86_64_H + +#include "linux/compiler.h" +#include "asm/errno.h" + +#define __FRAME_OFFSETS /* Needed to get the R* macros */ +#include "asm/ptrace-generic.h" + +#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64 + +#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs) +#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs) +#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs) +#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs) +#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs) +#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs) +#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs) +#define PT_REGS_R8(r) UPT_R8(&(r)->regs) +#define PT_REGS_R9(r) UPT_R9(&(r)->regs) +#define PT_REGS_R10(r) UPT_R10(&(r)->regs) +#define PT_REGS_R11(r) UPT_R11(&(r)->regs) +#define PT_REGS_R12(r) UPT_R12(&(r)->regs) +#define PT_REGS_R13(r) UPT_R13(&(r)->regs) +#define PT_REGS_R14(r) UPT_R14(&(r)->regs) +#define PT_REGS_R15(r) UPT_R15(&(r)->regs) + +#define PT_REGS_FS(r) UPT_FS(&(r)->regs) +#define PT_REGS_GS(r) UPT_GS(&(r)->regs) +#define PT_REGS_DS(r) UPT_DS(&(r)->regs) +#define PT_REGS_ES(r) UPT_ES(&(r)->regs) +#define PT_REGS_SS(r) UPT_SS(&(r)->regs) +#define PT_REGS_CS(r) UPT_CS(&(r)->regs) + +#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs) +#define PT_REGS_RIP(r) UPT_IP(&(r)->regs) +#define PT_REGS_RSP(r) UPT_SP(&(r)->regs) + +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) + +/* XXX */ +#define user_mode(r) UPT_IS_USER(&(r)->regs) +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r) +#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r) + +#define PT_FIX_EXEC_STACK(sp) do ; while(0) + +#define profile_pc(regs) PT_REGS_IP(regs) + +struct user_desc; + +static inline int ptrace_get_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc) +{ + return -ENOSYS; +} + +static inline int ptrace_set_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc) +{ + return -ENOSYS; +} + +extern long arch_prctl(struct task_struct *task, int code, + unsigned long __user *addr); +#endif diff --git a/arch/um/sys-x86/asm/vm-flags.h b/arch/um/sys-x86/asm/vm-flags.h new file mode 100644 index 0000000..7c297e9 --- /dev/null +++ b/arch/um/sys-x86/asm/vm-flags.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Copyright 2003 PathScale, Inc. + * Licensed under the GPL + */ + +#ifndef __VM_FLAGS_X86_H +#define __VM_FLAGS_X86_H + +#ifdef CONFIG_X86_32 + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#else + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ + VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif +#endif diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h deleted file mode 100644 index 6c08366..0000000 --- a/arch/um/sys-x86_64/asm/archparam.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_X86_64_H -#define __UM_ARCHPARAM_X86_64_H - - -/* No user-accessible fixmap addresses, i.e. vsyscall */ -#define FIXADDR_USER_START 0 -#define FIXADDR_USER_END 0 - -#endif - diff --git a/arch/um/sys-x86_64/asm/checksum.h b/arch/um/sys-x86_64/asm/checksum.h deleted file mode 100644 index a5be903..0000000 --- a/arch/um/sys-x86_64/asm/checksum.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/string.h" -#include "linux/in6.h" -#include "asm/uaccess.h" - -extern __wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return(csum_partial(dst, len, sum)); -} - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, - int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - return csum_partial(dst, len, sum); -} - -/** - * csum_fold - Fold and invert a 32bit checksum. - * sum: 32bit unfolded sum - * - * Fold a 32bit running checksum to 16bit and invert it. This is usually - * the last step before putting a checksum into a packet. - * Make sure not to mix with 64bit checksums. - */ -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - " addl %1,%0\n" - " adcl $0xffff,%0" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -/** - * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. - * @saddr: source address - * @daddr: destination address - * @len: length of packet - * @proto: ip protocol of packet - * @sum: initial sum to be added in (32bit unfolded) - * - * Returns the pseudo header checksum the input data. Result is - * 32bit unfolded. - */ -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - asm(" addl %1, %0\n" - " adcl %2, %0\n" - " adcl %3, %0\n" - " adcl $0, %0\n" - : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/** - * ip_fast_csum - Compute the IPv4 header checksum efficiently. - * iph: ipv4 header - * ihl: length of header / 4 - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - asm( " movl (%1), %0\n" - " subl $4, %2\n" - " jbe 2f\n" - " addl 4(%1), %0\n" - " adcl 8(%1), %0\n" - " adcl 12(%1), %0\n" - "1: adcl 16(%1), %0\n" - " lea 4(%1), %1\n" - " decl %2\n" - " jne 1b\n" - " adcl $0, %0\n" - " movl %0, %2\n" - " shrl $16, %0\n" - " addw %w2, %w0\n" - " adcl $0, %0\n" - " notl %0\n" - "2:" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -static inline unsigned add32_with_carry(unsigned a, unsigned b) -{ - asm("addl %2,%0\n\t" - "adcl $0,%0" - : "=r" (a) - : "0" (a), "r" (b)); - return a; -} - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#endif diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h deleted file mode 100644 index 11a2bfb..0000000 --- a/arch/um/sys-x86_64/asm/elf.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ -#ifndef __UM_ELF_X86_64_H -#define __UM_ELF_X86_64_H - -#include -#include "skas.h" - -/* x86-64 relocation types, taken from asm-x86_64/elf.h */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ - -#define R_X86_64_NUM 16 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - ((x)->e_machine == EM_X86_64) - -#define ELF_CLASS ELFCLASS64 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_X86_64 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_RBX(regs) = 0; \ - PT_REGS_RCX(regs) = 0; \ - PT_REGS_RDX(regs) = 0; \ - PT_REGS_RSI(regs) = 0; \ - PT_REGS_RDI(regs) = 0; \ - PT_REGS_RBP(regs) = 0; \ - PT_REGS_RAX(regs) = 0; \ - PT_REGS_R8(regs) = 0; \ - PT_REGS_R9(regs) = 0; \ - PT_REGS_R10(regs) = 0; \ - PT_REGS_R11(regs) = 0; \ - PT_REGS_R12(regs) = 0; \ - PT_REGS_R13(regs) = 0; \ - PT_REGS_R14(regs) = 0; \ - PT_REGS_R15(regs) = 0; \ -} while (0) - -#define ELF_CORE_COPY_REGS(pr_reg, _regs) \ - (pr_reg)[0] = (_regs)->regs.gp[0]; \ - (pr_reg)[1] = (_regs)->regs.gp[1]; \ - (pr_reg)[2] = (_regs)->regs.gp[2]; \ - (pr_reg)[3] = (_regs)->regs.gp[3]; \ - (pr_reg)[4] = (_regs)->regs.gp[4]; \ - (pr_reg)[5] = (_regs)->regs.gp[5]; \ - (pr_reg)[6] = (_regs)->regs.gp[6]; \ - (pr_reg)[7] = (_regs)->regs.gp[7]; \ - (pr_reg)[8] = (_regs)->regs.gp[8]; \ - (pr_reg)[9] = (_regs)->regs.gp[9]; \ - (pr_reg)[10] = (_regs)->regs.gp[10]; \ - (pr_reg)[11] = (_regs)->regs.gp[11]; \ - (pr_reg)[12] = (_regs)->regs.gp[12]; \ - (pr_reg)[13] = (_regs)->regs.gp[13]; \ - (pr_reg)[14] = (_regs)->regs.gp[14]; \ - (pr_reg)[15] = (_regs)->regs.gp[15]; \ - (pr_reg)[16] = (_regs)->regs.gp[16]; \ - (pr_reg)[17] = (_regs)->regs.gp[17]; \ - (pr_reg)[18] = (_regs)->regs.gp[18]; \ - (pr_reg)[19] = (_regs)->regs.gp[19]; \ - (pr_reg)[20] = (_regs)->regs.gp[20]; \ - (pr_reg)[21] = current->thread.arch.fs; \ - (pr_reg)[22] = 0; \ - (pr_reg)[23] = 0; \ - (pr_reg)[24] = 0; \ - (pr_reg)[25] = 0; \ - (pr_reg)[26] = 0; - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -#ifdef TIF_IA32 /* XXX */ -#error XXX, indeed - clear_thread_flag(TIF_IA32); -#endif - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -#define ELF_PLATFORM "x86_64" - -#define SET_PERSONALITY(ex) do ; while(0) - -#define __HAVE_ARCH_GATE_AREA 1 -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -struct linux_binprm; -extern int arch_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp); - -extern unsigned long um_vdso_addr; -#define AT_SYSINFO_EHDR 33 -#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) - -#endif diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h deleted file mode 100644 index 8eb79c2..0000000 --- a/arch/um/sys-x86_64/asm/module.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_MODULE_X86_64_H -#define __UM_MODULE_X86_64_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - -#endif - diff --git a/arch/um/sys-x86_64/asm/processor.h b/arch/um/sys-x86_64/asm/processor.h deleted file mode 100644 index 875a26a..0000000 --- a/arch/um/sys-x86_64/asm/processor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_X86_64_H -#define __UM_PROCESSOR_X86_64_H - -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - -struct arch_thread { - unsigned long debugregs[8]; - int debugregs_seq; - unsigned long fs; - struct faultinfo faultinfo; -}; - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .fs = 0, \ - .faultinfo = { 0, 0, 0 } } - -static inline void arch_flush_thread(struct arch_thread *thread) -{ -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - to->fs = from->fs; -} - -#include - -#define current_text_addr() \ - ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 128 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP) - -#include "asm/processor-generic.h" - -#endif diff --git a/arch/um/sys-x86_64/asm/ptrace.h b/arch/um/sys-x86_64/asm/ptrace.h deleted file mode 100644 index 83d8c47..0000000 --- a/arch/um/sys-x86_64/asm/ptrace.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_X86_64_H -#define __UM_PTRACE_X86_64_H - -#include "linux/compiler.h" -#include "asm/errno.h" - -#define __FRAME_OFFSETS /* Needed to get the R* macros */ -#include "asm/ptrace-generic.h" - -#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64 - -#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs) -#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs) -#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs) -#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs) -#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs) -#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs) -#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs) -#define PT_REGS_R8(r) UPT_R8(&(r)->regs) -#define PT_REGS_R9(r) UPT_R9(&(r)->regs) -#define PT_REGS_R10(r) UPT_R10(&(r)->regs) -#define PT_REGS_R11(r) UPT_R11(&(r)->regs) -#define PT_REGS_R12(r) UPT_R12(&(r)->regs) -#define PT_REGS_R13(r) UPT_R13(&(r)->regs) -#define PT_REGS_R14(r) UPT_R14(&(r)->regs) -#define PT_REGS_R15(r) UPT_R15(&(r)->regs) - -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) - -#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs) -#define PT_REGS_RIP(r) UPT_IP(&(r)->regs) -#define PT_REGS_RSP(r) UPT_SP(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -/* XXX */ -#define user_mode(r) UPT_IS_USER(&(r)->regs) -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r) - -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -struct user_desc; - -static inline int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -static inline int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -extern long arch_prctl(struct task_struct *task, int code, - unsigned long __user *addr); -#endif diff --git a/arch/um/sys-x86_64/asm/vm-flags.h b/arch/um/sys-x86_64/asm/vm-flags.h deleted file mode 100644 index 3978e55..0000000 --- a/arch/um/sys-x86_64/asm/vm-flags.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_X86_64_H -#define __VM_FLAGS_X86_64_H - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif -- cgit v1.1 From 858ba94499b4f48e9eb0be7cf0092f1ea9460fef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:09 +0100 Subject: um: merge arch/um/sys-{i386,x86_64}/shared Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 3 +- arch/um/sys-i386/shared/sysdep/archsetjmp.h | 22 --- arch/um/sys-i386/shared/sysdep/barrier.h | 9 -- arch/um/sys-i386/shared/sysdep/faultinfo.h | 29 ---- arch/um/sys-i386/shared/sysdep/host_ldt.h | 34 ----- arch/um/sys-i386/shared/sysdep/kernel-offsets.h | 21 --- arch/um/sys-i386/shared/sysdep/ptrace.h | 116 --------------- arch/um/sys-i386/shared/sysdep/ptrace_user.h | 26 ---- arch/um/sys-i386/shared/sysdep/sigcontext.h | 33 ----- arch/um/sys-i386/shared/sysdep/skas_ptrace.h | 22 --- arch/um/sys-i386/shared/sysdep/stub.h | 100 ------------- arch/um/sys-i386/shared/sysdep/syscalls.h | 20 --- arch/um/sys-i386/shared/sysdep/system.h | 132 ------------------ arch/um/sys-i386/shared/sysdep/tls.h | 32 ----- arch/um/sys-x86/shared/sysdep/archsetjmp.h | 5 + arch/um/sys-x86/shared/sysdep/archsetjmp_32.h | 22 +++ arch/um/sys-x86/shared/sysdep/archsetjmp_64.h | 24 ++++ arch/um/sys-x86/shared/sysdep/barrier.h | 5 + arch/um/sys-x86/shared/sysdep/barrier_32.h | 9 ++ arch/um/sys-x86/shared/sysdep/barrier_64.h | 7 + arch/um/sys-x86/shared/sysdep/faultinfo.h | 5 + arch/um/sys-x86/shared/sysdep/faultinfo_32.h | 29 ++++ arch/um/sys-x86/shared/sysdep/faultinfo_64.h | 29 ++++ arch/um/sys-x86/shared/sysdep/host_ldt.h | 5 + arch/um/sys-x86/shared/sysdep/host_ldt_32.h | 34 +++++ arch/um/sys-x86/shared/sysdep/host_ldt_64.h | 38 +++++ arch/um/sys-x86/shared/sysdep/kernel-offsets.h | 5 + arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h | 21 +++ arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h | 23 +++ arch/um/sys-x86/shared/sysdep/ptrace.h | 5 + arch/um/sys-x86/shared/sysdep/ptrace_32.h | 116 +++++++++++++++ arch/um/sys-x86/shared/sysdep/ptrace_64.h | 163 ++++++++++++++++++++++ arch/um/sys-x86/shared/sysdep/ptrace_user.h | 5 + arch/um/sys-x86/shared/sysdep/ptrace_user_32.h | 26 ++++ arch/um/sys-x86/shared/sysdep/ptrace_user_64.h | 38 +++++ arch/um/sys-x86/shared/sysdep/sigcontext.h | 5 + arch/um/sys-x86/shared/sysdep/sigcontext_32.h | 33 +++++ arch/um/sys-x86/shared/sysdep/sigcontext_64.h | 33 +++++ arch/um/sys-x86/shared/sysdep/skas_ptrace.h | 5 + arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h | 22 +++ arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h | 22 +++ arch/um/sys-x86/shared/sysdep/stub.h | 5 + arch/um/sys-x86/shared/sysdep/stub_32.h | 100 +++++++++++++ arch/um/sys-x86/shared/sysdep/stub_64.h | 106 ++++++++++++++ arch/um/sys-x86/shared/sysdep/syscalls.h | 5 + arch/um/sys-x86/shared/sysdep/syscalls_32.h | 20 +++ arch/um/sys-x86/shared/sysdep/syscalls_64.h | 32 +++++ arch/um/sys-x86/shared/sysdep/system.h | 132 ++++++++++++++++++ arch/um/sys-x86/shared/sysdep/tls.h | 5 + arch/um/sys-x86/shared/sysdep/tls_32.h | 32 +++++ arch/um/sys-x86/shared/sysdep/tls_64.h | 29 ++++ arch/um/sys-x86_64/shared/sysdep/archsetjmp.h | 24 ---- arch/um/sys-x86_64/shared/sysdep/barrier.h | 7 - arch/um/sys-x86_64/shared/sysdep/faultinfo.h | 29 ---- arch/um/sys-x86_64/shared/sysdep/host_ldt.h | 38 ----- arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h | 23 --- arch/um/sys-x86_64/shared/sysdep/ptrace.h | 163 ---------------------- arch/um/sys-x86_64/shared/sysdep/ptrace_user.h | 38 ----- arch/um/sys-x86_64/shared/sysdep/sigcontext.h | 33 ----- arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h | 22 --- arch/um/sys-x86_64/shared/sysdep/stub.h | 106 -------------- arch/um/sys-x86_64/shared/sysdep/syscalls.h | 32 ----- arch/um/sys-x86_64/shared/sysdep/system.h | 132 ------------------ arch/um/sys-x86_64/shared/sysdep/tls.h | 29 ---- 64 files changed, 1201 insertions(+), 1274 deletions(-) delete mode 100644 arch/um/sys-i386/shared/sysdep/archsetjmp.h delete mode 100644 arch/um/sys-i386/shared/sysdep/barrier.h delete mode 100644 arch/um/sys-i386/shared/sysdep/faultinfo.h delete mode 100644 arch/um/sys-i386/shared/sysdep/host_ldt.h delete mode 100644 arch/um/sys-i386/shared/sysdep/kernel-offsets.h delete mode 100644 arch/um/sys-i386/shared/sysdep/ptrace.h delete mode 100644 arch/um/sys-i386/shared/sysdep/ptrace_user.h delete mode 100644 arch/um/sys-i386/shared/sysdep/sigcontext.h delete mode 100644 arch/um/sys-i386/shared/sysdep/skas_ptrace.h delete mode 100644 arch/um/sys-i386/shared/sysdep/stub.h delete mode 100644 arch/um/sys-i386/shared/sysdep/syscalls.h delete mode 100644 arch/um/sys-i386/shared/sysdep/system.h delete mode 100644 arch/um/sys-i386/shared/sysdep/tls.h create mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp.h create mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/barrier.h create mode 100644 arch/um/sys-x86/shared/sysdep/barrier_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/barrier_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo.h create mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt.h create mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets.h create mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext.h create mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace.h create mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/stub.h create mode 100644 arch/um/sys-x86/shared/sysdep/stub_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/stub_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/syscalls.h create mode 100644 arch/um/sys-x86/shared/sysdep/syscalls_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/syscalls_64.h create mode 100644 arch/um/sys-x86/shared/sysdep/system.h create mode 100644 arch/um/sys-x86/shared/sysdep/tls.h create mode 100644 arch/um/sys-x86/shared/sysdep/tls_32.h create mode 100644 arch/um/sys-x86/shared/sysdep/tls_64.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/archsetjmp.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/barrier.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/faultinfo.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/host_ldt.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/ptrace.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/ptrace_user.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/sigcontext.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/stub.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/syscalls.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/system.h delete mode 100644 arch/um/sys-x86_64/shared/sysdep/tls.h (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index c121870..184494d 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -25,9 +25,8 @@ include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) -ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared +ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(HEADER_ARCH)/shared KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(HEADER_ARCH) -KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so # named - it's a common symbol in libpcap, so we get a binary which crashes. diff --git a/arch/um/sys-i386/shared/sysdep/archsetjmp.h b/arch/um/sys-i386/shared/sysdep/archsetjmp.h deleted file mode 100644 index 0f31208..0000000 --- a/arch/um/sys-i386/shared/sysdep/archsetjmp.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/um/include/sysdep-i386/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int __ebx; - unsigned int __esp; - unsigned int __ebp; - unsigned int __esi; - unsigned int __edi; - unsigned int __eip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __eip -#define JB_SP __esp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-i386/shared/sysdep/barrier.h b/arch/um/sys-i386/shared/sysdep/barrier.h deleted file mode 100644 index b58d52c..0000000 --- a/arch/um/sys-i386/shared/sysdep/barrier.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYSDEP_I386_BARRIER_H -#define __SYSDEP_I386_BARRIER_H - -/* Copied from include/asm-i386 for use by userspace. i386 has the option - * of using mfence, but I'm just using this, which works everywhere, for now. - */ -#define mb() asm volatile("lock; addl $0,0(%esp)") - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/faultinfo.h b/arch/um/sys-i386/shared/sysdep/faultinfo.h deleted file mode 100644 index db437cc..0000000 --- a/arch/um/sys-i386/shared/sysdep/faultinfo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Author: Bodo Stroesser - * Licensed under the GPL - */ - -#ifndef __FAULTINFO_I386_H -#define __FAULTINFO_I386_H - -/* this structure contains the full arch-specific faultinfo - * from the traps. - * On i386, ptrace_faultinfo unfortunately doesn't provide - * all the info, since trap_no is missing. - * All common elements are defined at the same position in - * both structures, thus making it easy to copy the - * contents without knowledge about the structure elements. - */ -struct faultinfo { - int error_code; /* in ptrace_faultinfo misleadingly called is_write */ - unsigned long cr2; /* in ptrace_faultinfo called addr */ - int trap_no; /* missing in ptrace_faultinfo */ -}; - -#define FAULT_WRITE(fi) ((fi).error_code & 2) -#define FAULT_ADDRESS(fi) ((fi).cr2) - -#define PTRACE_FULL_FAULTINFO 0 - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/host_ldt.h b/arch/um/sys-i386/shared/sysdep/host_ldt.h deleted file mode 100644 index 0953cc4..0000000 --- a/arch/um/sys-i386/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ASM_HOST_LDT_I386_H -#define __ASM_HOST_LDT_I386_H - -#include - -/* - * macros stolen from include/asm-i386/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h b/arch/um/sys-i386/shared/sysdep/kernel-offsets.h deleted file mode 100644 index 5868526..0000000 --- a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define STR(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include -} diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h deleted file mode 100644 index 6096c8f..0000000 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_H -#define __SYSDEP_I386_PTRACE_H - -#include -#include "sysdep/faultinfo.h" - -#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) -#define MAX_REG_OFFSET (UM_FRAME_SIZE) - -static inline void update_debugregs(int seq) {} - -/* syscall emulation path in ptrace */ - -#ifndef PTRACE_SYSEMU -#define PTRACE_SYSEMU 31 -#endif - -void set_using_sysemu(int value); -int get_using_sysemu(void); -extern int sysemu_supported; - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_EAX(r) ((r)[HOST_EAX]) -#define REGS_EBX(r) ((r)[HOST_EBX]) -#define REGS_ECX(r) ((r)[HOST_ECX]) -#define REGS_EDX(r) ((r)[HOST_EDX]) -#define REGS_ESI(r) ((r)[HOST_ESI]) -#define REGS_EDI(r) ((r)[HOST_EDI]) -#define REGS_EBP(r) ((r)[HOST_EBP]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_SS(r) ((r)[HOST_SS]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) - -#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) - -#ifndef PTRACE_SYSEMU_SINGLESTEP -#define PTRACE_SYSEMU_SINGLESTEP 32 -#endif - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FPX_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_EAX(r) REGS_EAX((r)->gp) -#define UPT_EBX(r) REGS_EBX((r)->gp) -#define UPT_ECX(r) REGS_ECX((r)->gp) -#define UPT_EDX(r) REGS_EDX((r)->gp) -#define UPT_ESI(r) REGS_ESI((r)->gp) -#define UPT_EDI(r) REGS_EDI((r)->gp) -#define UPT_EBP(r) REGS_EBP((r)->gp) -#define UPT_ORIG_EAX(r) ((r)->syscall) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) - -#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) -#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) -#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) -#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) -#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) -#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) -#define UPT_SYSCALL_RET(r) UPT_EAX(r) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -extern void arch_init_registers(int pid); - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/ptrace_user.h b/arch/um/sys-i386/shared/sysdep/ptrace_user.h deleted file mode 100644 index 9d88a79..0000000 --- a/arch/um/sys-i386/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_USER_H__ -#define __SYSDEP_I386_PTRACE_USER_H__ - -#include -#include -#include -#include - -#define PT_OFFSET(r) ((r) * sizeof(long)) - -#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) -#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) - -#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) - -#define REGS_IP_INDEX EIP -#define REGS_SP_INDEX UESP - -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sigcontext.h b/arch/um/sys-i386/shared/sysdep/sigcontext.h deleted file mode 100644 index 3827864..0000000 --- a/arch/um/sys-i386/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_I386_H -#define __SYS_SIGCONTEXT_I386_H - -#include - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h b/arch/um/sys-i386/shared/sysdep/skas_ptrace.h deleted file mode 100644 index e27b8a7..0000000 --- a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_SKAS_PTRACE_H -#define __SYSDEP_I386_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/stub.h b/arch/um/sys-i386/shared/sysdep/stub.h deleted file mode 100644 index cca14d4..0000000 --- a/arch/um/sys-i386/shared/sysdep/stub.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include -#include -#include -#include "as-layout.h" -#include "stub-data.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); - -#define STUB_SYSCALL_RET EAX -#define STUB_MMAP_NR __NR_mmap2 -#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); - - return ret; -} - -static inline long stub_syscall1(long syscall, long arg1) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2)); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3)); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4)); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(int fd, unsigned long offset) -{ - __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" - "movl %7, %%ebx ; movl %%eax, (%%ebx)" - : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), - "c" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED), "D" (fd), - "a" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : "memory"); -} - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h deleted file mode 100644 index 05cb796..0000000 --- a/arch/um/sys-i386/shared/sysdep/syscalls.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "asm/unistd.h" -#include "sysdep/ptrace.h" - -typedef long syscall_handler_t(struct pt_regs); - -/* Not declared on x86, incompatible declarations on x86_64, so these have - * to go here rather than in sys_call_table.c - */ -extern syscall_handler_t sys_rt_sigaction; - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - ((long (*)(struct syscall_args)) \ - (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) diff --git a/arch/um/sys-i386/shared/sysdep/system.h b/arch/um/sys-i386/shared/sysdep/system.h deleted file mode 100644 index d1b93c4..0000000 --- a/arch/um/sys-i386/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include -#include -#include -#include -#include - -#include -#include - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/tls.h b/arch/um/sys-i386/shared/sysdep/tls.h deleted file mode 100644 index 3455075..0000000 --- a/arch/um/sys-i386/shared/sysdep/tls.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ - -#define GDT_ENTRY_TLS_MIN_I386 6 -#define GDT_ENTRY_TLS_MIN_X86_64 12 - -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp.h b/arch/um/sys-x86/shared/sysdep/archsetjmp.h new file mode 100644 index 0000000..ff7766d --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/archsetjmp.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "archsetjmp_32.h" +#else +#include "archsetjmp_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h b/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h new file mode 100644 index 0000000..0f31208 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h @@ -0,0 +1,22 @@ +/* + * arch/um/include/sysdep-i386/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int __ebx; + unsigned int __esp; + unsigned int __ebp; + unsigned int __esi; + unsigned int __edi; + unsigned int __eip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#define JB_IP __eip +#define JB_SP __esp + +#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h b/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h new file mode 100644 index 0000000..2af8f12 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h @@ -0,0 +1,24 @@ +/* + * arch/um/include/sysdep-x86_64/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __rbx; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#define JB_IP __rip +#define JB_SP __rsp + +#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86/shared/sysdep/barrier.h b/arch/um/sys-x86/shared/sysdep/barrier.h new file mode 100644 index 0000000..89ee23b --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/barrier.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "barrier_32.h" +#else +#include "barrier_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/barrier_32.h b/arch/um/sys-x86/shared/sysdep/barrier_32.h new file mode 100644 index 0000000..b58d52c --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/barrier_32.h @@ -0,0 +1,9 @@ +#ifndef __SYSDEP_I386_BARRIER_H +#define __SYSDEP_I386_BARRIER_H + +/* Copied from include/asm-i386 for use by userspace. i386 has the option + * of using mfence, but I'm just using this, which works everywhere, for now. + */ +#define mb() asm volatile("lock; addl $0,0(%esp)") + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/barrier_64.h b/arch/um/sys-x86/shared/sysdep/barrier_64.h new file mode 100644 index 0000000..7b610be --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/barrier_64.h @@ -0,0 +1,7 @@ +#ifndef __SYSDEP_X86_64_BARRIER_H +#define __SYSDEP_X86_64_BARRIER_H + +/* Copied from include/asm-x86_64 for use by userspace. */ +#define mb() asm volatile("mfence":::"memory") + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo.h b/arch/um/sys-x86/shared/sysdep/faultinfo.h new file mode 100644 index 0000000..862ecb1 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/faultinfo.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "faultinfo_32.h" +#else +#include "faultinfo_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_32.h b/arch/um/sys-x86/shared/sysdep/faultinfo_32.h new file mode 100644 index 0000000..db437cc --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/faultinfo_32.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH + * Author: Bodo Stroesser + * Licensed under the GPL + */ + +#ifndef __FAULTINFO_I386_H +#define __FAULTINFO_I386_H + +/* this structure contains the full arch-specific faultinfo + * from the traps. + * On i386, ptrace_faultinfo unfortunately doesn't provide + * all the info, since trap_no is missing. + * All common elements are defined at the same position in + * both structures, thus making it easy to copy the + * contents without knowledge about the structure elements. + */ +struct faultinfo { + int error_code; /* in ptrace_faultinfo misleadingly called is_write */ + unsigned long cr2; /* in ptrace_faultinfo called addr */ + int trap_no; /* missing in ptrace_faultinfo */ +}; + +#define FAULT_WRITE(fi) ((fi).error_code & 2) +#define FAULT_ADDRESS(fi) ((fi).cr2) + +#define PTRACE_FULL_FAULTINFO 0 + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_64.h b/arch/um/sys-x86/shared/sysdep/faultinfo_64.h new file mode 100644 index 0000000..cb917b0 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/faultinfo_64.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH + * Author: Bodo Stroesser + * Licensed under the GPL + */ + +#ifndef __FAULTINFO_X86_64_H +#define __FAULTINFO_X86_64_H + +/* this structure contains the full arch-specific faultinfo + * from the traps. + * On i386, ptrace_faultinfo unfortunately doesn't provide + * all the info, since trap_no is missing. + * All common elements are defined at the same position in + * both structures, thus making it easy to copy the + * contents without knowledge about the structure elements. + */ +struct faultinfo { + int error_code; /* in ptrace_faultinfo misleadingly called is_write */ + unsigned long cr2; /* in ptrace_faultinfo called addr */ + int trap_no; /* missing in ptrace_faultinfo */ +}; + +#define FAULT_WRITE(fi) ((fi).error_code & 2) +#define FAULT_ADDRESS(fi) ((fi).cr2) + +#define PTRACE_FULL_FAULTINFO 1 + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt.h b/arch/um/sys-x86/shared/sysdep/host_ldt.h new file mode 100644 index 0000000..94518b3 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/host_ldt.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "host_ldt_32.h" +#else +#include "host_ldt_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt_32.h b/arch/um/sys-x86/shared/sysdep/host_ldt_32.h new file mode 100644 index 0000000..0953cc4 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/host_ldt_32.h @@ -0,0 +1,34 @@ +#ifndef __ASM_HOST_LDT_I386_H +#define __ASM_HOST_LDT_I386_H + +#include + +/* + * macros stolen from include/asm-i386/desc.h + */ +#define LDT_entry_a(info) \ + ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) + +#define LDT_entry_b(info) \ + (((info)->base_addr & 0xff000000) | \ + (((info)->base_addr & 0x00ff0000) >> 16) | \ + ((info)->limit & 0xf0000) | \ + (((info)->read_exec_only ^ 1) << 9) | \ + ((info)->contents << 10) | \ + (((info)->seg_not_present ^ 1) << 15) | \ + ((info)->seg_32bit << 22) | \ + ((info)->limit_in_pages << 23) | \ + ((info)->useable << 20) | \ + 0x7000) + +#define LDT_empty(info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0 ) + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt_64.h b/arch/um/sys-x86/shared/sysdep/host_ldt_64.h new file mode 100644 index 0000000..e8b1be1 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/host_ldt_64.h @@ -0,0 +1,38 @@ +#ifndef __ASM_HOST_LDT_X86_64_H +#define __ASM_HOST_LDT_X86_64_H + +#include + +/* + * macros stolen from include/asm-x86_64/desc.h + */ +#define LDT_entry_a(info) \ + ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) + +/* Don't allow setting of the lm bit. It is useless anyways because + * 64bit system calls require __USER_CS. */ +#define LDT_entry_b(info) \ + (((info)->base_addr & 0xff000000) | \ + (((info)->base_addr & 0x00ff0000) >> 16) | \ + ((info)->limit & 0xf0000) | \ + (((info)->read_exec_only ^ 1) << 9) | \ + ((info)->contents << 10) | \ + (((info)->seg_not_present ^ 1) << 15) | \ + ((info)->seg_32bit << 22) | \ + ((info)->limit_in_pages << 23) | \ + ((info)->useable << 20) | \ + /* ((info)->lm << 21) | */ \ + 0x7000) + +#define LDT_empty(info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0 && \ + (info)->lm == 0) + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets.h new file mode 100644 index 0000000..346bc08 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/kernel-offsets.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "kernel-offsets_32.h" +#else +#include "kernel-offsets_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h new file mode 100644 index 0000000..5868526 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define STR(x) #x +#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) + +#define BLANK() asm volatile("\n->" : : ) + +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)); + +void foo(void) +{ +#include +} diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h new file mode 100644 index 0000000..a307237 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define DEFINE_STR1(x) #x +#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) + +#define BLANK() asm volatile("\n->" : : ) + +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)); + +void foo(void) +{ +#include +} diff --git a/arch/um/sys-x86/shared/sysdep/ptrace.h b/arch/um/sys-x86/shared/sysdep/ptrace.h new file mode 100644 index 0000000..711b162 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "ptrace_32.h" +#else +#include "ptrace_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_32.h b/arch/um/sys-x86/shared/sysdep/ptrace_32.h new file mode 100644 index 0000000..6096c8f --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace_32.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_I386_PTRACE_H +#define __SYSDEP_I386_PTRACE_H + +#include +#include "sysdep/faultinfo.h" + +#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) +#define MAX_REG_OFFSET (UM_FRAME_SIZE) + +static inline void update_debugregs(int seq) {} + +/* syscall emulation path in ptrace */ + +#ifndef PTRACE_SYSEMU +#define PTRACE_SYSEMU 31 +#endif + +void set_using_sysemu(int value); +int get_using_sysemu(void); +extern int sysemu_supported; + +#define REGS_IP(r) ((r)[HOST_IP]) +#define REGS_SP(r) ((r)[HOST_SP]) +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) +#define REGS_EAX(r) ((r)[HOST_EAX]) +#define REGS_EBX(r) ((r)[HOST_EBX]) +#define REGS_ECX(r) ((r)[HOST_ECX]) +#define REGS_EDX(r) ((r)[HOST_EDX]) +#define REGS_ESI(r) ((r)[HOST_ESI]) +#define REGS_EDI(r) ((r)[HOST_EDI]) +#define REGS_EBP(r) ((r)[HOST_EBP]) +#define REGS_CS(r) ((r)[HOST_CS]) +#define REGS_SS(r) ((r)[HOST_SS]) +#define REGS_DS(r) ((r)[HOST_DS]) +#define REGS_ES(r) ((r)[HOST_ES]) +#define REGS_FS(r) ((r)[HOST_FS]) +#define REGS_GS(r) ((r)[HOST_GS]) + +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) + +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) + +#ifndef PTRACE_SYSEMU_SINGLESTEP +#define PTRACE_SYSEMU_SINGLESTEP 32 +#endif + +struct uml_pt_regs { + unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FPX_SIZE]; + struct faultinfo faultinfo; + long syscall; + int is_user; +}; + +#define EMPTY_UML_PT_REGS { } + +#define UPT_IP(r) REGS_IP((r)->gp) +#define UPT_SP(r) REGS_SP((r)->gp) +#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) +#define UPT_EAX(r) REGS_EAX((r)->gp) +#define UPT_EBX(r) REGS_EBX((r)->gp) +#define UPT_ECX(r) REGS_ECX((r)->gp) +#define UPT_EDX(r) REGS_EDX((r)->gp) +#define UPT_ESI(r) REGS_ESI((r)->gp) +#define UPT_EDI(r) REGS_EDI((r)->gp) +#define UPT_EBP(r) REGS_EBP((r)->gp) +#define UPT_ORIG_EAX(r) ((r)->syscall) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_SS(r) REGS_SS((r)->gp) +#define UPT_DS(r) REGS_DS((r)->gp) +#define UPT_ES(r) REGS_ES((r)->gp) +#define UPT_FS(r) REGS_FS((r)->gp) +#define UPT_GS(r) REGS_GS((r)->gp) + +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) + +extern int user_context(unsigned long sp); + +#define UPT_IS_USER(r) ((r)->is_user) + +struct syscall_args { + unsigned long args[6]; +}; + +#define SYSCALL_ARGS(r) ((struct syscall_args) \ + { .args = { UPT_SYSCALL_ARG1(r), \ + UPT_SYSCALL_ARG2(r), \ + UPT_SYSCALL_ARG3(r), \ + UPT_SYSCALL_ARG4(r), \ + UPT_SYSCALL_ARG5(r), \ + UPT_SYSCALL_ARG6(r) } } ) + +#define UPT_SET_SYSCALL_RETURN(r, res) \ + REGS_SET_SYSCALL_RETURN((r)->regs, (res)) + +#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) + +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) +#define UPT_SYSCALL_RET(r) UPT_EAX(r) + +#define UPT_FAULTINFO(r) (&(r)->faultinfo) + +extern void arch_init_registers(int pid); + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_64.h b/arch/um/sys-x86/shared/sysdep/ptrace_64.h new file mode 100644 index 0000000..9ed4597 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace_64.h @@ -0,0 +1,163 @@ +/* + * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_PTRACE_H +#define __SYSDEP_X86_64_PTRACE_H + +#include +#include "sysdep/faultinfo.h" + +#define MAX_REG_OFFSET (UM_FRAME_SIZE) +#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) + +#define REGS_IP(r) ((r)[HOST_IP]) +#define REGS_SP(r) ((r)[HOST_SP]) + +#define REGS_RBX(r) ((r)[HOST_RBX]) +#define REGS_RCX(r) ((r)[HOST_RCX]) +#define REGS_RDX(r) ((r)[HOST_RDX]) +#define REGS_RSI(r) ((r)[HOST_RSI]) +#define REGS_RDI(r) ((r)[HOST_RDI]) +#define REGS_RBP(r) ((r)[HOST_RBP]) +#define REGS_RAX(r) ((r)[HOST_RAX]) +#define REGS_R8(r) ((r)[HOST_R8]) +#define REGS_R9(r) ((r)[HOST_R9]) +#define REGS_R10(r) ((r)[HOST_R10]) +#define REGS_R11(r) ((r)[HOST_R11]) +#define REGS_R12(r) ((r)[HOST_R12]) +#define REGS_R13(r) ((r)[HOST_R13]) +#define REGS_R14(r) ((r)[HOST_R14]) +#define REGS_R15(r) ((r)[HOST_R15]) +#define REGS_CS(r) ((r)[HOST_CS]) +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) +#define REGS_SS(r) ((r)[HOST_SS]) + +#define HOST_FS_BASE 21 +#define HOST_GS_BASE 22 +#define HOST_DS 23 +#define HOST_ES 24 +#define HOST_FS 25 +#define HOST_GS 26 + +/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these + * are already defined for kernel code, but not for userspace code. + */ +#ifndef FS_BASE +/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, + * which is what x86_64 ptrace actually uses. + */ +#define FS_BASE (HOST_FS_BASE * sizeof(long)) +#define GS_BASE (HOST_GS_BASE * sizeof(long)) +#define DS (HOST_DS * sizeof(long)) +#define ES (HOST_ES * sizeof(long)) +#define FS (HOST_FS * sizeof(long)) +#define GS (HOST_GS * sizeof(long)) +#endif + +#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) +#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) +#define REGS_DS(r) ((r)[HOST_DS]) +#define REGS_ES(r) ((r)[HOST_ES]) +#define REGS_FS(r) ((r)[HOST_FS]) +#define REGS_GS(r) ((r)[HOST_GS]) + +#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX]) + +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) + +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) + +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) + +#define REGS_FAULT_ADDR(r) ((r)->fault_addr) + +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) + +#define REGS_TRAP(r) ((r)->trap_type) + +#define REGS_ERR(r) ((r)->fault_type) + +struct uml_pt_regs { + unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FP_SIZE]; + struct faultinfo faultinfo; + long syscall; + int is_user; +}; + +#define EMPTY_UML_PT_REGS { } + +#define UPT_RBX(r) REGS_RBX((r)->gp) +#define UPT_RCX(r) REGS_RCX((r)->gp) +#define UPT_RDX(r) REGS_RDX((r)->gp) +#define UPT_RSI(r) REGS_RSI((r)->gp) +#define UPT_RDI(r) REGS_RDI((r)->gp) +#define UPT_RBP(r) REGS_RBP((r)->gp) +#define UPT_RAX(r) REGS_RAX((r)->gp) +#define UPT_R8(r) REGS_R8((r)->gp) +#define UPT_R9(r) REGS_R9((r)->gp) +#define UPT_R10(r) REGS_R10((r)->gp) +#define UPT_R11(r) REGS_R11((r)->gp) +#define UPT_R12(r) REGS_R12((r)->gp) +#define UPT_R13(r) REGS_R13((r)->gp) +#define UPT_R14(r) REGS_R14((r)->gp) +#define UPT_R15(r) REGS_R15((r)->gp) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp) +#define UPT_FS(r) REGS_FS((r)->gp) +#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp) +#define UPT_GS(r) REGS_GS((r)->gp) +#define UPT_DS(r) REGS_DS((r)->gp) +#define UPT_ES(r) REGS_ES((r)->gp) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_SS(r) REGS_SS((r)->gp) +#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp) + +#define UPT_IP(r) REGS_IP((r)->gp) +#define UPT_SP(r) REGS_SP((r)->gp) + +#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) +#define UPT_SYSCALL_NR(r) ((r)->syscall) +#define UPT_SYSCALL_RET(r) UPT_RAX(r) + +extern int user_context(unsigned long sp); + +#define UPT_IS_USER(r) ((r)->is_user) + +#define UPT_SYSCALL_ARG1(r) UPT_RDI(r) +#define UPT_SYSCALL_ARG2(r) UPT_RSI(r) +#define UPT_SYSCALL_ARG3(r) UPT_RDX(r) +#define UPT_SYSCALL_ARG4(r) UPT_R10(r) +#define UPT_SYSCALL_ARG5(r) UPT_R8(r) +#define UPT_SYSCALL_ARG6(r) UPT_R9(r) + +struct syscall_args { + unsigned long args[6]; +}; + +#define SYSCALL_ARGS(r) ((struct syscall_args) \ + { .args = { UPT_SYSCALL_ARG1(r), \ + UPT_SYSCALL_ARG2(r), \ + UPT_SYSCALL_ARG3(r), \ + UPT_SYSCALL_ARG4(r), \ + UPT_SYSCALL_ARG5(r), \ + UPT_SYSCALL_ARG6(r) } } ) + +#define UPT_SET_SYSCALL_RETURN(r, res) \ + REGS_SET_SYSCALL_RETURN((r)->regs, (res)) + +#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) + +#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) + +#define UPT_FAULTINFO(r) (&(r)->faultinfo) + +static inline void arch_init_registers(int pid) +{ +} + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user.h b/arch/um/sys-x86/shared/sysdep/ptrace_user.h new file mode 100644 index 0000000..a92f883 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace_user.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "ptrace_user_32.h" +#else +#include "ptrace_user_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h b/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h new file mode 100644 index 0000000..9d88a79 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_I386_PTRACE_USER_H__ +#define __SYSDEP_I386_PTRACE_USER_H__ + +#include +#include +#include +#include + +#define PT_OFFSET(r) ((r) * sizeof(long)) + +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) + +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) + +#define REGS_IP_INDEX EIP +#define REGS_SP_INDEX UESP + +#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h b/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h new file mode 100644 index 0000000..2f1b6e3 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h @@ -0,0 +1,38 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_PTRACE_USER_H__ +#define __SYSDEP_X86_64_PTRACE_USER_H__ + +#define __FRAME_OFFSETS +#include +#include +#include +#undef __FRAME_OFFSETS +#include + +#define PT_INDEX(off) ((off) / sizeof(unsigned long)) + +#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) +#define PT_SYSCALL_NR_OFFSET (ORIG_RAX) + +#define PT_SYSCALL_RET_OFFSET (RAX) + +/* + * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though + * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the + * 2.4 name and value for 2.4 host compatibility. + */ +#ifndef PTRACE_OLDSETOPTIONS +#define PTRACE_OLDSETOPTIONS 21 +#endif + +#define REGS_IP_INDEX PT_INDEX(RIP) +#define REGS_SP_INDEX PT_INDEX(RSP) + +#define FP_SIZE (HOST_FP_SIZE) + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext.h b/arch/um/sys-x86/shared/sysdep/sigcontext.h new file mode 100644 index 0000000..f7f49f4 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/sigcontext.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "sigcontext_32.h" +#else +#include "sigcontext_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h new file mode 100644 index 0000000..3827864 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYS_SIGCONTEXT_I386_H +#define __SYS_SIGCONTEXT_I386_H + +#include + +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) + +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) + +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) + +#define GET_FAULTINFO_FROM_SC(fi, sc) \ + { \ + (fi).cr2 = SC_CR2(sc); \ + (fi).error_code = SC_ERR(sc); \ + (fi).trap_no = SC_TRAPNO(sc); \ + } + +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ +#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h new file mode 100644 index 0000000..9fb5277 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h @@ -0,0 +1,33 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_SIGCONTEXT_H +#define __SYSDEP_X86_64_SIGCONTEXT_H + +#include + +#define SC_OFFSET(sc, field) \ + *((unsigned long *) &(((char *) (sc))[HOST_##field])) +#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) +#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) +#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) + +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) + +#define GET_FAULTINFO_FROM_SC(fi, sc) \ + { \ + (fi).cr2 = SC_CR2(sc); \ + (fi).error_code = SC_ERR(sc); \ + (fi).trap_no = SC_TRAPNO(sc); \ + } + +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* No broken SKAS API, which doesn't pass trap_no, here. */ +#define SEGV_MAYBE_FIXABLE(fi) 0 + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace.h new file mode 100644 index 0000000..e63b575 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/skas_ptrace.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "skas_ptrace_32.h" +#else +#include "skas_ptrace_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h new file mode 100644 index 0000000..e27b8a7 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_I386_SKAS_PTRACE_H +#define __SYSDEP_I386_SKAS_PTRACE_H + +struct ptrace_faultinfo { + int is_write; + unsigned long addr; +}; + +struct ptrace_ldt { + int func; + void *ptr; + unsigned long bytecount; +}; + +#define PTRACE_LDT 54 + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h new file mode 100644 index 0000000..95db4be7 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H +#define __SYSDEP_X86_64_SKAS_PTRACE_H + +struct ptrace_faultinfo { + int is_write; + unsigned long addr; +}; + +struct ptrace_ldt { + int func; + void *ptr; + unsigned long bytecount; +}; + +#define PTRACE_LDT 54 + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/stub.h b/arch/um/sys-x86/shared/sysdep/stub.h new file mode 100644 index 0000000..13f523a --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/stub.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "stub_32.h" +#else +#include "stub_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/stub_32.h b/arch/um/sys-x86/shared/sysdep/stub_32.h new file mode 100644 index 0000000..cca14d4 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/stub_32.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include +#include +#include +#include "as-layout.h" +#include "stub-data.h" + +extern void stub_segv_handler(int sig); +extern void stub_clone_handler(void); + +#define STUB_SYSCALL_RET EAX +#define STUB_MMAP_NR __NR_mmap2 +#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) + +static inline long stub_syscall0(long syscall) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); + + return ret; +} + +static inline long stub_syscall1(long syscall, long arg1) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); + + return ret; +} + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), + "c" (arg2)); + + return ret; +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), + "c" (arg2), "d" (arg3)); + + return ret; +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, + long arg4) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), + "c" (arg2), "d" (arg3), "S" (arg4)); + + return ret; +} + +static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, + long arg4, long arg5) +{ + long ret; + + __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), + "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)); + + return ret; +} + +static inline void trap_myself(void) +{ + __asm("int3"); +} + +static inline void remap_stack(int fd, unsigned long offset) +{ + __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" + "movl %7, %%ebx ; movl %%eax, (%%ebx)" + : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), + "c" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "S" (MAP_FIXED | MAP_SHARED), "D" (fd), + "a" (offset), + "i" (&((struct stub_data *) STUB_DATA)->err) + : "memory"); +} + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/stub_64.h b/arch/um/sys-x86/shared/sysdep/stub_64.h new file mode 100644 index 0000000..922a570 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/stub_64.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include +#include +#include +#include "as-layout.h" +#include "stub-data.h" + +extern void stub_segv_handler(int sig); +extern void stub_clone_handler(void); + +#define STUB_SYSCALL_RET PT_INDEX(RAX) +#define STUB_MMAP_NR __NR_mmap +#define MMAP_OFFSET(o) (o) + +#define __syscall_clobber "r11","rcx","memory" +#define __syscall "syscall" + +static inline long stub_syscall0(long syscall) +{ + long ret; + + __asm__ volatile (__syscall + : "=a" (ret) + : "0" (syscall) : __syscall_clobber ); + + return ret; +} + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ + long ret; + + __asm__ volatile (__syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber ); + + return ret; +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ + long ret; + + __asm__ volatile (__syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3) + : __syscall_clobber ); + + return ret; +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, + long arg4) +{ + long ret; + + __asm__ volatile ("movq %5,%%r10 ; " __syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), + "g" (arg4) + : __syscall_clobber, "r10" ); + + return ret; +} + +static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, + long arg4, long arg5) +{ + long ret; + + __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), + "g" (arg4), "g" (arg5) + : __syscall_clobber, "r10", "r8" ); + + return ret; +} + +static inline void trap_myself(void) +{ + __asm("int3"); +} + +static inline void remap_stack(long fd, unsigned long offset) +{ + __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " + "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " + "movq %%rax, (%%rbx)": + : "a" (STUB_MMAP_NR), "D" (STUB_DATA), + "S" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "g" (MAP_FIXED | MAP_SHARED), "g" (fd), + "g" (offset), + "i" (&((struct stub_data *) STUB_DATA)->err) + : __syscall_clobber, "r10", "r8", "r9" ); +} + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/syscalls.h b/arch/um/sys-x86/shared/sysdep/syscalls.h new file mode 100644 index 0000000..bd9a89b --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/syscalls.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "syscalls_32.h" +#else +#include "syscalls_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/syscalls_32.h b/arch/um/sys-x86/shared/sysdep/syscalls_32.h new file mode 100644 index 0000000..05cb796 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/syscalls_32.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include "asm/unistd.h" +#include "sysdep/ptrace.h" + +typedef long syscall_handler_t(struct pt_regs); + +/* Not declared on x86, incompatible declarations on x86_64, so these have + * to go here rather than in sys_call_table.c + */ +extern syscall_handler_t sys_rt_sigaction; + +extern syscall_handler_t *sys_call_table[]; + +#define EXECUTE_SYSCALL(syscall, regs) \ + ((long (*)(struct syscall_args)) \ + (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) diff --git a/arch/um/sys-x86/shared/sysdep/syscalls_64.h b/arch/um/sys-x86/shared/sysdep/syscalls_64.h new file mode 100644 index 0000000..8a7d5e1 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/syscalls_64.h @@ -0,0 +1,32 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_SYSCALLS_H__ +#define __SYSDEP_X86_64_SYSCALLS_H__ + +#include +#include + +typedef long syscall_handler_t(void); + +extern syscall_handler_t *sys_call_table[]; + +#define EXECUTE_SYSCALL(syscall, regs) \ + (((long (*)(long, long, long, long, long, long)) \ + (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ + UPT_SYSCALL_ARG2(®s->regs), \ + UPT_SYSCALL_ARG3(®s->regs), \ + UPT_SYSCALL_ARG4(®s->regs), \ + UPT_SYSCALL_ARG5(®s->regs), \ + UPT_SYSCALL_ARG6(®s->regs))) + +extern long old_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); +extern syscall_handler_t sys_modify_ldt; +extern syscall_handler_t sys_arch_prctl; + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/system.h b/arch/um/sys-x86/shared/sysdep/system.h new file mode 100644 index 0000000..d1b93c4 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/system.h @@ -0,0 +1,132 @@ +#ifndef _ASM_X86_SYSTEM_H_ +#define _ASM_X86_SYSTEM_H_ + +#include +#include +#include +#include +#include + +#include +#include + +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + +extern unsigned long arch_align_stack(unsigned long sp); + +void default_idle(void); + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + */ +#ifdef CONFIG_X86_32 +/* + * Some non-Intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ +#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) +#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) +#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#else +#define mb() asm volatile("mfence":::"memory") +#define rmb() asm volatile("lfence":::"memory") +#define wmb() asm volatile("sfence" ::: "memory") +#endif + +/** + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like this where there are no data dependencies. + **/ + +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#ifdef CONFIG_X86_PPRO_FENCE +# define smp_rmb() rmb() +#else +# define smp_rmb() barrier() +#endif +#ifdef CONFIG_X86_OOSTORE +# define smp_wmb() wmb() +#else +# define smp_wmb() barrier() +#endif +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + +/* + * Stop RDTSC speculation. This is needed when you need to use RDTSC + * (or get_cycles or vread that possibly accesses the TSC) in a defined + * code region. + * + * (Could use an alternative three way for this if there was one.) + */ +static inline void rdtsc_barrier(void) +{ + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); +} + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/tls.h b/arch/um/sys-x86/shared/sysdep/tls.h new file mode 100644 index 0000000..4d8f752 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/tls.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "tls_32.h" +#else +#include "tls_64.h" +#endif diff --git a/arch/um/sys-x86/shared/sysdep/tls_32.h b/arch/um/sys-x86/shared/sysdep/tls_32.h new file mode 100644 index 0000000..3455075 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/tls_32.h @@ -0,0 +1,32 @@ +#ifndef _SYSDEP_TLS_H +#define _SYSDEP_TLS_H + +# ifndef __KERNEL__ + +/* Change name to avoid conflicts with the original one from , which + * may be named user_desc (but in 2.4 and in header matching its API was named + * modify_ldt_ldt_s). */ + +typedef struct um_dup_user_desc { + unsigned int entry_number; + unsigned int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +} user_desc_t; + +# else /* __KERNEL__ */ + +# include +typedef struct user_desc user_desc_t; + +# endif /* __KERNEL__ */ + +#define GDT_ENTRY_TLS_MIN_I386 6 +#define GDT_ENTRY_TLS_MIN_X86_64 12 + +#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86/shared/sysdep/tls_64.h b/arch/um/sys-x86/shared/sysdep/tls_64.h new file mode 100644 index 0000000..18c000d --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/tls_64.h @@ -0,0 +1,29 @@ +#ifndef _SYSDEP_TLS_H +#define _SYSDEP_TLS_H + +# ifndef __KERNEL__ + +/* Change name to avoid conflicts with the original one from , which + * may be named user_desc (but in 2.4 and in header matching its API was named + * modify_ldt_ldt_s). */ + +typedef struct um_dup_user_desc { + unsigned int entry_number; + unsigned int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; + unsigned int lm:1; +} user_desc_t; + +# else /* __KERNEL__ */ + +# include +typedef struct user_desc user_desc_t; + +# endif /* __KERNEL__ */ +#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h b/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h deleted file mode 100644 index 2af8f12..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/um/include/sysdep-x86_64/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; - unsigned long __rbp; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __rip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __rip -#define JB_SP __rsp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86_64/shared/sysdep/barrier.h b/arch/um/sys-x86_64/shared/sysdep/barrier.h deleted file mode 100644 index 7b610be..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/barrier.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SYSDEP_X86_64_BARRIER_H -#define __SYSDEP_X86_64_BARRIER_H - -/* Copied from include/asm-x86_64 for use by userspace. */ -#define mb() asm volatile("mfence":::"memory") - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h b/arch/um/sys-x86_64/shared/sysdep/faultinfo.h deleted file mode 100644 index cb917b0..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Author: Bodo Stroesser - * Licensed under the GPL - */ - -#ifndef __FAULTINFO_X86_64_H -#define __FAULTINFO_X86_64_H - -/* this structure contains the full arch-specific faultinfo - * from the traps. - * On i386, ptrace_faultinfo unfortunately doesn't provide - * all the info, since trap_no is missing. - * All common elements are defined at the same position in - * both structures, thus making it easy to copy the - * contents without knowledge about the structure elements. - */ -struct faultinfo { - int error_code; /* in ptrace_faultinfo misleadingly called is_write */ - unsigned long cr2; /* in ptrace_faultinfo called addr */ - int trap_no; /* missing in ptrace_faultinfo */ -}; - -#define FAULT_WRITE(fi) ((fi).error_code & 2) -#define FAULT_ADDRESS(fi) ((fi).cr2) - -#define PTRACE_FULL_FAULTINFO 1 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h b/arch/um/sys-x86_64/shared/sysdep/host_ldt.h deleted file mode 100644 index e8b1be1..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_HOST_LDT_X86_64_H -#define __ASM_HOST_LDT_X86_64_H - -#include - -/* - * macros stolen from include/asm-x86_64/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -/* Don't allow setting of the lm bit. It is useless anyways because - * 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 && \ - (info)->lm == 0) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h deleted file mode 100644 index a307237..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_STR1(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include -} diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h deleted file mode 100644 index 9ed4597..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_H -#define __SYSDEP_X86_64_PTRACE_H - -#include -#include "sysdep/faultinfo.h" - -#define MAX_REG_OFFSET (UM_FRAME_SIZE) -#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) - -#define REGS_RBX(r) ((r)[HOST_RBX]) -#define REGS_RCX(r) ((r)[HOST_RCX]) -#define REGS_RDX(r) ((r)[HOST_RDX]) -#define REGS_RSI(r) ((r)[HOST_RSI]) -#define REGS_RDI(r) ((r)[HOST_RDI]) -#define REGS_RBP(r) ((r)[HOST_RBP]) -#define REGS_RAX(r) ((r)[HOST_RAX]) -#define REGS_R8(r) ((r)[HOST_R8]) -#define REGS_R9(r) ((r)[HOST_R9]) -#define REGS_R10(r) ((r)[HOST_R10]) -#define REGS_R11(r) ((r)[HOST_R11]) -#define REGS_R12(r) ((r)[HOST_R12]) -#define REGS_R13(r) ((r)[HOST_R13]) -#define REGS_R14(r) ((r)[HOST_R14]) -#define REGS_R15(r) ((r)[HOST_R15]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_SS(r) ((r)[HOST_SS]) - -#define HOST_FS_BASE 21 -#define HOST_GS_BASE 22 -#define HOST_DS 23 -#define HOST_ES 24 -#define HOST_FS 25 -#define HOST_GS 26 - -/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these - * are already defined for kernel code, but not for userspace code. - */ -#ifndef FS_BASE -/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, - * which is what x86_64 ptrace actually uses. - */ -#define FS_BASE (HOST_FS_BASE * sizeof(long)) -#define GS_BASE (HOST_GS_BASE * sizeof(long)) -#define DS (HOST_DS * sizeof(long)) -#define ES (HOST_ES * sizeof(long)) -#define FS (HOST_FS * sizeof(long)) -#define GS (HOST_GS * sizeof(long)) -#endif - -#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) -#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) - -#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) - -#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) - -#define REGS_FAULT_ADDR(r) ((r)->fault_addr) - -#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) - -#define REGS_TRAP(r) ((r)->trap_type) - -#define REGS_ERR(r) ((r)->fault_type) - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FP_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_RBX(r) REGS_RBX((r)->gp) -#define UPT_RCX(r) REGS_RCX((r)->gp) -#define UPT_RDX(r) REGS_RDX((r)->gp) -#define UPT_RSI(r) REGS_RSI((r)->gp) -#define UPT_RDI(r) REGS_RDI((r)->gp) -#define UPT_RBP(r) REGS_RBP((r)->gp) -#define UPT_RAX(r) REGS_RAX((r)->gp) -#define UPT_R8(r) REGS_R8((r)->gp) -#define UPT_R9(r) REGS_R9((r)->gp) -#define UPT_R10(r) REGS_R10((r)->gp) -#define UPT_R11(r) REGS_R11((r)->gp) -#define UPT_R12(r) REGS_R12((r)->gp) -#define UPT_R13(r) REGS_R13((r)->gp) -#define UPT_R14(r) REGS_R14((r)->gp) -#define UPT_R15(r) REGS_R15((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp) - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) - -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_SYSCALL_NR(r) ((r)->syscall) -#define UPT_SYSCALL_RET(r) UPT_RAX(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -#define UPT_SYSCALL_ARG1(r) UPT_RDI(r) -#define UPT_SYSCALL_ARG2(r) UPT_RSI(r) -#define UPT_SYSCALL_ARG3(r) UPT_RDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_R10(r) -#define UPT_SYSCALL_ARG5(r) UPT_R8(r) -#define UPT_SYSCALL_ARG6(r) UPT_R9(r) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -static inline void arch_init_registers(int pid) -{ -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h deleted file mode 100644 index 2f1b6e3..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_USER_H__ -#define __SYSDEP_X86_64_PTRACE_USER_H__ - -#define __FRAME_OFFSETS -#include -#include -#include -#undef __FRAME_OFFSETS -#include - -#define PT_INDEX(off) ((off) / sizeof(unsigned long)) - -#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) -#define PT_SYSCALL_NR_OFFSET (ORIG_RAX) - -#define PT_SYSCALL_RET_OFFSET (RAX) - -/* - * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though - * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the - * 2.4 name and value for 2.4 host compatibility. - */ -#ifndef PTRACE_OLDSETOPTIONS -#define PTRACE_OLDSETOPTIONS 21 -#endif - -#define REGS_IP_INDEX PT_INDEX(RIP) -#define REGS_SP_INDEX PT_INDEX(RSP) - -#define FP_SIZE (HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h deleted file mode 100644 index 9fb5277..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SIGCONTEXT_H -#define __SYSDEP_X86_64_SIGCONTEXT_H - -#include - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* No broken SKAS API, which doesn't pass trap_no, here. */ -#define SEGV_MAYBE_FIXABLE(fi) 0 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h deleted file mode 100644 index 95db4be7..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H -#define __SYSDEP_X86_64_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/stub.h b/arch/um/sys-x86_64/shared/sysdep/stub.h deleted file mode 100644 index 922a570..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/stub.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include -#include -#include -#include "as-layout.h" -#include "stub-data.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); - -#define STUB_SYSCALL_RET PT_INDEX(RAX) -#define STUB_MMAP_NR __NR_mmap -#define MMAP_OFFSET(o) (o) - -#define __syscall_clobber "r11","rcx","memory" -#define __syscall "syscall" - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3) - : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4) - : __syscall_clobber, "r10" ); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4), "g" (arg5) - : __syscall_clobber, "r10", "r8" ); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(long fd, unsigned long offset) -{ - __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " - "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " - "movq %%rax, (%%rbx)": - : "a" (STUB_MMAP_NR), "D" (STUB_DATA), - "S" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "g" (MAP_FIXED | MAP_SHARED), "g" (fd), - "g" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : __syscall_clobber, "r10", "r8", "r9" ); -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/syscalls.h b/arch/um/sys-x86_64/shared/sysdep/syscalls.h deleted file mode 100644 index 8a7d5e1..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/syscalls.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SYSCALLS_H__ -#define __SYSDEP_X86_64_SYSCALLS_H__ - -#include -#include - -typedef long syscall_handler_t(void); - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - (((long (*)(long, long, long, long, long, long)) \ - (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ - UPT_SYSCALL_ARG2(®s->regs), \ - UPT_SYSCALL_ARG3(®s->regs), \ - UPT_SYSCALL_ARG4(®s->regs), \ - UPT_SYSCALL_ARG5(®s->regs), \ - UPT_SYSCALL_ARG6(®s->regs))) - -extern long old_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff); -extern syscall_handler_t sys_modify_ldt; -extern syscall_handler_t sys_arch_prctl; - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/system.h b/arch/um/sys-x86_64/shared/sysdep/system.h deleted file mode 100644 index d1b93c4..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include -#include -#include -#include -#include - -#include -#include - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/tls.h b/arch/um/sys-x86_64/shared/sysdep/tls.h deleted file mode 100644 index 18c000d..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/tls.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int lm:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ -#endif /* _SYSDEP_TLS_H */ -- cgit v1.1 From 6582b7f7743da6ce3e3714e9e8b18e0e073d4acd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:19 +0100 Subject: um: merge arch/um/sys-{i386,x86_64} Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 6 +- arch/um/Makefile-i386 | 2 +- arch/um/Makefile-x86_64 | 2 +- arch/um/sys-i386/Makefile | 24 -- arch/um/sys-i386/bug.c | 21 -- arch/um/sys-i386/bugs.c | 74 ----- arch/um/sys-i386/checksum.S | 458 --------------------------- arch/um/sys-i386/delay.c | 60 ---- arch/um/sys-i386/elfcore.c | 83 ----- arch/um/sys-i386/fault.c | 28 -- arch/um/sys-i386/ksyms.c | 5 - arch/um/sys-i386/ldt.c | 502 ------------------------------ arch/um/sys-i386/mem.c | 62 ---- arch/um/sys-i386/ptrace.c | 273 ---------------- arch/um/sys-i386/ptrace_user.c | 21 -- arch/um/sys-i386/setjmp.S | 58 ---- arch/um/sys-i386/signal.c | 498 ----------------------------- arch/um/sys-i386/stub.S | 51 --- arch/um/sys-i386/stub_segv.c | 17 - arch/um/sys-i386/sys_call_table.S | 28 -- arch/um/sys-i386/syscalls.c | 66 ---- arch/um/sys-i386/sysrq.c | 101 ------ arch/um/sys-i386/tls.c | 396 ----------------------- arch/um/sys-i386/user-offsets.c | 53 ---- arch/um/sys-x86/Makefile | 45 +++ arch/um/sys-x86/bug.c | 21 ++ arch/um/sys-x86/bugs_32.c | 74 +++++ arch/um/sys-x86/bugs_64.c | 15 + arch/um/sys-x86/checksum_32.S | 458 +++++++++++++++++++++++++++ arch/um/sys-x86/delay_32.c | 60 ++++ arch/um/sys-x86/delay_64.c | 60 ++++ arch/um/sys-x86/elfcore.c | 83 +++++ arch/um/sys-x86/fault.c | 28 ++ arch/um/sys-x86/ksyms.c | 13 + arch/um/sys-x86/ldt.c | 502 ++++++++++++++++++++++++++++++ arch/um/sys-x86/mem_32.c | 62 ++++ arch/um/sys-x86/mem_64.c | 26 ++ arch/um/sys-x86/ptrace_32.c | 273 ++++++++++++++++ arch/um/sys-x86/ptrace_64.c | 271 ++++++++++++++++ arch/um/sys-x86/ptrace_user.c | 21 ++ arch/um/sys-x86/setjmp_32.S | 58 ++++ arch/um/sys-x86/setjmp_64.S | 54 ++++ arch/um/sys-x86/signal_32.c | 498 +++++++++++++++++++++++++++++ arch/um/sys-x86/signal_64.c | 255 +++++++++++++++ arch/um/sys-x86/stub_32.S | 51 +++ arch/um/sys-x86/stub_64.S | 66 ++++ arch/um/sys-x86/stub_segv_32.c | 17 + arch/um/sys-x86/stub_segv_64.c | 22 ++ arch/um/sys-x86/sys_call_table_32.S | 28 ++ arch/um/sys-x86/sys_call_table_64.c | 64 ++++ arch/um/sys-x86/syscalls_32.c | 66 ++++ arch/um/sys-x86/syscalls_64.c | 102 ++++++ arch/um/sys-x86/sysrq_32.c | 101 ++++++ arch/um/sys-x86/sysrq_64.c | 41 +++ arch/um/sys-x86/tls_32.c | 396 +++++++++++++++++++++++ arch/um/sys-x86/tls_64.c | 17 + arch/um/sys-x86/user-offsets.c | 86 +++++ arch/um/sys-x86/vdso/Makefile | 90 ++++++ arch/um/sys-x86/vdso/checkundef.sh | 10 + arch/um/sys-x86/vdso/um_vdso.c | 71 +++++ arch/um/sys-x86/vdso/vdso-layout.lds.S | 64 ++++ arch/um/sys-x86/vdso/vdso-note.S | 12 + arch/um/sys-x86/vdso/vdso.S | 10 + arch/um/sys-x86/vdso/vdso.lds.S | 32 ++ arch/um/sys-x86/vdso/vma.c | 74 +++++ arch/um/sys-x86_64/Makefile | 27 -- arch/um/sys-x86_64/bug.c | 21 -- arch/um/sys-x86_64/bugs.c | 15 - arch/um/sys-x86_64/delay.c | 60 ---- arch/um/sys-x86_64/fault.c | 28 -- arch/um/sys-x86_64/ksyms.c | 11 - arch/um/sys-x86_64/mem.c | 26 -- arch/um/sys-x86_64/ptrace.c | 271 ---------------- arch/um/sys-x86_64/ptrace_user.c | 22 -- arch/um/sys-x86_64/setjmp.S | 54 ---- arch/um/sys-x86_64/signal.c | 255 --------------- arch/um/sys-x86_64/stub.S | 66 ---- arch/um/sys-x86_64/stub_segv.c | 22 -- arch/um/sys-x86_64/syscall_table.c | 64 ---- arch/um/sys-x86_64/syscalls.c | 102 ------ arch/um/sys-x86_64/sysrq.c | 41 --- arch/um/sys-x86_64/tls.c | 17 - arch/um/sys-x86_64/user-offsets.c | 65 ---- arch/um/sys-x86_64/vdso/Makefile | 90 ------ arch/um/sys-x86_64/vdso/checkundef.sh | 10 - arch/um/sys-x86_64/vdso/um_vdso.c | 71 ----- arch/um/sys-x86_64/vdso/vdso-layout.lds.S | 64 ---- arch/um/sys-x86_64/vdso/vdso-note.S | 12 - arch/um/sys-x86_64/vdso/vdso.S | 10 - arch/um/sys-x86_64/vdso/vdso.lds.S | 32 -- arch/um/sys-x86_64/vdso/vma.c | 74 ----- 91 files changed, 4302 insertions(+), 4414 deletions(-) delete mode 100644 arch/um/sys-i386/Makefile delete mode 100644 arch/um/sys-i386/bug.c delete mode 100644 arch/um/sys-i386/bugs.c delete mode 100644 arch/um/sys-i386/checksum.S delete mode 100644 arch/um/sys-i386/delay.c delete mode 100644 arch/um/sys-i386/elfcore.c delete mode 100644 arch/um/sys-i386/fault.c delete mode 100644 arch/um/sys-i386/ksyms.c delete mode 100644 arch/um/sys-i386/ldt.c delete mode 100644 arch/um/sys-i386/mem.c delete mode 100644 arch/um/sys-i386/ptrace.c delete mode 100644 arch/um/sys-i386/ptrace_user.c delete mode 100644 arch/um/sys-i386/setjmp.S delete mode 100644 arch/um/sys-i386/signal.c delete mode 100644 arch/um/sys-i386/stub.S delete mode 100644 arch/um/sys-i386/stub_segv.c delete mode 100644 arch/um/sys-i386/sys_call_table.S delete mode 100644 arch/um/sys-i386/syscalls.c delete mode 100644 arch/um/sys-i386/sysrq.c delete mode 100644 arch/um/sys-i386/tls.c delete mode 100644 arch/um/sys-i386/user-offsets.c create mode 100644 arch/um/sys-x86/Makefile create mode 100644 arch/um/sys-x86/bug.c create mode 100644 arch/um/sys-x86/bugs_32.c create mode 100644 arch/um/sys-x86/bugs_64.c create mode 100644 arch/um/sys-x86/checksum_32.S create mode 100644 arch/um/sys-x86/delay_32.c create mode 100644 arch/um/sys-x86/delay_64.c create mode 100644 arch/um/sys-x86/elfcore.c create mode 100644 arch/um/sys-x86/fault.c create mode 100644 arch/um/sys-x86/ksyms.c create mode 100644 arch/um/sys-x86/ldt.c create mode 100644 arch/um/sys-x86/mem_32.c create mode 100644 arch/um/sys-x86/mem_64.c create mode 100644 arch/um/sys-x86/ptrace_32.c create mode 100644 arch/um/sys-x86/ptrace_64.c create mode 100644 arch/um/sys-x86/ptrace_user.c create mode 100644 arch/um/sys-x86/setjmp_32.S create mode 100644 arch/um/sys-x86/setjmp_64.S create mode 100644 arch/um/sys-x86/signal_32.c create mode 100644 arch/um/sys-x86/signal_64.c create mode 100644 arch/um/sys-x86/stub_32.S create mode 100644 arch/um/sys-x86/stub_64.S create mode 100644 arch/um/sys-x86/stub_segv_32.c create mode 100644 arch/um/sys-x86/stub_segv_64.c create mode 100644 arch/um/sys-x86/sys_call_table_32.S create mode 100644 arch/um/sys-x86/sys_call_table_64.c create mode 100644 arch/um/sys-x86/syscalls_32.c create mode 100644 arch/um/sys-x86/syscalls_64.c create mode 100644 arch/um/sys-x86/sysrq_32.c create mode 100644 arch/um/sys-x86/sysrq_64.c create mode 100644 arch/um/sys-x86/tls_32.c create mode 100644 arch/um/sys-x86/tls_64.c create mode 100644 arch/um/sys-x86/user-offsets.c create mode 100644 arch/um/sys-x86/vdso/Makefile create mode 100644 arch/um/sys-x86/vdso/checkundef.sh create mode 100644 arch/um/sys-x86/vdso/um_vdso.c create mode 100644 arch/um/sys-x86/vdso/vdso-layout.lds.S create mode 100644 arch/um/sys-x86/vdso/vdso-note.S create mode 100644 arch/um/sys-x86/vdso/vdso.S create mode 100644 arch/um/sys-x86/vdso/vdso.lds.S create mode 100644 arch/um/sys-x86/vdso/vma.c delete mode 100644 arch/um/sys-x86_64/Makefile delete mode 100644 arch/um/sys-x86_64/bug.c delete mode 100644 arch/um/sys-x86_64/bugs.c delete mode 100644 arch/um/sys-x86_64/delay.c delete mode 100644 arch/um/sys-x86_64/fault.c delete mode 100644 arch/um/sys-x86_64/ksyms.c delete mode 100644 arch/um/sys-x86_64/mem.c delete mode 100644 arch/um/sys-x86_64/ptrace.c delete mode 100644 arch/um/sys-x86_64/ptrace_user.c delete mode 100644 arch/um/sys-x86_64/setjmp.S delete mode 100644 arch/um/sys-x86_64/signal.c delete mode 100644 arch/um/sys-x86_64/stub.S delete mode 100644 arch/um/sys-x86_64/stub_segv.c delete mode 100644 arch/um/sys-x86_64/syscall_table.c delete mode 100644 arch/um/sys-x86_64/syscalls.c delete mode 100644 arch/um/sys-x86_64/sysrq.c delete mode 100644 arch/um/sys-x86_64/tls.c delete mode 100644 arch/um/sys-x86_64/user-offsets.c delete mode 100644 arch/um/sys-x86_64/vdso/Makefile delete mode 100644 arch/um/sys-x86_64/vdso/checkundef.sh delete mode 100644 arch/um/sys-x86_64/vdso/um_vdso.c delete mode 100644 arch/um/sys-x86_64/vdso/vdso-layout.lds.S delete mode 100644 arch/um/sys-x86_64/vdso/vdso-note.S delete mode 100644 arch/um/sys-x86_64/vdso/vdso.S delete mode 100644 arch/um/sys-x86_64/vdso/vdso.lds.S delete mode 100644 arch/um/sys-x86_64/vdso/vma.c (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index 184494d..bd0587e 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,8 +121,8 @@ archclean: # Generated files -$(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE - $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@ +$(ARCH_DIR)/sys-$(HEADER_ARCH)/user-offsets.s: FORCE + $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(HEADER_ARCH) $@ define filechk_gen-asm-offsets (set -e; \ @@ -137,7 +137,7 @@ define filechk_gen-asm-offsets echo ""; ) endef -include/generated/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s +include/generated/user_constants.h: $(ARCH_DIR)/sys-$(HEADER_ARCH)/user-offsets.s $(call filechk,gen-asm-offsets) export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 302cbe5..7e5f1ba 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -1,4 +1,4 @@ -core-y += arch/um/sys-i386/ arch/x86/crypto/ +core-y += arch/um/sys-x86/ arch/x86/crypto/ TOP_ADDR := $(CONFIG_TOP_ADDR) diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index a9cd7e7..92d8f8f 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -1,7 +1,7 @@ # Copyright 2003 - 2004 Pathscale, Inc # Released under the GPL -core-y += arch/um/sys-x86_64/ arch/x86/crypto/ +core-y += arch/um/sys-x86/ arch/x86/crypto/ START := 0x60000000 _extra_flags_ = -fno-builtin -m64 diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile deleted file mode 100644 index 231bb98..0000000 --- a/arch/um/sys-i386/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# - -obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o mem.o - -obj-$(CONFIG_BINFMT_ELF) += elfcore.o - -subarch-obj-y = lib/string_32.o lib/atomic64_32.o lib/atomic64_cx8_32.o -subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -USER_OBJS := bugs.o ptrace_user.o fault.o - -extra-y += user-offsets.s -$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c deleted file mode 100644 index 8d4f273..0000000 --- a/arch/um/sys-i386/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include -#include - -/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c deleted file mode 100644 index 7058e1f..0000000 --- a/arch/um/sys-i386/bugs.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "kern_util.h" -#include "longjmp.h" -#include "task.h" -#include "sysdep/ptrace.h" - -/* Set during early boot */ -static int host_has_cmov = 1; -static jmp_buf cmov_test_return; - -static void cmov_sigill_test_handler(int sig) -{ - host_has_cmov = 0; - longjmp(cmov_test_return, 1); -} - -void arch_check_bugs(void) -{ - struct sigaction old, new; - - printk(UM_KERN_INFO "Checking for host processor cmov support..."); - new.sa_handler = cmov_sigill_test_handler; - - /* Make sure that SIGILL is enabled after the handler longjmps back */ - new.sa_flags = SA_NODEFER; - sigemptyset(&new.sa_mask); - sigaction(SIGILL, &new, &old); - - if (setjmp(cmov_test_return) == 0) { - unsigned long foo = 0; - __asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo)); - printk(UM_KERN_CONT "Yes\n"); - } else - printk(UM_KERN_CONT "No\n"); - - sigaction(SIGILL, &old, &new); -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ - unsigned char tmp[2]; - - /* - * This is testing for a cmov (0x0f 0x4x) instruction causing a - * SIGILL in init. - */ - if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) - return; - - if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) { - printk(UM_KERN_ERR "SIGILL in init, could not read " - "instructions!\n"); - return; - } - - if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return; - - if (host_has_cmov == 0) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor doesn't implement. Boot a filesystem " - "compiled for older processors"); - else if (host_has_cmov == 1) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor claims to implement"); - else - printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)", - host_has_cmov); -} diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S deleted file mode 100644 index f058d2f..0000000 --- a/arch/um/sys-i386/checksum.S +++ /dev/null @@ -1,458 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Pentium Pro/II routines: - * Alexander Kjeldaas - * Finn Arne Gangstad - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception - * handling. - * Andi Kleen, add zeroing on error - * converted to pure assembler - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -/* -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) - */ - -.text -.align 4 -.globl csum_partial - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - - /* - * Experiments with Ethernet and SLIP connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. We get at - * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. - * Fortunately, it is easy to convert 2-byte alignment to 4-byte - * alignment for the unrolled loop. - */ -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: unsigned char *buff - testl $2, %esi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -1: movw (%esi), %bx - addl $2, %esi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, %edx - shrl $5, %ecx - jz 2f - testl %esi, %esi -1: movl (%esi), %ebx - adcl %ebx, %eax - movl 4(%esi), %ebx - adcl %ebx, %eax - movl 8(%esi), %ebx - adcl %ebx, %eax - movl 12(%esi), %ebx - adcl %ebx, %eax - movl 16(%esi), %ebx - adcl %ebx, %eax - movl 20(%esi), %ebx - adcl %ebx, %eax - movl 24(%esi), %ebx - adcl %ebx, %eax - movl 28(%esi), %ebx - adcl %ebx, %eax - lea 32(%esi), %esi - dec %ecx - jne 1b - adcl $0, %eax -2: movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -3: adcl (%esi), %eax - lea 4(%esi), %esi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f - movw (%esi),%cx - leal 2(%esi),%esi - je 6f - shll $16,%ecx -5: movb (%esi),%cl -6: addl %ecx,%eax - adcl $0, %eax -7: - popl %ebx - popl %esi - ret - -#else - -/* Version for PentiumII/PPro */ - -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: const unsigned char *buf - - testl $2, %esi - jnz 30f -10: - movl %ecx, %edx - movl %ecx, %ebx - andl $0x7c, %ebx - shrl $7, %ecx - addl %ebx,%esi - shrl $2, %ebx - negl %ebx - lea 45f(%ebx,%ebx,2), %ebx - testl %esi, %esi - jmp *%ebx - - # Handle 2-byte-aligned regions -20: addw (%esi), %ax - lea 2(%esi), %esi - adcl $0, %eax - jmp 10b - -30: subl $2, %ecx - ja 20b - je 32f - movzbl (%esi),%ebx # csumming 1 byte, 2-aligned - addl %ebx, %eax - adcl $0, %eax - jmp 80f -32: - addw (%esi), %ax # csumming 2 bytes, 2-aligned - adcl $0, %eax - jmp 80f - -40: - addl -128(%esi), %eax - adcl -124(%esi), %eax - adcl -120(%esi), %eax - adcl -116(%esi), %eax - adcl -112(%esi), %eax - adcl -108(%esi), %eax - adcl -104(%esi), %eax - adcl -100(%esi), %eax - adcl -96(%esi), %eax - adcl -92(%esi), %eax - adcl -88(%esi), %eax - adcl -84(%esi), %eax - adcl -80(%esi), %eax - adcl -76(%esi), %eax - adcl -72(%esi), %eax - adcl -68(%esi), %eax - adcl -64(%esi), %eax - adcl -60(%esi), %eax - adcl -56(%esi), %eax - adcl -52(%esi), %eax - adcl -48(%esi), %eax - adcl -44(%esi), %eax - adcl -40(%esi), %eax - adcl -36(%esi), %eax - adcl -32(%esi), %eax - adcl -28(%esi), %eax - adcl -24(%esi), %eax - adcl -20(%esi), %eax - adcl -16(%esi), %eax - adcl -12(%esi), %eax - adcl -8(%esi), %eax - adcl -4(%esi), %eax -45: - lea 128(%esi), %esi - adcl $0, %eax - dec %ecx - jge 40b - movl %edx, %ecx -50: andl $3, %ecx - jz 80f - - # Handle the last 1-3 bytes without jumping - notl %ecx # 1->2, 2->1, 3->0, higher bits are masked - movl $0xffffff,%ebx # by the shll and shrl instructions - shll $3,%ecx - shrl %cl,%ebx - andl -128(%esi),%ebx # esi is 4-aligned so should be ok - addl %ebx,%eax - adcl $0,%eax -80: - popl %ebx - popl %esi - ret - -#endif - -/* -unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) - */ - -/* - * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. - */ - -#define SRC(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6001f ; \ - .previous - -#define DST(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6002f ; \ - .previous - -.align 4 - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - -#define ARGBASE 16 -#define FP 12 - -csum_partial_copy_generic_i386: - subl $4,%esp - pushl %edi - pushl %esi - pushl %ebx - movl ARGBASE+16(%esp),%eax # sum - movl ARGBASE+12(%esp),%ecx # len - movl ARGBASE+4(%esp),%esi # src - movl ARGBASE+8(%esp),%edi # dst - - testl $2, %edi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -SRC(1: movw (%esi), %bx ) - addl $2, %esi -DST( movw %bx, (%edi) ) - addl $2, %edi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, FP(%esp) - shrl $5, %ecx - jz 2f - testl %esi, %esi -SRC(1: movl (%esi), %ebx ) -SRC( movl 4(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - adcl %edx, %eax -DST( movl %edx, 4(%edi) ) - -SRC( movl 8(%esi), %ebx ) -SRC( movl 12(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 8(%edi) ) - adcl %edx, %eax -DST( movl %edx, 12(%edi) ) - -SRC( movl 16(%esi), %ebx ) -SRC( movl 20(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 16(%edi) ) - adcl %edx, %eax -DST( movl %edx, 20(%edi) ) - -SRC( movl 24(%esi), %ebx ) -SRC( movl 28(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 24(%edi) ) - adcl %edx, %eax -DST( movl %edx, 28(%edi) ) - - lea 32(%esi), %esi - lea 32(%edi), %edi - dec %ecx - jne 1b - adcl $0, %eax -2: movl FP(%esp), %edx - movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -SRC(3: movl (%esi), %ebx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - lea 4(%esi), %esi - lea 4(%edi), %edi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f -SRC( movw (%esi), %cx ) - leal 2(%esi), %esi -DST( movw %cx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%ecx -SRC(5: movb (%esi), %cl ) -DST( movb %cl, (%edi) ) -6: addl %ecx, %eax - adcl $0, %eax -7: -5000: - -# Exception handler: -.section .fixup, "ax" - -6001: - movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - - # zero the complete destination - computing the rest - # is too much work - movl ARGBASE+8(%esp), %edi # dst - movl ARGBASE+12(%esp), %ecx # len - xorl %eax,%eax - rep ; stosb - - jmp 5000b - -6002: - movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT,(%ebx) - jmp 5000b - -.previous - - popl %ebx - popl %esi - popl %edi - popl %ecx # equivalent to addl $4,%esp - ret - -#else - -/* Version for PentiumII/PPro */ - -#define ROUND1(x) \ - SRC(movl x(%esi), %ebx ) ; \ - addl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ROUND(x) \ - SRC(movl x(%esi), %ebx ) ; \ - adcl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ARGBASE 12 - -csum_partial_copy_generic_i386: - pushl %ebx - pushl %edi - pushl %esi - movl ARGBASE+4(%esp),%esi #src - movl ARGBASE+8(%esp),%edi #dst - movl ARGBASE+12(%esp),%ecx #len - movl ARGBASE+16(%esp),%eax #sum -# movl %ecx, %edx - movl %ecx, %ebx - movl %esi, %edx - shrl $6, %ecx - andl $0x3c, %ebx - negl %ebx - subl %ebx, %esi - subl %ebx, %edi - lea -1(%esi),%edx - andl $-32,%edx - lea 3f(%ebx,%ebx), %ebx - testl %esi, %esi - jmp *%ebx -1: addl $64,%esi - addl $64,%edi - SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) - ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) - ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) - ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) - ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) -3: adcl $0,%eax - addl $64, %edx - dec %ecx - jge 1b -4: movl ARGBASE+12(%esp),%edx #len - andl $3, %edx - jz 7f - cmpl $2, %edx - jb 5f -SRC( movw (%esi), %dx ) - leal 2(%esi), %esi -DST( movw %dx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%edx -5: -SRC( movb (%esi), %dl ) -DST( movb %dl, (%edi) ) -6: addl %edx, %eax - adcl $0, %eax -7: -.section .fixup, "ax" -6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - # zero the complete destination (computing the rest is too much work) - movl ARGBASE+8(%esp),%edi # dst - movl ARGBASE+12(%esp),%ecx # len - xorl %eax,%eax - rep; stosb - jmp 7b -6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT, (%ebx) - jmp 7b -.previous - - popl %esi - popl %edi - popl %ebx - ret - -#undef ROUND -#undef ROUND1 - -#endif diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c deleted file mode 100644 index f3fe1a6..0000000 --- a/arch/um/sys-i386/delay.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * Mostly copied from arch/x86/lib/delay.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -void __delay(unsigned long loops) -{ - asm volatile( - "test %0,%0\n" - "jz 3f\n" - "jmp 1f\n" - - ".align 16\n" - "1: jmp 2f\n" - - ".align 16\n" - "2: dec %0\n" - " jnz 2b\n" - "3: dec %0\n" - - : /* we don't need output */ - : "a" (loops) - ); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - asm("mull %%edx" - : "=d" (xloops), "=&a" (d0) - : "1" (xloops), "0" - (loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c deleted file mode 100644 index 6bb49b6..0000000 --- a/arch/um/sys-i386/elfcore.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include - -#include - - -Elf32_Half elf_core_extra_phdrs(void) -{ - return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; -} - -int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - Elf32_Off ofs = 0; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - struct elf_phdr phdr = phdrp[i]; - - if (phdr.p_type == PT_LOAD) { - ofs = phdr.p_offset = offset; - offset += phdr.p_filesz; - } else { - phdr.p_offset += ofs; - } - phdr.p_paddr = 0; /* match other core phdrs */ - *size += sizeof(phdr); - if (*size > limit - || !dump_write(file, &phdr, sizeof(phdr))) - return 0; - } - } - return 1; -} - -int elf_core_write_extra_data(struct file *file, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - if (phdrp[i].p_type == PT_LOAD) { - void *addr = (void *) phdrp[i].p_vaddr; - size_t filesz = phdrp[i].p_filesz; - - *size += filesz; - if (*size > limit - || !dump_write(file, addr, filesz)) - return 0; - } - } - } - return 1; -} - -size_t elf_core_extra_data_size(void) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *)vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) - if (phdrp[i].p_type == PT_LOAD) - return (size_t) phdrp[i].p_filesz; - } - return 0; -} diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c deleted file mode 100644 index d670f68..0000000 --- a/arch/um/sys-i386/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c deleted file mode 100644 index bfbefd3..0000000 --- a/arch/um/sys-i386/ksyms.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "linux/module.h" -#include "asm/checksum.h" - -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c deleted file mode 100644 index 3f2bf20..0000000 --- a/arch/um/sys-i386/ldt.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include "os.h" -#include "proc_mm.h" -#include "skas.h" -#include "skas_ptrace.h" -#include "sysdep/tls.h" - -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); - -static long write_ldt_entry(struct mm_id *mm_idp, int func, - struct user_desc *desc, void **addr, int done) -{ - long res; - - if (proc_mm) { - /* - * This is a special handling for the case, that the mm to - * modify isn't current->active_mm. - * If this is called directly by modify_ldt, - * (current->active_mm->context.skas.u == mm_idp) - * will be true. So no call to __switch_mm(mm_idp) is done. - * If this is called in case of init_new_ldt or PTRACE_LDT, - * mm_idp won't belong to current->active_mm, but child->mm. - * So we need to switch child's mm into our userspace, then - * later switch back. - * - * Note: I'm unsure: should interrupts be disabled here? - */ - if (!current->active_mm || current->active_mm == &init_mm || - mm_idp != ¤t->active_mm->context.id) - __switch_mm(mm_idp); - } - - if (ptrace_ldt) { - struct ptrace_ldt ldt_op = (struct ptrace_ldt) { - .func = func, - .ptr = desc, - .bytecount = sizeof(*desc)}; - u32 cpu; - int pid; - - if (!proc_mm) - pid = mm_idp->u.pid; - else { - cpu = get_cpu(); - pid = userspace_pid[cpu]; - } - - res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); - - if (proc_mm) - put_cpu(); - } - else { - void *stub_addr; - res = syscall_stub_data(mm_idp, (unsigned long *)desc, - (sizeof(*desc) + sizeof(long) - 1) & - ~(sizeof(long) - 1), - addr, &stub_addr); - if (!res) { - unsigned long args[] = { func, - (unsigned long)stub_addr, - sizeof(*desc), - 0, 0, 0 }; - res = run_syscall_stub(mm_idp, __NR_modify_ldt, args, - 0, addr, done); - } - } - - if (proc_mm) { - /* - * This is the second part of special handling, that makes - * PTRACE_LDT possible to implement. - */ - if (current->active_mm && current->active_mm != &init_mm && - mm_idp != ¤t->active_mm->context.id) - __switch_mm(¤t->active_mm->context.id); - } - - return res; -} - -static long read_ldt_from_host(void __user * ptr, unsigned long bytecount) -{ - int res, n; - struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) { - .func = 0, - .bytecount = bytecount, - .ptr = kmalloc(bytecount, GFP_KERNEL)}; - u32 cpu; - - if (ptrace_ldt.ptr == NULL) - return -ENOMEM; - - /* - * This is called from sys_modify_ldt only, so userspace_pid gives - * us the right number - */ - - cpu = get_cpu(); - res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); - put_cpu(); - if (res < 0) - goto out; - - n = copy_to_user(ptr, ptrace_ldt.ptr, res); - if (n != 0) - res = -EFAULT; - - out: - kfree(ptrace_ldt.ptr); - - return res; -} - -/* - * In skas mode, we hold our own ldt data in UML. - * Thus, the code implementing sys_modify_ldt_skas - * is very similar to (and mostly stolen from) sys_modify_ldt - * for arch/i386/kernel/ldt.c - * The routines copied and modified in part are: - * - read_ldt - * - read_default_ldt - * - write_ldt - * - sys_modify_ldt_skas - */ - -static int read_ldt(void __user * ptr, unsigned long bytecount) -{ - int i, err = 0; - unsigned long size; - uml_ldt_t * ldt = ¤t->mm->context.ldt; - - if (!ldt->entry_count) - goto out; - if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) - bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - err = bytecount; - - if (ptrace_ldt) - return read_ldt_from_host(ptr, bytecount); - - mutex_lock(&ldt->lock); - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { - size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.entries, size)) - err = -EFAULT; - bytecount -= size; - ptr += size; - } - else { - for (i=0; ientry_count/LDT_ENTRIES_PER_PAGE && bytecount; - i++) { - size = PAGE_SIZE; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.pages[i], size)) { - err = -EFAULT; - break; - } - bytecount -= size; - ptr += size; - } - } - mutex_unlock(&ldt->lock); - - if (bytecount == 0 || err == -EFAULT) - goto out; - - if (clear_user(ptr, bytecount)) - err = -EFAULT; - -out: - return err; -} - -static int read_default_ldt(void __user * ptr, unsigned long bytecount) -{ - int err; - - if (bytecount > 5*LDT_ENTRY_SIZE) - bytecount = 5*LDT_ENTRY_SIZE; - - err = bytecount; - /* - * UML doesn't support lcall7 and lcall27. - * So, we don't really have a default ldt, but emulate - * an empty ldt of common host default ldt size. - */ - if (clear_user(ptr, bytecount)) - err = -EFAULT; - - return err; -} - -static int write_ldt(void __user * ptr, unsigned long bytecount, int func) -{ - uml_ldt_t * ldt = ¤t->mm->context.ldt; - struct mm_id * mm_idp = ¤t->mm->context.id; - int i, err; - struct user_desc ldt_info; - struct ldt_entry entry0, *ldt_p; - void *addr = NULL; - - err = -EINVAL; - if (bytecount != sizeof(ldt_info)) - goto out; - err = -EFAULT; - if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) - goto out; - - err = -EINVAL; - if (ldt_info.entry_number >= LDT_ENTRIES) - goto out; - if (ldt_info.contents == 3) { - if (func == 1) - goto out; - if (ldt_info.seg_not_present == 0) - goto out; - } - - if (!ptrace_ldt) - mutex_lock(&ldt->lock); - - err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); - if (err) - goto out_unlock; - else if (ptrace_ldt) { - /* With PTRACE_LDT available, this is used as a flag only */ - ldt->entry_count = 1; - goto out; - } - - if (ldt_info.entry_number >= ldt->entry_count && - ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { - for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; - i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; - i++) { - if (i == 0) - memcpy(&entry0, ldt->u.entries, - sizeof(entry0)); - ldt->u.pages[i] = (struct ldt_entry *) - __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!ldt->u.pages[i]) { - err = -ENOMEM; - /* Undo the change in host */ - memset(&ldt_info, 0, sizeof(ldt_info)); - write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); - goto out_unlock; - } - if (i == 0) { - memcpy(ldt->u.pages[0], &entry0, - sizeof(entry0)); - memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, - sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); - } - ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; - } - } - if (ldt->entry_count <= ldt_info.entry_number) - ldt->entry_count = ldt_info.entry_number + 1; - - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) - ldt_p = ldt->u.entries + ldt_info.entry_number; - else - ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + - ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; - - if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && - (func == 1 || LDT_empty(&ldt_info))) { - ldt_p->a = 0; - ldt_p->b = 0; - } - else{ - if (func == 1) - ldt_info.useable = 0; - ldt_p->a = LDT_entry_a(&ldt_info); - ldt_p->b = LDT_entry_b(&ldt_info); - } - err = 0; - -out_unlock: - mutex_unlock(&ldt->lock); -out: - return err; -} - -static long do_modify_ldt_skas(int func, void __user *ptr, - unsigned long bytecount) -{ - int ret = -ENOSYS; - - switch (func) { - case 0: - ret = read_ldt(ptr, bytecount); - break; - case 1: - case 0x11: - ret = write_ldt(ptr, bytecount, func); - break; - case 2: - ret = read_default_ldt(ptr, bytecount); - break; - } - return ret; -} - -static DEFINE_SPINLOCK(host_ldt_lock); -static short dummy_list[9] = {0, -1}; -static short * host_ldt_entries = NULL; - -static void ldt_get_host_info(void) -{ - long ret; - struct ldt_entry * ldt; - short *tmp; - int i, size, k, order; - - spin_lock(&host_ldt_lock); - - if (host_ldt_entries != NULL) { - spin_unlock(&host_ldt_lock); - return; - } - host_ldt_entries = dummy_list+1; - - spin_unlock(&host_ldt_lock); - - for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) - ; - - ldt = (struct ldt_entry *) - __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); - if (ldt == NULL) { - printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " - "for host ldt\n"); - return; - } - - ret = modify_ldt(0, ldt, (1<ldt.lock); - - if (!from_mm) { - memset(&desc, 0, sizeof(desc)); - /* - * We have to initialize a clean ldt. - */ - if (proc_mm) { - /* - * If the new mm was created using proc_mm, host's - * default-ldt currently is assigned, which normally - * contains the call-gates for lcall7 and lcall27. - * To remove these gates, we simply write an empty - * entry as number 0 to the host. - */ - err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1); - } - else{ - /* - * Now we try to retrieve info about the ldt, we - * inherited from the host. All ldt-entries found - * will be reset in the following loop - */ - ldt_get_host_info(); - for (num_p=host_ldt_entries; *num_p != -1; num_p++) { - desc.entry_number = *num_p; - err = write_ldt_entry(&new_mm->id, 1, &desc, - &addr, *(num_p + 1) == -1); - if (err) - break; - } - } - new_mm->ldt.entry_count = 0; - - goto out; - } - - if (proc_mm) { - /* - * We have a valid from_mm, so we now have to copy the LDT of - * from_mm to new_mm, because using proc_mm an new mm with - * an empty/default LDT was created in new_mm() - */ - copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, - .u = - { .copy_segments = - from_mm->id.u.mm_fd } } ); - i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); - if (i != sizeof(copy)) - printk(KERN_ERR "new_mm : /proc/mm copy_segments " - "failed, err = %d\n", -i); - } - - if (!ptrace_ldt) { - /* - * Our local LDT is used to supply the data for - * modify_ldt(READLDT), if PTRACE_LDT isn't available, - * i.e., we have to use the stub for modify_ldt, which - * can't handle the big read buffer of up to 64kB. - */ - mutex_lock(&from_mm->ldt.lock); - if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) - memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, - sizeof(new_mm->ldt.u.entries)); - else { - i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-->0) { - page = __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!page) { - err = -ENOMEM; - break; - } - new_mm->ldt.u.pages[i] = - (struct ldt_entry *) page; - memcpy(new_mm->ldt.u.pages[i], - from_mm->ldt.u.pages[i], PAGE_SIZE); - } - } - new_mm->ldt.entry_count = from_mm->ldt.entry_count; - mutex_unlock(&from_mm->ldt.lock); - } - - out: - return err; -} - - -void free_ldt(struct mm_context *mm) -{ - int i; - - if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { - i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-- > 0) - free_page((long) mm->ldt.u.pages[i]); - } - mm->ldt.entry_count = 0; -} - -int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -{ - return do_modify_ldt_skas(func, ptr, bytecount); -} diff --git a/arch/um/sys-i386/mem.c b/arch/um/sys-i386/mem.c deleted file mode 100644 index 639900a..0000000 --- a/arch/um/sys-i386/mem.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -static struct vm_area_struct gate_vma; - -static int __init gate_vma_init(void) -{ - if (!FIXADDR_USER_START) - return 0; - - gate_vma.vm_mm = NULL; - gate_vma.vm_start = FIXADDR_USER_START; - gate_vma.vm_end = FIXADDR_USER_END; - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; - gate_vma.vm_page_prot = __P101; - - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - gate_vma.vm_flags |= VM_ALWAYSDUMP; - - return 0; -} -__initcall(gate_vma_init); - -struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return FIXADDR_USER_START ? &gate_vma : NULL; -} - -int in_gate_area_no_mm(unsigned long addr) -{ - if (!FIXADDR_USER_START) - return 0; - - if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) - return 1; - - return 0; -} - -int in_gate_area(struct mm_struct *mm, unsigned long addr) -{ - struct vm_area_struct *vma = get_gate_vma(mm); - - if (!vma) - return 0; - - return (addr >= vma->vm_start) && (addr < vma->vm_end); -} diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c deleted file mode 100644 index a174fde..0000000 --- a/arch/um/sys-i386/ptrace.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "skas.h" - -extern int arch_switch_tls(struct task_struct *to); - -void arch_switch_to(struct task_struct *to) -{ - int err = arch_switch_tls(to); - if (!err) - return; - - if (err != -EINVAL) - printk(KERN_WARNING "arch_switch_tls failed, errno %d, " - "not EINVAL\n", -err); - else - printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); -} - -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk(KERN_ERR "is_syscall : failed to read " - "instruction from 0x%lx\n", addr); - return 1; - } - } - /* int 0x80 or sysenter */ - return (instr == 0x80cd) || (instr == 0x340f); -} - -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ -#define FLAG_MASK 0x00044dd5 - -static const int reg_offsets[] = { - [EBX] = HOST_EBX, - [ECX] = HOST_ECX, - [EDX] = HOST_EDX, - [ESI] = HOST_ESI, - [EDI] = HOST_EDI, - [EBP] = HOST_EBP, - [EAX] = HOST_EAX, - [DS] = HOST_DS, - [ES] = HOST_ES, - [FS] = HOST_FS, - [GS] = HOST_GS, - [EIP] = HOST_IP, - [CS] = HOST_CS, - [EFL] = HOST_EFLAGS, - [UESP] = HOST_SP, - [SS] = HOST_SS, -}; - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ - regno >>= 2; - switch (regno) { - case EBX: - case ECX: - case EDX: - case ESI: - case EDI: - case EBP: - case EAX: - case EIP: - case UESP: - break; - case FS: - if (value && (value & 3) != 3) - return -EIO; - break; - case GS: - if (value && (value & 3) != 3) - return -EIO; - break; - case DS: - case ES: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case SS: - case CS: - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case EFL: - value &= FLAG_MASK; - child->thread.regs.regs.gp[HOST_EFLAGS] |= value; - return 0; - case ORIG_EAX: - child->thread.regs.regs.syscall = value; - return 0; - default : - panic("Bad register in putreg() : %d\n", regno); - } - child->thread.regs.regs.gp[reg_offsets[regno]] = value; - return 0; -} - -int poke_user(struct task_struct *child, long addr, long data) -{ - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if ((addr == 4) || (addr == 5)) - return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; -} - -unsigned long getreg(struct task_struct *child, int regno) -{ - unsigned long mask = ~0UL; - - regno >>= 2; - switch (regno) { - case ORIG_EAX: - return child->thread.regs.regs.syscall; - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - mask = 0xffff; - break; - case EIP: - case UESP: - case EAX: - case EBX: - case ECX: - case EDX: - case ESI: - case EDI: - case EBP: - case EFL: - break; - default: - panic("Bad register in getreg() : %d\n", regno); - } - return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; -} - -/* read the word at location addr in the USER area. */ -int peek_user(struct task_struct *child, long addr, long data) -{ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if (addr < MAX_REG_OFFSET) { - tmp = getreg(child, addr); - } - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long __user *) data); -} - -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fpx_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EIO; - void __user *datap = (void __user *) data; - switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpxregs(datap, child); - break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpxregs(datap, child); - break; - default: - ret = -EIO; - } - return ret; -} diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c deleted file mode 100644 index 0b10c3e..0000000 --- a/arch/um/sys-i386/ptrace_user.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return 0; -} - -int ptrace_setregs(long pid, unsigned long *regs) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0) - return -errno; - return 0; -} diff --git a/arch/um/sys-i386/setjmp.S b/arch/um/sys-i386/setjmp.S deleted file mode 100644 index b766792..0000000 --- a/arch/um/sys-i386/setjmp.S +++ /dev/null @@ -1,58 +0,0 @@ -# -# arch/i386/setjmp.S -# -# setjmp/longjmp for the i386 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %ebx -# %esp -# %ebp -# %esi -# %edi -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: -#ifdef _REGPARM - movl %eax,%edx -#else - movl 4(%esp),%edx -#endif - popl %ecx # Return address, and adjust the stack - xorl %eax,%eax # Return value - movl %ebx,(%edx) - movl %esp,4(%edx) # Post-return %esp! - pushl %ecx # Make the call/return stack happy - movl %ebp,8(%edx) - movl %esi,12(%edx) - movl %edi,16(%edx) - movl %ecx,20(%edx) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: -#ifdef _REGPARM - xchgl %eax,%edx -#else - movl 4(%esp),%edx # jmp_ptr address - movl 8(%esp),%eax # Return value -#endif - movl (%edx),%ebx - movl 4(%edx),%esp - movl 8(%edx),%ebp - movl 12(%edx),%esi - movl 16(%edx),%edi - jmp *20(%edx) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c deleted file mode 100644 index bcbfb0d..0000000 --- a/arch/um/sys-i386/signal.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include "frame_kern.h" -#include "skas.h" - -/* - * FPU tag word conversions. - */ - -static inline unsigned short twd_i387_to_fxsr(unsigned short twd) -{ - unsigned int tmp; /* to avoid 16 bit prefixes in the code */ - - /* Transform each pair of bits into 01 (valid) or 00 (empty) */ - tmp = ~twd; - tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ - /* and move the valid bits to the lower byte. */ - tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ - tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ - tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ - return tmp; -} - -static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) -{ - struct _fpxreg *st = NULL; - unsigned long twd = (unsigned long) fxsave->twd; - unsigned long tag; - unsigned long ret = 0xffff0000; - int i; - -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) - - for (i = 0; i < 8; i++) { - if (twd & 0x1) { - st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); - - switch (st->exponent & 0x7fff) { - case 0x7fff: - tag = 2; /* Special */ - break; - case 0x0000: - if ( !st->significand[0] && - !st->significand[1] && - !st->significand[2] && - !st->significand[3] ) { - tag = 1; /* Zero */ - } else { - tag = 2; /* Special */ - } - break; - default: - if (st->significand[3] & 0x8000) { - tag = 0; /* Valid */ - } else { - tag = 2; /* Special */ - } - break; - } - } else { - tag = 3; /* Empty */ - } - ret |= (tag << (2 * i)); - twd = twd >> 1; - } - return ret; -} - -static int convert_fxsr_to_user(struct _fpstate __user *buf, - struct user_fxsr_struct *fxsave) -{ - unsigned long env[7]; - struct _fpreg __user *to; - struct _fpxreg *from; - int i; - - env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; - env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; - env[2] = twd_fxsr_to_i387(fxsave); - env[3] = fxsave->fip; - env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); - env[5] = fxsave->foo; - env[6] = fxsave->fos; - - if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) - return 1; - - to = &buf->_st[0]; - from = (struct _fpxreg *) &fxsave->st_space[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long __user *t = (unsigned long __user *)to; - unsigned long *f = (unsigned long *)from; - - if (__put_user(*f, t) || - __put_user(*(f + 1), t + 1) || - __put_user(from->exponent, &to->exponent)) - return 1; - } - return 0; -} - -static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, - struct _fpstate __user *buf) -{ - unsigned long env[7]; - struct _fpxreg *to; - struct _fpreg __user *from; - int i; - - if (copy_from_user( env, buf, 7 * sizeof(long))) - return 1; - - fxsave->cwd = (unsigned short)(env[0] & 0xffff); - fxsave->swd = (unsigned short)(env[1] & 0xffff); - fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); - fxsave->fip = env[3]; - fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); - fxsave->fcs = (env[4] & 0xffff); - fxsave->foo = env[5]; - fxsave->fos = env[6]; - - to = (struct _fpxreg *) &fxsave->st_space[0]; - from = &buf->_st[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long *t = (unsigned long *)to; - unsigned long __user *f = (unsigned long __user *)from; - - if (__get_user(*t, f) || - __get_user(*(t + 1), f + 1) || - __get_user(to->exponent, &from->exponent)) - return 1; - } - return 0; -} - -extern int have_fpx_regs; - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from) -{ - struct sigcontext sc; - int err, pid; - - err = copy_from_user(&sc, from, sizeof(sc)); - if (err) - return err; - - pid = userspace_pid[current_thread_info()->cpu]; - -#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname - - GETREG(GS, gs); - GETREG(FS, fs); - GETREG(ES, es); - GETREG(DS, ds); - GETREG(EDI, di); - GETREG(ESI, si); - GETREG(EBP, bp); - GETREG(SP, sp); - GETREG(EBX, bx); - GETREG(EDX, dx); - GETREG(ECX, cx); - GETREG(EAX, ax); - GETREG(IP, ip); - GETREG(CS, cs); - GETREG(EFLAGS, flags); - GETREG(SS, ss); - -#undef GETREG - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = copy_from_user(&fpx, - &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0], - sizeof(struct user_fxsr_struct)); - if (err) - return 1; - - err = convert_fxsr_from_user(&fpx, sc.fpstate); - if (err) - return 1; - - err = restore_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fpx_registers failed, errno = %d\n", - -err); - return 1; - } - } else { - struct user_i387_struct fp; - - err = copy_from_user(&fp, sc.fpstate, - sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(pid, (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long sp) -{ - struct sigcontext sc; - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - int err, pid; - memset(&sc, 0, sizeof(struct sigcontext)); - - sc.gs = REGS_GS(regs->regs.gp); - sc.fs = REGS_FS(regs->regs.gp); - sc.es = REGS_ES(regs->regs.gp); - sc.ds = REGS_DS(regs->regs.gp); - sc.di = REGS_EDI(regs->regs.gp); - sc.si = REGS_ESI(regs->regs.gp); - sc.bp = REGS_EBP(regs->regs.gp); - sc.sp = sp; - sc.bx = REGS_EBX(regs->regs.gp); - sc.dx = REGS_EDX(regs->regs.gp); - sc.cx = REGS_ECX(regs->regs.gp); - sc.ax = REGS_EAX(regs->regs.gp); - sc.ip = REGS_IP(regs->regs.gp); - sc.cs = REGS_CS(regs->regs.gp); - sc.flags = REGS_EFLAGS(regs->regs.gp); - sc.sp_at_signal = regs->regs.gp[UESP]; - sc.ss = regs->regs.gp[SS]; - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); - sc.fpstate = to_fp; - - pid = userspace_pid[current_thread_info()->cpu]; - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = save_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0){ - printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " - "failed, errno = %d\n", err); - return 1; - } - - err = convert_fxsr_to_user(to_fp, &fpx); - if (err) - return 1; - - err |= __put_user(fpx.swd, &to_fp->status); - err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic); - if (err) - return 1; - - if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, - sizeof(struct user_fxsr_struct))) - return 1; - } - else { - struct user_i387_struct fp; - - err = save_fp_registers(pid, (unsigned long *) &fp); - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - } - - return copy_to_user(to, &sc, sizeof(sc)); -} - -static int copy_ucontext_to_user(struct ucontext __user *uc, - struct _fpstate __user *fp, sigset_t *set, - unsigned long sp) -{ - int err = 0; - - err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); - err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); - err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); - err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); - err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return err; -} - -struct sigframe -{ - char __user *pretcode; - int sig; - struct sigcontext sc; - struct _fpstate fpstate; - unsigned long extramask[_NSIG_WORDS-1]; - char retcode[8]; -}; - -struct rt_sigframe -{ - char __user *pretcode; - int sig; - struct siginfo __user *pinfo; - void __user *puc; - struct siginfo info; - struct ucontext uc; - struct _fpstate fpstate; - char retcode[8]; -}; - -int setup_signal_stack_sc(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - sigset_t *mask) -{ - struct sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ - stack_top = ((stack_top + 4) & -16UL) - 4; - frame = (struct sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); - err |= __put_user(mask->sig[0], &frame->sc.oldmask); - if (_NSIG_WORDS > 1) - err |= __copy_to_user(&frame->extramask, &mask->sig[1], - sizeof(frame->extramask)); - - /* - * This is popl %eax ; movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); - err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); - - if (err) - goto err; - - PT_REGS_SP(regs) = (unsigned long) frame; - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) 0; - PT_REGS_ECX(regs) = (unsigned long) 0; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - siginfo_t *info, sigset_t *mask) -{ - struct rt_sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - stack_top &= -8UL; - frame = (struct rt_sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* See comment above about why this is here */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, - save_sp); - - /* - * This is movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); - err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); - - if (err) - goto err; - - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) &frame->info; - PT_REGS_ECX(regs) = (unsigned long) &frame->uc; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -long sys_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); - sigset_t set; - struct sigcontext __user *sc = &frame->sc; - unsigned long __user *oldmask = &sc->oldmask; - unsigned long __user *extramask = frame->extramask; - int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - - if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || - copy_from_user(&set.sig[1], extramask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, sc)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} - -long sys_rt_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *) (sp - 4); - sigset_t set; - struct ucontext __user *uc = &frame->uc; - int sig_size = _NSIG_WORDS * sizeof(unsigned long); - - if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S deleted file mode 100644 index 54a36ec..0000000 --- a/arch/um/sys-i386/stub.S +++ /dev/null @@ -1,51 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" - - .globl batch_syscall_stub -batch_syscall_stub: - /* load pointer to first operation */ - mov $(STUB_DATA+8), %esp - -again: - /* load length of additional data */ - mov 0x0(%esp), %eax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %eax, STUB_DATA+4 - cmpl $0, %eax - jz done - - /* save current pointer */ - mov %esp, STUB_DATA+4 - - /* skip additional data */ - add %eax, %esp - - /* load syscall-# */ - pop %eax - - /* load syscall params */ - pop %ebx - pop %ecx - pop %edx - pop %esi - pop %edi - pop %ebp - - /* execute syscall */ - int $0x80 - - /* check return value */ - pop %ebx - cmp %ebx, %eax - je again - -done: - /* save return value */ - mov %eax, STUB_DATA - - /* stop */ - int3 diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c deleted file mode 100644 index 28ccf73..0000000 --- a/arch/um/sys-i386/stub_segv.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/stub.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct sigcontext *sc = (struct sigcontext *) (&sig + 1); - - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); - - trap_myself(); -} diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S deleted file mode 100644 index de274071..0000000 --- a/arch/um/sys-i386/sys_call_table.S +++ /dev/null @@ -1,28 +0,0 @@ -#include -/* Steal i386 syscall table for our purposes, but with some slight changes.*/ - -#define sys_iopl sys_ni_syscall -#define sys_ioperm sys_ni_syscall - -#define sys_vm86old sys_ni_syscall -#define sys_vm86 sys_ni_syscall - -#define old_mmap sys_old_mmap - -#define ptregs_fork sys_fork -#define ptregs_execve sys_execve -#define ptregs_iopl sys_iopl -#define ptregs_vm86old sys_vm86old -#define ptregs_sigreturn sys_sigreturn -#define ptregs_clone sys_clone -#define ptregs_vm86 sys_vm86 -#define ptregs_rt_sigreturn sys_rt_sigreturn -#define ptregs_sigaltstack sys_sigaltstack -#define ptregs_vfork sys_vfork - -.section .rodata,"a" - -#include "../../x86/kernel/syscall_table_32.S" - -ENTRY(syscall_table_size) -.long .-sys_call_table diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c deleted file mode 100644 index 70ca357..0000000 --- a/arch/um/sys-i386/syscalls.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "linux/shm.h" -#include "linux/ipc.h" -#include "linux/syscalls.h" -#include "asm/mman.h" -#include "asm/uaccess.h" -#include "asm/unistd.h" - -/* - * The prototype on i386 is: - * - * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) - * - * and the "newtls" arg. on i386 is read by copy_thread directly from the - * register saved on the stack. - */ -long sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tid, void *newtls, int __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -long sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c deleted file mode 100644 index 171b3e9..0000000 --- a/arch/um/sys-i386/sysrq.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "linux/smp.h" -#include "linux/sched.h" -#include "linux/kallsyms.h" -#include "asm/ptrace.h" -#include "sysrq.h" - -/* This is declared by */ -void show_regs(struct pt_regs *regs) -{ - printk("\n"); - printk("EIP: %04lx:[<%08lx>] CPU: %d %s", - 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs), - smp_processor_id(), print_tainted()); - if (PT_REGS_CS(regs) & 3) - printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs), - PT_REGS_SP(regs)); - printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs), - print_tainted()); - printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - PT_REGS_EAX(regs), PT_REGS_EBX(regs), - PT_REGS_ECX(regs), - PT_REGS_EDX(regs)); - printk("ESI: %08lx EDI: %08lx EBP: %08lx", - PT_REGS_ESI(regs), PT_REGS_EDI(regs), - PT_REGS_EBP(regs)); - printk(" DS: %04lx ES: %04lx\n", - 0xffff & PT_REGS_DS(regs), - 0xffff & PT_REGS_ES(regs)); - - show_trace(NULL, (unsigned long *) ®s); -} - -/* Copied from i386. */ -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - return p > (void *)tinfo && - p < (void *)tinfo + THREAD_SIZE - 3; -} - -/* Adapted from i386 (we also print the address we read from). */ -static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long ebp) -{ - unsigned long addr; - -#ifdef CONFIG_FRAME_POINTER - while (valid_stack_ptr(tinfo, (void *)ebp)) { - addr = *(unsigned long *)(ebp + 4); - printk("%08lx: [<%08lx>]", ebp + 4, addr); - print_symbol(" %s", addr); - printk("\n"); - ebp = *(unsigned long *)ebp; - } -#else - while (valid_stack_ptr(tinfo, stack)) { - addr = *stack; - if (__kernel_text_address(addr)) { - printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); - print_symbol(" %s", addr); - printk("\n"); - } - stack++; - } -#endif - return ebp; -} - -void show_trace(struct task_struct* task, unsigned long * stack) -{ - unsigned long ebp; - struct thread_info *context; - - /* Turn this into BUG_ON if possible. */ - if (!stack) { - stack = (unsigned long*) &stack; - printk("show_trace: got NULL stack, implicit assumption task == current"); - WARN_ON(1); - } - - if (!task) - task = current; - - if (task != current) { - ebp = (unsigned long) KSTK_EBP(task); - } else { - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - print_context_stack(context, stack, ebp); - - printk("\n"); -} - diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c deleted file mode 100644 index c6c7131..0000000 --- a/arch/um/sys-i386/tls.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso - * Licensed under the GPL - */ - -#include "linux/percpu.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "os.h" -#include "skas.h" -#include "sysdep/tls.h" - -/* - * If needed we can detect when it's uninitialized. - * - * These are initialized in an initcall and unchanged thereafter. - */ -static int host_supports_tls = -1; -int host_gdt_entry_tls_min; - -int do_set_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_set_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_SET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -int do_get_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_get_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -/* - * sys_get_thread_area: get a yet unused TLS descriptor index. - * XXX: Consider leaving one free slot for glibc usage at first place. This must - * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else. - * - * Also, this must be tested when compiling in SKAS mode with dynamic linking - * and running against NPTL. - */ -static int get_free_idx(struct task_struct* task) -{ - struct thread_struct *t = &task->thread; - int idx; - - if (!t->arch.tls_array) - return GDT_ENTRY_TLS_MIN; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (!t->arch.tls_array[idx].present) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -static inline void clear_user_desc(struct user_desc* info) -{ - /* Postcondition: LDT_empty(info) returns true. */ - memset(info, 0, sizeof(*info)); - - /* - * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain - * indeed an empty user_desc. - */ - info->read_exec_only = 1; - info->seg_not_present = 1; -} - -#define O_FORCE 1 - -static int load_TLS(int flags, struct task_struct *to) -{ - int ret = 0; - int idx; - - for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { - struct uml_tls_struct* curr = - &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; - - /* - * Actually, now if it wasn't flushed it gets cleared and - * flushed to the host, which will clear it. - */ - if (!curr->present) { - if (!curr->flushed) { - clear_user_desc(&curr->tls); - curr->tls.entry_number = idx; - } else { - WARN_ON(!LDT_empty(&curr->tls)); - continue; - } - } - - if (!(flags & O_FORCE) && curr->flushed) - continue; - - ret = do_set_thread_area(&curr->tls); - if (ret) - goto out; - - curr->flushed = 1; - } -out: - return ret; -} - -/* - * Verify if we need to do a flush for the new process, i.e. if there are any - * present desc's, only if they haven't been flushed. - */ -static inline int needs_TLS_update(struct task_struct *task) -{ - int i; - int ret = 0; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Can't test curr->present, we may need to clear a descriptor - * which had a value. - */ - if (curr->flushed) - continue; - ret = 1; - break; - } - return ret; -} - -/* - * On a newly forked process, the TLS descriptors haven't yet been flushed. So - * we mark them as such and the first switch_to will do the job. - */ -void clear_flushed_tls(struct task_struct *task) -{ - int i; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Still correct to do this, if it wasn't present on the host it - * will remain as flushed as it was. - */ - if (!curr->present) - continue; - - curr->flushed = 0; - } -} - -/* - * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a - * common host process. So this is needed in SKAS0 too. - * - * However, if each thread had a different host process (and this was discussed - * for SMP support) this won't be needed. - * - * And this will not need be used when (and if) we'll add support to the host - * SKAS patch. - */ - -int arch_switch_tls(struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - /* - * We have no need whatsoever to switch TLS for kernel threads; beyond - * that, that would also result in us calling os_set_thread_area with - * userspace_pid[cpu] == 0, which gives an error. - */ - if (likely(to->mm)) - return load_TLS(O_FORCE, to); - - return 0; -} - -static int set_tls_entry(struct task_struct* task, struct user_desc *info, - int idx, int flushed) -{ - struct thread_struct *t = &task->thread; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed; - - return 0; -} - -int arch_copy_tls(struct task_struct *new) -{ - struct user_desc info; - int idx, ret = -EFAULT; - - if (copy_from_user(&info, - (void __user *) UPT_ESI(&new->thread.regs.regs), - sizeof(info))) - goto out; - - ret = -EINVAL; - if (LDT_empty(&info)) - goto out; - - idx = info.entry_number; - - ret = set_tls_entry(new, &info, idx, 0); -out: - return ret; -} - -/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ -static int get_tls_entry(struct task_struct *task, struct user_desc *info, - int idx) -{ - struct thread_struct *t = &task->thread; - - if (!t->arch.tls_array) - goto clear; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present) - goto clear; - - *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; - -out: - /* - * Temporary debugging check, to make sure that things have been - * flushed. This could be triggered if load_TLS() failed. - */ - if (unlikely(task == current && - !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { - printk(KERN_ERR "get_tls_entry: task with pid %d got here " - "without flushed TLS.", current->pid); - } - - return 0; -clear: - /* - * When the TLS entry has not been set, the values read to user in the - * tls_array are 0 (because it's cleared at boot, see - * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. - */ - clear_user_desc(info); - info->entry_number = idx; - goto out; -} - -int sys_set_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - idx = info.entry_number; - - if (idx == -1) { - idx = get_free_idx(current); - if (idx < 0) - return idx; - info.entry_number = idx; - /* Tell the user which slot we chose for him.*/ - if (put_user(idx, &user_desc->entry_number)) - return -EFAULT; - } - - ret = do_set_thread_area(&info); - if (ret) - return ret; - return set_tls_entry(current, &info, idx, 1); -} - -/* - * Perform set_thread_area on behalf of the traced child. - * Note: error handling is not done on the deferred load, and this differ from - * i386. However the only possible error are caused by bugs. - */ -int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - - if (!host_supports_tls) - return -EIO; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - return set_tls_entry(child, &info, idx, 0); -} - -int sys_get_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (get_user(idx, &user_desc->entry_number)) - return -EFAULT; - - ret = get_tls_entry(current, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; - -out: - return ret; -} - -/* - * Perform get_thread_area on behalf of the traced child. - */ -int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - int ret; - - if (!host_supports_tls) - return -EIO; - - ret = get_tls_entry(child, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; -out: - return ret; -} - -/* - * This code is really i386-only, but it detects and logs x86_64 GDT indexes - * if a 32-bit UML is running on a 64-bit host. - */ -static int __init __setup_host_supports_tls(void) -{ - check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); - if (host_supports_tls) { - printk(KERN_INFO "Host TLS support detected\n"); - printk(KERN_INFO "Detected host type: "); - switch (host_gdt_entry_tls_min) { - case GDT_ENTRY_TLS_MIN_I386: - printk(KERN_CONT "i386"); - break; - case GDT_ENTRY_TLS_MIN_X86_64: - printk(KERN_CONT "x86_64"); - break; - } - printk(KERN_CONT " (GDT indexes %d to %d)\n", - host_gdt_entry_tls_min, - host_gdt_entry_tls_min + GDT_ENTRY_TLS_ENTRIES); - } else - printk(KERN_ERR " Host TLS support NOT detected! " - "TLS support inside UML will not work\n"); - return 0; -} - -__initcall(__setup_host_supports_tls); diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c deleted file mode 100644 index 5f883bf..0000000 --- a/arch/um/sys-i386/user-offsets.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_CR2, sigcontext, cr2); - - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); - - DEFINE(HOST_IP, EIP); - DEFINE(HOST_SP, UESP); - DEFINE(HOST_EFLAGS, EFL); - DEFINE(HOST_EAX, EAX); - DEFINE(HOST_EBX, EBX); - DEFINE(HOST_ECX, ECX); - DEFINE(HOST_EDX, EDX); - DEFINE(HOST_ESI, ESI); - DEFINE(HOST_EDI, EDI); - DEFINE(HOST_EBP, EBP); - DEFINE(HOST_CS, CS); - DEFINE(HOST_SS, SS); - DEFINE(HOST_DS, DS); - DEFINE(HOST_FS, FS); - DEFINE(HOST_ES, ES); - DEFINE(HOST_GS, GS); - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); - - /* XXX Duplicated between i386 and x86_64 */ - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} diff --git a/arch/um/sys-x86/Makefile b/arch/um/sys-x86/Makefile new file mode 100644 index 0000000..671de0b --- /dev/null +++ b/arch/um/sys-x86/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +# + +ifeq ($(CONFIG_X86_32),y) + BITS := 32 +else + BITS := 64 +endif + +obj-y = bug.o bugs_$(BITS).o delay_$(BITS).o fault.o ksyms.o ldt.o \ + ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal_$(BITS).o \ + stub_$(BITS).o stub_segv_$(BITS).o syscalls_$(BITS).o \ + sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o mem_$(BITS).o + +ifeq ($(CONFIG_X86_32),y) + +obj-y += checksum_32.o +obj-$(CONFIG_BINFMT_ELF) += elfcore.o + +subarch-obj-y = lib/string_32.o lib/atomic64_32.o lib/atomic64_cx8_32.o +subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o +subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o +subarch-obj-$(CONFIG_MODULES) += kernel/module.o + +else + +obj-y += vdso/ + +subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ + lib/rwsem.o + +endif + +subarch-obj-$(CONFIG_MODULES) += kernel/module.o + +USER_OBJS := bugs_$(BITS).o ptrace_user.o fault.o + +extra-y += user-offsets.s +$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) + +UNPROFILE_OBJS := stub_segv.o +CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) + +include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-x86/bug.c b/arch/um/sys-x86/bug.c new file mode 100644 index 0000000..e8034e3 --- /dev/null +++ b/arch/um/sys-x86/bug.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL V2 + */ + +#include + +/* + * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because + * that's not relevant in skas mode. + */ + +int is_valid_bugaddr(unsigned long eip) +{ + unsigned short ud2; + + if (probe_kernel_address((unsigned short __user *)eip, ud2)) + return 0; + + return ud2 == 0x0b0f; +} diff --git a/arch/um/sys-x86/bugs_32.c b/arch/um/sys-x86/bugs_32.c new file mode 100644 index 0000000..7058e1f --- /dev/null +++ b/arch/um/sys-x86/bugs_32.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include "kern_util.h" +#include "longjmp.h" +#include "task.h" +#include "sysdep/ptrace.h" + +/* Set during early boot */ +static int host_has_cmov = 1; +static jmp_buf cmov_test_return; + +static void cmov_sigill_test_handler(int sig) +{ + host_has_cmov = 0; + longjmp(cmov_test_return, 1); +} + +void arch_check_bugs(void) +{ + struct sigaction old, new; + + printk(UM_KERN_INFO "Checking for host processor cmov support..."); + new.sa_handler = cmov_sigill_test_handler; + + /* Make sure that SIGILL is enabled after the handler longjmps back */ + new.sa_flags = SA_NODEFER; + sigemptyset(&new.sa_mask); + sigaction(SIGILL, &new, &old); + + if (setjmp(cmov_test_return) == 0) { + unsigned long foo = 0; + __asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo)); + printk(UM_KERN_CONT "Yes\n"); + } else + printk(UM_KERN_CONT "No\n"); + + sigaction(SIGILL, &old, &new); +} + +void arch_examine_signal(int sig, struct uml_pt_regs *regs) +{ + unsigned char tmp[2]; + + /* + * This is testing for a cmov (0x0f 0x4x) instruction causing a + * SIGILL in init. + */ + if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) + return; + + if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) { + printk(UM_KERN_ERR "SIGILL in init, could not read " + "instructions!\n"); + return; + } + + if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) + return; + + if (host_has_cmov == 0) + printk(UM_KERN_ERR "SIGILL caused by cmov, which this " + "processor doesn't implement. Boot a filesystem " + "compiled for older processors"); + else if (host_has_cmov == 1) + printk(UM_KERN_ERR "SIGILL caused by cmov, which this " + "processor claims to implement"); + else + printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)", + host_has_cmov); +} diff --git a/arch/um/sys-x86/bugs_64.c b/arch/um/sys-x86/bugs_64.c new file mode 100644 index 0000000..44e02ba --- /dev/null +++ b/arch/um/sys-x86/bugs_64.c @@ -0,0 +1,15 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#include "sysdep/ptrace.h" + +void arch_check_bugs(void) +{ +} + +void arch_examine_signal(int sig, struct uml_pt_regs *regs) +{ +} diff --git a/arch/um/sys-x86/checksum_32.S b/arch/um/sys-x86/checksum_32.S new file mode 100644 index 0000000..f058d2f --- /dev/null +++ b/arch/um/sys-x86/checksum_32.S @@ -0,0 +1,458 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, + * Arnt Gulbrandsen, + * Tom May, + * Pentium Pro/II routines: + * Alexander Kjeldaas + * Finn Arne Gangstad + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception + * handling. + * Andi Kleen, add zeroing on error + * converted to pure assembler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +/* +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) + */ + +.text +.align 4 +.globl csum_partial + +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM + + /* + * Experiments with Ethernet and SLIP connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. We get at + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. + * Fortunately, it is easy to convert 2-byte alignment to 4-byte + * alignment for the unrolled loop. + */ +csum_partial: + pushl %esi + pushl %ebx + movl 20(%esp),%eax # Function arg: unsigned int sum + movl 16(%esp),%ecx # Function arg: int len + movl 12(%esp),%esi # Function arg: unsigned char *buff + testl $2, %esi # Check alignment. + jz 2f # Jump if alignment is ok. + subl $2, %ecx # Alignment uses up two bytes. + jae 1f # Jump if we had at least two bytes. + addl $2, %ecx # ecx was < 2. Deal with it. + jmp 4f +1: movw (%esi), %bx + addl $2, %esi + addw %bx, %ax + adcl $0, %eax +2: + movl %ecx, %edx + shrl $5, %ecx + jz 2f + testl %esi, %esi +1: movl (%esi), %ebx + adcl %ebx, %eax + movl 4(%esi), %ebx + adcl %ebx, %eax + movl 8(%esi), %ebx + adcl %ebx, %eax + movl 12(%esi), %ebx + adcl %ebx, %eax + movl 16(%esi), %ebx + adcl %ebx, %eax + movl 20(%esi), %ebx + adcl %ebx, %eax + movl 24(%esi), %ebx + adcl %ebx, %eax + movl 28(%esi), %ebx + adcl %ebx, %eax + lea 32(%esi), %esi + dec %ecx + jne 1b + adcl $0, %eax +2: movl %edx, %ecx + andl $0x1c, %edx + je 4f + shrl $2, %edx # This clears CF +3: adcl (%esi), %eax + lea 4(%esi), %esi + dec %edx + jne 3b + adcl $0, %eax +4: andl $3, %ecx + jz 7f + cmpl $2, %ecx + jb 5f + movw (%esi),%cx + leal 2(%esi),%esi + je 6f + shll $16,%ecx +5: movb (%esi),%cl +6: addl %ecx,%eax + adcl $0, %eax +7: + popl %ebx + popl %esi + ret + +#else + +/* Version for PentiumII/PPro */ + +csum_partial: + pushl %esi + pushl %ebx + movl 20(%esp),%eax # Function arg: unsigned int sum + movl 16(%esp),%ecx # Function arg: int len + movl 12(%esp),%esi # Function arg: const unsigned char *buf + + testl $2, %esi + jnz 30f +10: + movl %ecx, %edx + movl %ecx, %ebx + andl $0x7c, %ebx + shrl $7, %ecx + addl %ebx,%esi + shrl $2, %ebx + negl %ebx + lea 45f(%ebx,%ebx,2), %ebx + testl %esi, %esi + jmp *%ebx + + # Handle 2-byte-aligned regions +20: addw (%esi), %ax + lea 2(%esi), %esi + adcl $0, %eax + jmp 10b + +30: subl $2, %ecx + ja 20b + je 32f + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned + addl %ebx, %eax + adcl $0, %eax + jmp 80f +32: + addw (%esi), %ax # csumming 2 bytes, 2-aligned + adcl $0, %eax + jmp 80f + +40: + addl -128(%esi), %eax + adcl -124(%esi), %eax + adcl -120(%esi), %eax + adcl -116(%esi), %eax + adcl -112(%esi), %eax + adcl -108(%esi), %eax + adcl -104(%esi), %eax + adcl -100(%esi), %eax + adcl -96(%esi), %eax + adcl -92(%esi), %eax + adcl -88(%esi), %eax + adcl -84(%esi), %eax + adcl -80(%esi), %eax + adcl -76(%esi), %eax + adcl -72(%esi), %eax + adcl -68(%esi), %eax + adcl -64(%esi), %eax + adcl -60(%esi), %eax + adcl -56(%esi), %eax + adcl -52(%esi), %eax + adcl -48(%esi), %eax + adcl -44(%esi), %eax + adcl -40(%esi), %eax + adcl -36(%esi), %eax + adcl -32(%esi), %eax + adcl -28(%esi), %eax + adcl -24(%esi), %eax + adcl -20(%esi), %eax + adcl -16(%esi), %eax + adcl -12(%esi), %eax + adcl -8(%esi), %eax + adcl -4(%esi), %eax +45: + lea 128(%esi), %esi + adcl $0, %eax + dec %ecx + jge 40b + movl %edx, %ecx +50: andl $3, %ecx + jz 80f + + # Handle the last 1-3 bytes without jumping + notl %ecx # 1->2, 2->1, 3->0, higher bits are masked + movl $0xffffff,%ebx # by the shll and shrl instructions + shll $3,%ecx + shrl %cl,%ebx + andl -128(%esi),%ebx # esi is 4-aligned so should be ok + addl %ebx,%eax + adcl $0,%eax +80: + popl %ebx + popl %esi + ret + +#endif + +/* +unsigned int csum_partial_copy_generic (const char *src, char *dst, + int len, int sum, int *src_err_ptr, int *dst_err_ptr) + */ + +/* + * Copy from ds while checksumming, otherwise like csum_partial + * + * The macros SRC and DST specify the type of access for the instruction. + * thus we can call a custom exception handler for all access types. + * + * FIXME: could someone double-check whether I haven't mixed up some SRC and + * DST definitions? It's damn hard to trigger all cases. I hope I got + * them all but there's no guarantee. + */ + +#define SRC(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6001f ; \ + .previous + +#define DST(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6002f ; \ + .previous + +.align 4 + +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM + +#define ARGBASE 16 +#define FP 12 + +csum_partial_copy_generic_i386: + subl $4,%esp + pushl %edi + pushl %esi + pushl %ebx + movl ARGBASE+16(%esp),%eax # sum + movl ARGBASE+12(%esp),%ecx # len + movl ARGBASE+4(%esp),%esi # src + movl ARGBASE+8(%esp),%edi # dst + + testl $2, %edi # Check alignment. + jz 2f # Jump if alignment is ok. + subl $2, %ecx # Alignment uses up two bytes. + jae 1f # Jump if we had at least two bytes. + addl $2, %ecx # ecx was < 2. Deal with it. + jmp 4f +SRC(1: movw (%esi), %bx ) + addl $2, %esi +DST( movw %bx, (%edi) ) + addl $2, %edi + addw %bx, %ax + adcl $0, %eax +2: + movl %ecx, FP(%esp) + shrl $5, %ecx + jz 2f + testl %esi, %esi +SRC(1: movl (%esi), %ebx ) +SRC( movl 4(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, (%edi) ) + adcl %edx, %eax +DST( movl %edx, 4(%edi) ) + +SRC( movl 8(%esi), %ebx ) +SRC( movl 12(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 8(%edi) ) + adcl %edx, %eax +DST( movl %edx, 12(%edi) ) + +SRC( movl 16(%esi), %ebx ) +SRC( movl 20(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 16(%edi) ) + adcl %edx, %eax +DST( movl %edx, 20(%edi) ) + +SRC( movl 24(%esi), %ebx ) +SRC( movl 28(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 24(%edi) ) + adcl %edx, %eax +DST( movl %edx, 28(%edi) ) + + lea 32(%esi), %esi + lea 32(%edi), %edi + dec %ecx + jne 1b + adcl $0, %eax +2: movl FP(%esp), %edx + movl %edx, %ecx + andl $0x1c, %edx + je 4f + shrl $2, %edx # This clears CF +SRC(3: movl (%esi), %ebx ) + adcl %ebx, %eax +DST( movl %ebx, (%edi) ) + lea 4(%esi), %esi + lea 4(%edi), %edi + dec %edx + jne 3b + adcl $0, %eax +4: andl $3, %ecx + jz 7f + cmpl $2, %ecx + jb 5f +SRC( movw (%esi), %cx ) + leal 2(%esi), %esi +DST( movw %cx, (%edi) ) + leal 2(%edi), %edi + je 6f + shll $16,%ecx +SRC(5: movb (%esi), %cl ) +DST( movb %cl, (%edi) ) +6: addl %ecx, %eax + adcl $0, %eax +7: +5000: + +# Exception handler: +.section .fixup, "ax" + +6001: + movl ARGBASE+20(%esp), %ebx # src_err_ptr + movl $-EFAULT, (%ebx) + + # zero the complete destination - computing the rest + # is too much work + movl ARGBASE+8(%esp), %edi # dst + movl ARGBASE+12(%esp), %ecx # len + xorl %eax,%eax + rep ; stosb + + jmp 5000b + +6002: + movl ARGBASE+24(%esp), %ebx # dst_err_ptr + movl $-EFAULT,(%ebx) + jmp 5000b + +.previous + + popl %ebx + popl %esi + popl %edi + popl %ecx # equivalent to addl $4,%esp + ret + +#else + +/* Version for PentiumII/PPro */ + +#define ROUND1(x) \ + SRC(movl x(%esi), %ebx ) ; \ + addl %ebx, %eax ; \ + DST(movl %ebx, x(%edi) ) ; + +#define ROUND(x) \ + SRC(movl x(%esi), %ebx ) ; \ + adcl %ebx, %eax ; \ + DST(movl %ebx, x(%edi) ) ; + +#define ARGBASE 12 + +csum_partial_copy_generic_i386: + pushl %ebx + pushl %edi + pushl %esi + movl ARGBASE+4(%esp),%esi #src + movl ARGBASE+8(%esp),%edi #dst + movl ARGBASE+12(%esp),%ecx #len + movl ARGBASE+16(%esp),%eax #sum +# movl %ecx, %edx + movl %ecx, %ebx + movl %esi, %edx + shrl $6, %ecx + andl $0x3c, %ebx + negl %ebx + subl %ebx, %esi + subl %ebx, %edi + lea -1(%esi),%edx + andl $-32,%edx + lea 3f(%ebx,%ebx), %ebx + testl %esi, %esi + jmp *%ebx +1: addl $64,%esi + addl $64,%edi + SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) + ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) + ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) + ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) + ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) +3: adcl $0,%eax + addl $64, %edx + dec %ecx + jge 1b +4: movl ARGBASE+12(%esp),%edx #len + andl $3, %edx + jz 7f + cmpl $2, %edx + jb 5f +SRC( movw (%esi), %dx ) + leal 2(%esi), %esi +DST( movw %dx, (%edi) ) + leal 2(%edi), %edi + je 6f + shll $16,%edx +5: +SRC( movb (%esi), %dl ) +DST( movb %dl, (%edi) ) +6: addl %edx, %eax + adcl $0, %eax +7: +.section .fixup, "ax" +6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr + movl $-EFAULT, (%ebx) + # zero the complete destination (computing the rest is too much work) + movl ARGBASE+8(%esp),%edi # dst + movl ARGBASE+12(%esp),%ecx # len + xorl %eax,%eax + rep; stosb + jmp 7b +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr + movl $-EFAULT, (%ebx) + jmp 7b +.previous + + popl %esi + popl %edi + popl %ebx + ret + +#undef ROUND +#undef ROUND1 + +#endif diff --git a/arch/um/sys-x86/delay_32.c b/arch/um/sys-x86/delay_32.c new file mode 100644 index 0000000..f3fe1a6 --- /dev/null +++ b/arch/um/sys-x86/delay_32.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * Mostly copied from arch/x86/lib/delay.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +void __delay(unsigned long loops) +{ + asm volatile( + "test %0,%0\n" + "jz 3f\n" + "jmp 1f\n" + + ".align 16\n" + "1: jmp 2f\n" + + ".align 16\n" + "2: dec %0\n" + " jnz 2b\n" + "3: dec %0\n" + + : /* we don't need output */ + : "a" (loops) + ); +} +EXPORT_SYMBOL(__delay); + +inline void __const_udelay(unsigned long xloops) +{ + int d0; + + xloops *= 4; + asm("mull %%edx" + : "=d" (xloops), "=&a" (d0) + : "1" (xloops), "0" + (loops_per_jiffy * (HZ/4))); + + __delay(++xloops); +} +EXPORT_SYMBOL(__const_udelay); + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ +} +EXPORT_SYMBOL(__udelay); + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ +} +EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86/delay_64.c b/arch/um/sys-x86/delay_64.c new file mode 100644 index 0000000..f3fe1a6 --- /dev/null +++ b/arch/um/sys-x86/delay_64.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * Mostly copied from arch/x86/lib/delay.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +void __delay(unsigned long loops) +{ + asm volatile( + "test %0,%0\n" + "jz 3f\n" + "jmp 1f\n" + + ".align 16\n" + "1: jmp 2f\n" + + ".align 16\n" + "2: dec %0\n" + " jnz 2b\n" + "3: dec %0\n" + + : /* we don't need output */ + : "a" (loops) + ); +} +EXPORT_SYMBOL(__delay); + +inline void __const_udelay(unsigned long xloops) +{ + int d0; + + xloops *= 4; + asm("mull %%edx" + : "=d" (xloops), "=&a" (d0) + : "1" (xloops), "0" + (loops_per_jiffy * (HZ/4))); + + __delay(++xloops); +} +EXPORT_SYMBOL(__const_udelay); + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ +} +EXPORT_SYMBOL(__udelay); + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ +} +EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86/elfcore.c b/arch/um/sys-x86/elfcore.c new file mode 100644 index 0000000..6bb49b6 --- /dev/null +++ b/arch/um/sys-x86/elfcore.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +#include + + +Elf32_Half elf_core_extra_phdrs(void) +{ + return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; +} + +int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, + unsigned long limit) +{ + if ( vsyscall_ehdr ) { + const struct elfhdr *const ehdrp = + (struct elfhdr *) vsyscall_ehdr; + const struct elf_phdr *const phdrp = + (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); + int i; + Elf32_Off ofs = 0; + + for (i = 0; i < ehdrp->e_phnum; ++i) { + struct elf_phdr phdr = phdrp[i]; + + if (phdr.p_type == PT_LOAD) { + ofs = phdr.p_offset = offset; + offset += phdr.p_filesz; + } else { + phdr.p_offset += ofs; + } + phdr.p_paddr = 0; /* match other core phdrs */ + *size += sizeof(phdr); + if (*size > limit + || !dump_write(file, &phdr, sizeof(phdr))) + return 0; + } + } + return 1; +} + +int elf_core_write_extra_data(struct file *file, size_t *size, + unsigned long limit) +{ + if ( vsyscall_ehdr ) { + const struct elfhdr *const ehdrp = + (struct elfhdr *) vsyscall_ehdr; + const struct elf_phdr *const phdrp = + (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); + int i; + + for (i = 0; i < ehdrp->e_phnum; ++i) { + if (phdrp[i].p_type == PT_LOAD) { + void *addr = (void *) phdrp[i].p_vaddr; + size_t filesz = phdrp[i].p_filesz; + + *size += filesz; + if (*size > limit + || !dump_write(file, addr, filesz)) + return 0; + } + } + } + return 1; +} + +size_t elf_core_extra_data_size(void) +{ + if ( vsyscall_ehdr ) { + const struct elfhdr *const ehdrp = + (struct elfhdr *)vsyscall_ehdr; + const struct elf_phdr *const phdrp = + (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); + int i; + + for (i = 0; i < ehdrp->e_phnum; ++i) + if (phdrp[i].p_type == PT_LOAD) + return (size_t) phdrp[i].p_filesz; + } + return 0; +} diff --git a/arch/um/sys-x86/fault.c b/arch/um/sys-x86/fault.c new file mode 100644 index 0000000..d670f68 --- /dev/null +++ b/arch/um/sys-x86/fault.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include "sysdep/ptrace.h" + +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ +struct exception_table_entry +{ + unsigned long insn; + unsigned long fixup; +}; + +const struct exception_table_entry *search_exception_tables(unsigned long add); + +/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ +int arch_fixup(unsigned long address, struct uml_pt_regs *regs) +{ + const struct exception_table_entry *fixup; + + fixup = search_exception_tables(address); + if (fixup != 0) { + UPT_IP(regs) = fixup->fixup; + return 1; + } + return 0; +} diff --git a/arch/um/sys-x86/ksyms.c b/arch/um/sys-x86/ksyms.c new file mode 100644 index 0000000..2e8f43e --- /dev/null +++ b/arch/um/sys-x86/ksyms.c @@ -0,0 +1,13 @@ +#include +#include +#include + +#ifndef CONFIG_X86_32 +/*XXX: we need them because they would be exported by x86_64 */ +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 +EXPORT_SYMBOL(memcpy); +#else +EXPORT_SYMBOL(__memcpy); +#endif +#endif +EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-x86/ldt.c b/arch/um/sys-x86/ldt.c new file mode 100644 index 0000000..3f2bf20 --- /dev/null +++ b/arch/um/sys-x86/ldt.c @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include "os.h" +#include "proc_mm.h" +#include "skas.h" +#include "skas_ptrace.h" +#include "sysdep/tls.h" + +extern int modify_ldt(int func, void *ptr, unsigned long bytecount); + +static long write_ldt_entry(struct mm_id *mm_idp, int func, + struct user_desc *desc, void **addr, int done) +{ + long res; + + if (proc_mm) { + /* + * This is a special handling for the case, that the mm to + * modify isn't current->active_mm. + * If this is called directly by modify_ldt, + * (current->active_mm->context.skas.u == mm_idp) + * will be true. So no call to __switch_mm(mm_idp) is done. + * If this is called in case of init_new_ldt or PTRACE_LDT, + * mm_idp won't belong to current->active_mm, but child->mm. + * So we need to switch child's mm into our userspace, then + * later switch back. + * + * Note: I'm unsure: should interrupts be disabled here? + */ + if (!current->active_mm || current->active_mm == &init_mm || + mm_idp != ¤t->active_mm->context.id) + __switch_mm(mm_idp); + } + + if (ptrace_ldt) { + struct ptrace_ldt ldt_op = (struct ptrace_ldt) { + .func = func, + .ptr = desc, + .bytecount = sizeof(*desc)}; + u32 cpu; + int pid; + + if (!proc_mm) + pid = mm_idp->u.pid; + else { + cpu = get_cpu(); + pid = userspace_pid[cpu]; + } + + res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); + + if (proc_mm) + put_cpu(); + } + else { + void *stub_addr; + res = syscall_stub_data(mm_idp, (unsigned long *)desc, + (sizeof(*desc) + sizeof(long) - 1) & + ~(sizeof(long) - 1), + addr, &stub_addr); + if (!res) { + unsigned long args[] = { func, + (unsigned long)stub_addr, + sizeof(*desc), + 0, 0, 0 }; + res = run_syscall_stub(mm_idp, __NR_modify_ldt, args, + 0, addr, done); + } + } + + if (proc_mm) { + /* + * This is the second part of special handling, that makes + * PTRACE_LDT possible to implement. + */ + if (current->active_mm && current->active_mm != &init_mm && + mm_idp != ¤t->active_mm->context.id) + __switch_mm(¤t->active_mm->context.id); + } + + return res; +} + +static long read_ldt_from_host(void __user * ptr, unsigned long bytecount) +{ + int res, n; + struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) { + .func = 0, + .bytecount = bytecount, + .ptr = kmalloc(bytecount, GFP_KERNEL)}; + u32 cpu; + + if (ptrace_ldt.ptr == NULL) + return -ENOMEM; + + /* + * This is called from sys_modify_ldt only, so userspace_pid gives + * us the right number + */ + + cpu = get_cpu(); + res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); + put_cpu(); + if (res < 0) + goto out; + + n = copy_to_user(ptr, ptrace_ldt.ptr, res); + if (n != 0) + res = -EFAULT; + + out: + kfree(ptrace_ldt.ptr); + + return res; +} + +/* + * In skas mode, we hold our own ldt data in UML. + * Thus, the code implementing sys_modify_ldt_skas + * is very similar to (and mostly stolen from) sys_modify_ldt + * for arch/i386/kernel/ldt.c + * The routines copied and modified in part are: + * - read_ldt + * - read_default_ldt + * - write_ldt + * - sys_modify_ldt_skas + */ + +static int read_ldt(void __user * ptr, unsigned long bytecount) +{ + int i, err = 0; + unsigned long size; + uml_ldt_t * ldt = ¤t->mm->context.ldt; + + if (!ldt->entry_count) + goto out; + if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) + bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; + err = bytecount; + + if (ptrace_ldt) + return read_ldt_from_host(ptr, bytecount); + + mutex_lock(&ldt->lock); + if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { + size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; + if (size > bytecount) + size = bytecount; + if (copy_to_user(ptr, ldt->u.entries, size)) + err = -EFAULT; + bytecount -= size; + ptr += size; + } + else { + for (i=0; ientry_count/LDT_ENTRIES_PER_PAGE && bytecount; + i++) { + size = PAGE_SIZE; + if (size > bytecount) + size = bytecount; + if (copy_to_user(ptr, ldt->u.pages[i], size)) { + err = -EFAULT; + break; + } + bytecount -= size; + ptr += size; + } + } + mutex_unlock(&ldt->lock); + + if (bytecount == 0 || err == -EFAULT) + goto out; + + if (clear_user(ptr, bytecount)) + err = -EFAULT; + +out: + return err; +} + +static int read_default_ldt(void __user * ptr, unsigned long bytecount) +{ + int err; + + if (bytecount > 5*LDT_ENTRY_SIZE) + bytecount = 5*LDT_ENTRY_SIZE; + + err = bytecount; + /* + * UML doesn't support lcall7 and lcall27. + * So, we don't really have a default ldt, but emulate + * an empty ldt of common host default ldt size. + */ + if (clear_user(ptr, bytecount)) + err = -EFAULT; + + return err; +} + +static int write_ldt(void __user * ptr, unsigned long bytecount, int func) +{ + uml_ldt_t * ldt = ¤t->mm->context.ldt; + struct mm_id * mm_idp = ¤t->mm->context.id; + int i, err; + struct user_desc ldt_info; + struct ldt_entry entry0, *ldt_p; + void *addr = NULL; + + err = -EINVAL; + if (bytecount != sizeof(ldt_info)) + goto out; + err = -EFAULT; + if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) + goto out; + + err = -EINVAL; + if (ldt_info.entry_number >= LDT_ENTRIES) + goto out; + if (ldt_info.contents == 3) { + if (func == 1) + goto out; + if (ldt_info.seg_not_present == 0) + goto out; + } + + if (!ptrace_ldt) + mutex_lock(&ldt->lock); + + err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); + if (err) + goto out_unlock; + else if (ptrace_ldt) { + /* With PTRACE_LDT available, this is used as a flag only */ + ldt->entry_count = 1; + goto out; + } + + if (ldt_info.entry_number >= ldt->entry_count && + ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { + for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; + i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; + i++) { + if (i == 0) + memcpy(&entry0, ldt->u.entries, + sizeof(entry0)); + ldt->u.pages[i] = (struct ldt_entry *) + __get_free_page(GFP_KERNEL|__GFP_ZERO); + if (!ldt->u.pages[i]) { + err = -ENOMEM; + /* Undo the change in host */ + memset(&ldt_info, 0, sizeof(ldt_info)); + write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); + goto out_unlock; + } + if (i == 0) { + memcpy(ldt->u.pages[0], &entry0, + sizeof(entry0)); + memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, + sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); + } + ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; + } + } + if (ldt->entry_count <= ldt_info.entry_number) + ldt->entry_count = ldt_info.entry_number + 1; + + if (ldt->entry_count <= LDT_DIRECT_ENTRIES) + ldt_p = ldt->u.entries + ldt_info.entry_number; + else + ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + + ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; + + if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && + (func == 1 || LDT_empty(&ldt_info))) { + ldt_p->a = 0; + ldt_p->b = 0; + } + else{ + if (func == 1) + ldt_info.useable = 0; + ldt_p->a = LDT_entry_a(&ldt_info); + ldt_p->b = LDT_entry_b(&ldt_info); + } + err = 0; + +out_unlock: + mutex_unlock(&ldt->lock); +out: + return err; +} + +static long do_modify_ldt_skas(int func, void __user *ptr, + unsigned long bytecount) +{ + int ret = -ENOSYS; + + switch (func) { + case 0: + ret = read_ldt(ptr, bytecount); + break; + case 1: + case 0x11: + ret = write_ldt(ptr, bytecount, func); + break; + case 2: + ret = read_default_ldt(ptr, bytecount); + break; + } + return ret; +} + +static DEFINE_SPINLOCK(host_ldt_lock); +static short dummy_list[9] = {0, -1}; +static short * host_ldt_entries = NULL; + +static void ldt_get_host_info(void) +{ + long ret; + struct ldt_entry * ldt; + short *tmp; + int i, size, k, order; + + spin_lock(&host_ldt_lock); + + if (host_ldt_entries != NULL) { + spin_unlock(&host_ldt_lock); + return; + } + host_ldt_entries = dummy_list+1; + + spin_unlock(&host_ldt_lock); + + for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) + ; + + ldt = (struct ldt_entry *) + __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); + if (ldt == NULL) { + printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " + "for host ldt\n"); + return; + } + + ret = modify_ldt(0, ldt, (1<ldt.lock); + + if (!from_mm) { + memset(&desc, 0, sizeof(desc)); + /* + * We have to initialize a clean ldt. + */ + if (proc_mm) { + /* + * If the new mm was created using proc_mm, host's + * default-ldt currently is assigned, which normally + * contains the call-gates for lcall7 and lcall27. + * To remove these gates, we simply write an empty + * entry as number 0 to the host. + */ + err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1); + } + else{ + /* + * Now we try to retrieve info about the ldt, we + * inherited from the host. All ldt-entries found + * will be reset in the following loop + */ + ldt_get_host_info(); + for (num_p=host_ldt_entries; *num_p != -1; num_p++) { + desc.entry_number = *num_p; + err = write_ldt_entry(&new_mm->id, 1, &desc, + &addr, *(num_p + 1) == -1); + if (err) + break; + } + } + new_mm->ldt.entry_count = 0; + + goto out; + } + + if (proc_mm) { + /* + * We have a valid from_mm, so we now have to copy the LDT of + * from_mm to new_mm, because using proc_mm an new mm with + * an empty/default LDT was created in new_mm() + */ + copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, + .u = + { .copy_segments = + from_mm->id.u.mm_fd } } ); + i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); + if (i != sizeof(copy)) + printk(KERN_ERR "new_mm : /proc/mm copy_segments " + "failed, err = %d\n", -i); + } + + if (!ptrace_ldt) { + /* + * Our local LDT is used to supply the data for + * modify_ldt(READLDT), if PTRACE_LDT isn't available, + * i.e., we have to use the stub for modify_ldt, which + * can't handle the big read buffer of up to 64kB. + */ + mutex_lock(&from_mm->ldt.lock); + if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) + memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, + sizeof(new_mm->ldt.u.entries)); + else { + i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; + while (i-->0) { + page = __get_free_page(GFP_KERNEL|__GFP_ZERO); + if (!page) { + err = -ENOMEM; + break; + } + new_mm->ldt.u.pages[i] = + (struct ldt_entry *) page; + memcpy(new_mm->ldt.u.pages[i], + from_mm->ldt.u.pages[i], PAGE_SIZE); + } + } + new_mm->ldt.entry_count = from_mm->ldt.entry_count; + mutex_unlock(&from_mm->ldt.lock); + } + + out: + return err; +} + + +void free_ldt(struct mm_context *mm) +{ + int i; + + if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { + i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; + while (i-- > 0) + free_page((long) mm->ldt.u.pages[i]); + } + mm->ldt.entry_count = 0; +} + +int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) +{ + return do_modify_ldt_skas(func, ptr, bytecount); +} diff --git a/arch/um/sys-x86/mem_32.c b/arch/um/sys-x86/mem_32.c new file mode 100644 index 0000000..639900a --- /dev/null +++ b/arch/um/sys-x86/mem_32.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +static struct vm_area_struct gate_vma; + +static int __init gate_vma_init(void) +{ + if (!FIXADDR_USER_START) + return 0; + + gate_vma.vm_mm = NULL; + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; + gate_vma.vm_page_prot = __P101; + + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + gate_vma.vm_flags |= VM_ALWAYSDUMP; + + return 0; +} +__initcall(gate_vma_init); + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return FIXADDR_USER_START ? &gate_vma : NULL; +} + +int in_gate_area_no_mm(unsigned long addr) +{ + if (!FIXADDR_USER_START) + return 0; + + if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) + return 1; + + return 0; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + struct vm_area_struct *vma = get_gate_vma(mm); + + if (!vma) + return 0; + + return (addr >= vma->vm_start) && (addr < vma->vm_end); +} diff --git a/arch/um/sys-x86/mem_64.c b/arch/um/sys-x86/mem_64.c new file mode 100644 index 0000000..5465187 --- /dev/null +++ b/arch/um/sys-x86/mem_64.c @@ -0,0 +1,26 @@ +#include "linux/mm.h" +#include "asm/page.h" +#include "asm/mman.h" + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm && vma->vm_start == um_vdso_addr) + return "[vdso]"; + + return NULL; +} + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return NULL; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + return 0; +} + +int in_gate_area_no_mm(unsigned long addr) +{ + return 0; +} diff --git a/arch/um/sys-x86/ptrace_32.c b/arch/um/sys-x86/ptrace_32.c new file mode 100644 index 0000000..a174fde --- /dev/null +++ b/arch/um/sys-x86/ptrace_32.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include "linux/mm.h" +#include "linux/sched.h" +#include "asm/uaccess.h" +#include "skas.h" + +extern int arch_switch_tls(struct task_struct *to); + +void arch_switch_to(struct task_struct *to) +{ + int err = arch_switch_tls(to); + if (!err) + return; + + if (err != -EINVAL) + printk(KERN_WARNING "arch_switch_tls failed, errno %d, " + "not EINVAL\n", -err); + else + printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); +} + +int is_syscall(unsigned long addr) +{ + unsigned short instr; + int n; + + n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); + if (n) { + /* access_process_vm() grants access to vsyscall and stub, + * while copy_from_user doesn't. Maybe access_process_vm is + * slow, but that doesn't matter, since it will be called only + * in case of singlestepping, if copy_from_user failed. + */ + n = access_process_vm(current, addr, &instr, sizeof(instr), 0); + if (n != sizeof(instr)) { + printk(KERN_ERR "is_syscall : failed to read " + "instruction from 0x%lx\n", addr); + return 1; + } + } + /* int 0x80 or sysenter */ + return (instr == 0x80cd) || (instr == 0x340f); +} + +/* determines which flags the user has access to. */ +/* 1 = access 0 = no access */ +#define FLAG_MASK 0x00044dd5 + +static const int reg_offsets[] = { + [EBX] = HOST_EBX, + [ECX] = HOST_ECX, + [EDX] = HOST_EDX, + [ESI] = HOST_ESI, + [EDI] = HOST_EDI, + [EBP] = HOST_EBP, + [EAX] = HOST_EAX, + [DS] = HOST_DS, + [ES] = HOST_ES, + [FS] = HOST_FS, + [GS] = HOST_GS, + [EIP] = HOST_IP, + [CS] = HOST_CS, + [EFL] = HOST_EFLAGS, + [UESP] = HOST_SP, + [SS] = HOST_SS, +}; + +int putreg(struct task_struct *child, int regno, unsigned long value) +{ + regno >>= 2; + switch (regno) { + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EAX: + case EIP: + case UESP: + break; + case FS: + if (value && (value & 3) != 3) + return -EIO; + break; + case GS: + if (value && (value & 3) != 3) + return -EIO; + break; + case DS: + case ES: + if (value && (value & 3) != 3) + return -EIO; + value &= 0xffff; + break; + case SS: + case CS: + if ((value & 3) != 3) + return -EIO; + value &= 0xffff; + break; + case EFL: + value &= FLAG_MASK; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + case ORIG_EAX: + child->thread.regs.regs.syscall = value; + return 0; + default : + panic("Bad register in putreg() : %d\n", regno); + } + child->thread.regs.regs.gp[reg_offsets[regno]] = value; + return 0; +} + +int poke_user(struct task_struct *child, long addr, long data) +{ + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; +} + +unsigned long getreg(struct task_struct *child, int regno) +{ + unsigned long mask = ~0UL; + + regno >>= 2; + switch (regno) { + case ORIG_EAX: + return child->thread.regs.regs.syscall; + case FS: + case GS: + case DS: + case ES: + case SS: + case CS: + mask = 0xffff; + break; + case EIP: + case UESP: + case EAX: + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EFL: + break; + default: + panic("Bad register in getreg() : %d\n", regno); + } + return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; +} + +/* read the word at location addr in the USER area. */ +int peek_user(struct task_struct *child, long addr, long data) +{ + unsigned long tmp; + + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if (addr < MAX_REG_OFFSET) { + tmp = getreg(child, addr); + } + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long __user *) data); +} + +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +{ + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + struct user_i387_struct fpregs; + + err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs); + if (err) + return err; + + n = copy_to_user(buf, &fpregs, sizeof(fpregs)); + if(n > 0) + return -EFAULT; + + return n; +} + +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +{ + int n, cpu = ((struct thread_info *) child->stack)->cpu; + struct user_i387_struct fpregs; + + n = copy_from_user(&fpregs, buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; + + return restore_fp_registers(userspace_pid[cpu], + (unsigned long *) &fpregs); +} + +static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +{ + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + struct user_fxsr_struct fpregs; + + err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); + if (err) + return err; + + n = copy_to_user(buf, &fpregs, sizeof(fpregs)); + if(n > 0) + return -EFAULT; + + return n; +} + +static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +{ + int n, cpu = ((struct thread_info *) child->stack)->cpu; + struct user_fxsr_struct fpregs; + + n = copy_from_user(&fpregs, buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; + + return restore_fpx_registers(userspace_pid[cpu], + (unsigned long *) &fpregs); +} + +long subarch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) +{ + int ret = -EIO; + void __user *datap = (void __user *) data; + switch (request) { + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(datap, child); + break; + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(datap, child); + break; + case PTRACE_GETFPXREGS: /* Get the child FPU state. */ + ret = get_fpxregs(datap, child); + break; + case PTRACE_SETFPXREGS: /* Set the child FPU state. */ + ret = set_fpxregs(datap, child); + break; + default: + ret = -EIO; + } + return ret; +} diff --git a/arch/um/sys-x86/ptrace_64.c b/arch/um/sys-x86/ptrace_64.c new file mode 100644 index 0000000..44e68e0 --- /dev/null +++ b/arch/um/sys-x86/ptrace_64.c @@ -0,0 +1,271 @@ +/* + * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * + * Licensed under the GPL + */ + +#include +#include +#include +#define __FRAME_OFFSETS +#include +#include + +/* + * determines which flags the user has access to. + * 1 = access 0 = no access + */ +#define FLAG_MASK 0x44dd5UL + +static const int reg_offsets[] = +{ + [R8 >> 3] = HOST_R8, + [R9 >> 3] = HOST_R9, + [R10 >> 3] = HOST_R10, + [R11 >> 3] = HOST_R11, + [R12 >> 3] = HOST_R12, + [R13 >> 3] = HOST_R13, + [R14 >> 3] = HOST_R14, + [R15 >> 3] = HOST_R15, + [RIP >> 3] = HOST_IP, + [RSP >> 3] = HOST_SP, + [RAX >> 3] = HOST_RAX, + [RBX >> 3] = HOST_RBX, + [RCX >> 3] = HOST_RCX, + [RDX >> 3] = HOST_RDX, + [RSI >> 3] = HOST_RSI, + [RDI >> 3] = HOST_RDI, + [RBP >> 3] = HOST_RBP, + [CS >> 3] = HOST_CS, + [SS >> 3] = HOST_SS, + [FS_BASE >> 3] = HOST_FS_BASE, + [GS_BASE >> 3] = HOST_GS_BASE, + [DS >> 3] = HOST_DS, + [ES >> 3] = HOST_ES, + [FS >> 3] = HOST_FS, + [GS >> 3] = HOST_GS, + [EFLAGS >> 3] = HOST_EFLAGS, + [ORIG_RAX >> 3] = HOST_ORIG_RAX, +}; + +int putreg(struct task_struct *child, int regno, unsigned long value) +{ +#ifdef TIF_IA32 + /* + * Some code in the 64bit emulation may not be 64bit clean. + * Don't take any chances. + */ + if (test_tsk_thread_flag(child, TIF_IA32)) + value &= 0xffffffff; +#endif + switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + break; + + case FS: + case GS: + case DS: + case ES: + case SS: + case CS: + if (value && (value & 3) != 3) + return -EIO; + value &= 0xffff; + break; + + case FS_BASE: + case GS_BASE: + if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) + return -EIO; + break; + + case EFLAGS: + value &= FLAG_MASK; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + + default: + panic("Bad register in putreg(): %d\n", regno); + } + + child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; + return 0; +} + +int poke_user(struct task_struct *child, long addr, long data) +{ + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; +} + +unsigned long getreg(struct task_struct *child, int regno) +{ + unsigned long mask = ~0UL; +#ifdef TIF_IA32 + if (test_tsk_thread_flag(child, TIF_IA32)) + mask = 0xffffffff; +#endif + switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + case EFLAGS: + case FS_BASE: + case GS_BASE: + break; + case FS: + case GS: + case DS: + case ES: + case SS: + case CS: + mask = 0xffff; + break; + default: + panic("Bad register in getreg: %d\n", regno); + } + return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; +} + +int peek_user(struct task_struct *child, long addr, long data) +{ + /* read the word at location addr in the USER area. */ + unsigned long tmp; + + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if (addr < MAX_REG_OFFSET) + tmp = getreg(child, addr); + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); +} + +/* XXX Mostly copied from sys-i386 */ +int is_syscall(unsigned long addr) +{ + unsigned short instr; + int n; + + n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); + if (n) { + /* + * access_process_vm() grants access to vsyscall and stub, + * while copy_from_user doesn't. Maybe access_process_vm is + * slow, but that doesn't matter, since it will be called only + * in case of singlestepping, if copy_from_user failed. + */ + n = access_process_vm(current, addr, &instr, sizeof(instr), 0); + if (n != sizeof(instr)) { + printk("is_syscall : failed to read instruction from " + "0x%lx\n", addr); + return 1; + } + } + /* sysenter */ + return instr == 0x050f; +} + +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +{ + int err, n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; + + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + err = save_fp_registers(userspace_pid[cpu], fpregs); + if (err) + return err; + + n = copy_to_user(buf, fpregs, sizeof(fpregs)); + if (n > 0) + return -EFAULT; + + return n; +} + +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +{ + int n, cpu = ((struct thread_info *) child->stack)->cpu; + long fpregs[HOST_FP_SIZE]; + + BUG_ON(sizeof(*buf) != sizeof(fpregs)); + n = copy_from_user(fpregs, buf, sizeof(fpregs)); + if (n > 0) + return -EFAULT; + + return restore_fp_registers(userspace_pid[cpu], fpregs); +} + +long subarch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) +{ + int ret = -EIO; + void __user *datap = (void __user *) data; + + switch (request) { + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(datap, child); + break; + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(datap, child); + break; + case PTRACE_ARCH_PRCTL: + /* XXX Calls ptrace on the host - needs some SMP thinking */ + ret = arch_prctl(child, data, (void __user *) addr); + break; + } + + return ret; +} diff --git a/arch/um/sys-x86/ptrace_user.c b/arch/um/sys-x86/ptrace_user.c new file mode 100644 index 0000000..3960ca1 --- /dev/null +++ b/arch/um/sys-x86/ptrace_user.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include "ptrace_user.h" + +int ptrace_getregs(long pid, unsigned long *regs_out) +{ + if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) + return -errno; + return 0; +} + +int ptrace_setregs(long pid, unsigned long *regs) +{ + if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0) + return -errno; + return 0; +} diff --git a/arch/um/sys-x86/setjmp_32.S b/arch/um/sys-x86/setjmp_32.S new file mode 100644 index 0000000..b766792 --- /dev/null +++ b/arch/um/sys-x86/setjmp_32.S @@ -0,0 +1,58 @@ +# +# arch/i386/setjmp.S +# +# setjmp/longjmp for the i386 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %ebx +# %esp +# %ebp +# %esi +# %edi +# +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: +#ifdef _REGPARM + movl %eax,%edx +#else + movl 4(%esp),%edx +#endif + popl %ecx # Return address, and adjust the stack + xorl %eax,%eax # Return value + movl %ebx,(%edx) + movl %esp,4(%edx) # Post-return %esp! + pushl %ecx # Make the call/return stack happy + movl %ebp,8(%edx) + movl %esi,12(%edx) + movl %edi,16(%edx) + movl %ecx,20(%edx) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: +#ifdef _REGPARM + xchgl %eax,%edx +#else + movl 4(%esp),%edx # jmp_ptr address + movl 8(%esp),%eax # Return value +#endif + movl (%edx),%ebx + movl 4(%edx),%esp + movl 8(%edx),%ebp + movl 12(%edx),%esi + movl 16(%edx),%edi + jmp *20(%edx) + + .size longjmp,.-longjmp diff --git a/arch/um/sys-x86/setjmp_64.S b/arch/um/sys-x86/setjmp_64.S new file mode 100644 index 0000000..45f547b --- /dev/null +++ b/arch/um/sys-x86/setjmp_64.S @@ -0,0 +1,54 @@ +# +# arch/x86_64/setjmp.S +# +# setjmp/longjmp for the x86-64 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %rbx +# %rsp (post-return) +# %rbp +# %r12 +# %r13 +# %r14 +# %r15 +# +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: + pop %rsi # Return address, and adjust the stack + xorl %eax,%eax # Return value + movq %rbx,(%rdi) + movq %rsp,8(%rdi) # Post-return %rsp! + push %rsi # Make the call/return stack happy + movq %rbp,16(%rdi) + movq %r12,24(%rdi) + movq %r13,32(%rdi) + movq %r14,40(%rdi) + movq %r15,48(%rdi) + movq %rsi,56(%rdi) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: + movl %esi,%eax # Return value (int) + movq (%rdi),%rbx + movq 8(%rdi),%rsp + movq 16(%rdi),%rbp + movq 24(%rdi),%r12 + movq 32(%rdi),%r13 + movq 40(%rdi),%r14 + movq 48(%rdi),%r15 + jmp *56(%rdi) + + .size longjmp,.-longjmp diff --git a/arch/um/sys-x86/signal_32.c b/arch/um/sys-x86/signal_32.c new file mode 100644 index 0000000..bcbfb0d --- /dev/null +++ b/arch/um/sys-x86/signal_32.c @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include "frame_kern.h" +#include "skas.h" + +/* + * FPU tag word conversions. + */ + +static inline unsigned short twd_i387_to_fxsr(unsigned short twd) +{ + unsigned int tmp; /* to avoid 16 bit prefixes in the code */ + + /* Transform each pair of bits into 01 (valid) or 00 (empty) */ + tmp = ~twd; + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ + /* and move the valid bits to the lower byte. */ + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ + return tmp; +} + +static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) +{ + struct _fpxreg *st = NULL; + unsigned long twd = (unsigned long) fxsave->twd; + unsigned long tag; + unsigned long ret = 0xffff0000; + int i; + +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) + + for (i = 0; i < 8; i++) { + if (twd & 0x1) { + st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); + + switch (st->exponent & 0x7fff) { + case 0x7fff: + tag = 2; /* Special */ + break; + case 0x0000: + if ( !st->significand[0] && + !st->significand[1] && + !st->significand[2] && + !st->significand[3] ) { + tag = 1; /* Zero */ + } else { + tag = 2; /* Special */ + } + break; + default: + if (st->significand[3] & 0x8000) { + tag = 0; /* Valid */ + } else { + tag = 2; /* Special */ + } + break; + } + } else { + tag = 3; /* Empty */ + } + ret |= (tag << (2 * i)); + twd = twd >> 1; + } + return ret; +} + +static int convert_fxsr_to_user(struct _fpstate __user *buf, + struct user_fxsr_struct *fxsave) +{ + unsigned long env[7]; + struct _fpreg __user *to; + struct _fpxreg *from; + int i; + + env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; + env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; + env[2] = twd_fxsr_to_i387(fxsave); + env[3] = fxsave->fip; + env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); + env[5] = fxsave->foo; + env[6] = fxsave->fos; + + if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) + return 1; + + to = &buf->_st[0]; + from = (struct _fpxreg *) &fxsave->st_space[0]; + for (i = 0; i < 8; i++, to++, from++) { + unsigned long __user *t = (unsigned long __user *)to; + unsigned long *f = (unsigned long *)from; + + if (__put_user(*f, t) || + __put_user(*(f + 1), t + 1) || + __put_user(from->exponent, &to->exponent)) + return 1; + } + return 0; +} + +static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, + struct _fpstate __user *buf) +{ + unsigned long env[7]; + struct _fpxreg *to; + struct _fpreg __user *from; + int i; + + if (copy_from_user( env, buf, 7 * sizeof(long))) + return 1; + + fxsave->cwd = (unsigned short)(env[0] & 0xffff); + fxsave->swd = (unsigned short)(env[1] & 0xffff); + fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); + fxsave->fip = env[3]; + fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); + fxsave->fcs = (env[4] & 0xffff); + fxsave->foo = env[5]; + fxsave->fos = env[6]; + + to = (struct _fpxreg *) &fxsave->st_space[0]; + from = &buf->_st[0]; + for (i = 0; i < 8; i++, to++, from++) { + unsigned long *t = (unsigned long *)to; + unsigned long __user *f = (unsigned long __user *)from; + + if (__get_user(*t, f) || + __get_user(*(t + 1), f + 1) || + __get_user(to->exponent, &from->exponent)) + return 1; + } + return 0; +} + +extern int have_fpx_regs; + +static int copy_sc_from_user(struct pt_regs *regs, + struct sigcontext __user *from) +{ + struct sigcontext sc; + int err, pid; + + err = copy_from_user(&sc, from, sizeof(sc)); + if (err) + return err; + + pid = userspace_pid[current_thread_info()->cpu]; + +#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname + + GETREG(GS, gs); + GETREG(FS, fs); + GETREG(ES, es); + GETREG(DS, ds); + GETREG(EDI, di); + GETREG(ESI, si); + GETREG(EBP, bp); + GETREG(SP, sp); + GETREG(EBX, bx); + GETREG(EDX, dx); + GETREG(ECX, cx); + GETREG(EAX, ax); + GETREG(IP, ip); + GETREG(CS, cs); + GETREG(EFLAGS, flags); + GETREG(SS, ss); + +#undef GETREG + if (have_fpx_regs) { + struct user_fxsr_struct fpx; + + err = copy_from_user(&fpx, + &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0], + sizeof(struct user_fxsr_struct)); + if (err) + return 1; + + err = convert_fxsr_from_user(&fpx, sc.fpstate); + if (err) + return 1; + + err = restore_fpx_registers(pid, (unsigned long *) &fpx); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fpx_registers failed, errno = %d\n", + -err); + return 1; + } + } else { + struct user_i387_struct fp; + + err = copy_from_user(&fp, sc.fpstate, + sizeof(struct user_i387_struct)); + if (err) + return 1; + + err = restore_fp_registers(pid, (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fp_registers failed, errno = %d\n", + -err); + return 1; + } + } + + return 0; +} + +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, + unsigned long sp) +{ + struct sigcontext sc; + struct faultinfo * fi = ¤t->thread.arch.faultinfo; + int err, pid; + memset(&sc, 0, sizeof(struct sigcontext)); + + sc.gs = REGS_GS(regs->regs.gp); + sc.fs = REGS_FS(regs->regs.gp); + sc.es = REGS_ES(regs->regs.gp); + sc.ds = REGS_DS(regs->regs.gp); + sc.di = REGS_EDI(regs->regs.gp); + sc.si = REGS_ESI(regs->regs.gp); + sc.bp = REGS_EBP(regs->regs.gp); + sc.sp = sp; + sc.bx = REGS_EBX(regs->regs.gp); + sc.dx = REGS_EDX(regs->regs.gp); + sc.cx = REGS_ECX(regs->regs.gp); + sc.ax = REGS_EAX(regs->regs.gp); + sc.ip = REGS_IP(regs->regs.gp); + sc.cs = REGS_CS(regs->regs.gp); + sc.flags = REGS_EFLAGS(regs->regs.gp); + sc.sp_at_signal = regs->regs.gp[UESP]; + sc.ss = regs->regs.gp[SS]; + sc.cr2 = fi->cr2; + sc.err = fi->error_code; + sc.trapno = fi->trap_no; + + to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); + sc.fpstate = to_fp; + + pid = userspace_pid[current_thread_info()->cpu]; + if (have_fpx_regs) { + struct user_fxsr_struct fpx; + + err = save_fpx_registers(pid, (unsigned long *) &fpx); + if (err < 0){ + printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " + "failed, errno = %d\n", err); + return 1; + } + + err = convert_fxsr_to_user(to_fp, &fpx); + if (err) + return 1; + + err |= __put_user(fpx.swd, &to_fp->status); + err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic); + if (err) + return 1; + + if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, + sizeof(struct user_fxsr_struct))) + return 1; + } + else { + struct user_i387_struct fp; + + err = save_fp_registers(pid, (unsigned long *) &fp); + if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) + return 1; + } + + return copy_to_user(to, &sc, sizeof(sc)); +} + +static int copy_ucontext_to_user(struct ucontext __user *uc, + struct _fpstate __user *fp, sigset_t *set, + unsigned long sp) +{ + int err = 0; + + err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); + err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); + err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); + return err; +} + +struct sigframe +{ + char __user *pretcode; + int sig; + struct sigcontext sc; + struct _fpstate fpstate; + unsigned long extramask[_NSIG_WORDS-1]; + char retcode[8]; +}; + +struct rt_sigframe +{ + char __user *pretcode; + int sig; + struct siginfo __user *pinfo; + void __user *puc; + struct siginfo info; + struct ucontext uc; + struct _fpstate fpstate; + char retcode[8]; +}; + +int setup_signal_stack_sc(unsigned long stack_top, int sig, + struct k_sigaction *ka, struct pt_regs *regs, + sigset_t *mask) +{ + struct sigframe __user *frame; + void __user *restorer; + unsigned long save_sp = PT_REGS_SP(regs); + int err = 0; + + /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ + stack_top = ((stack_top + 4) & -16UL) - 4; + frame = (struct sigframe __user *) stack_top - 1; + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + return 1; + + restorer = frame->retcode; + if (ka->sa.sa_flags & SA_RESTORER) + restorer = ka->sa.sa_restorer; + + /* Update SP now because the page fault handler refuses to extend + * the stack if the faulting address is too far below the current + * SP, which frame now certainly is. If there's an error, the original + * value is restored on the way out. + * When writing the sigcontext to the stack, we have to write the + * original value, so that's passed to copy_sc_to_user, which does + * the right thing with it. + */ + PT_REGS_SP(regs) = (unsigned long) frame; + + err |= __put_user(restorer, &frame->pretcode); + err |= __put_user(sig, &frame->sig); + err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); + err |= __put_user(mask->sig[0], &frame->sc.oldmask); + if (_NSIG_WORDS > 1) + err |= __copy_to_user(&frame->extramask, &mask->sig[1], + sizeof(frame->extramask)); + + /* + * This is popl %eax ; movl $,%eax ; int $0x80 + * + * WE DO NOT USE IT ANY MORE! It's only left here for historical + * reasons and because gdb uses it as a signature to notice + * signal handler stack frames. + */ + err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); + err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); + + if (err) + goto err; + + PT_REGS_SP(regs) = (unsigned long) frame; + PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; + PT_REGS_EAX(regs) = (unsigned long) sig; + PT_REGS_EDX(regs) = (unsigned long) 0; + PT_REGS_ECX(regs) = (unsigned long) 0; + + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + ptrace_notify(SIGTRAP); + return 0; + +err: + PT_REGS_SP(regs) = save_sp; + return err; +} + +int setup_signal_stack_si(unsigned long stack_top, int sig, + struct k_sigaction *ka, struct pt_regs *regs, + siginfo_t *info, sigset_t *mask) +{ + struct rt_sigframe __user *frame; + void __user *restorer; + unsigned long save_sp = PT_REGS_SP(regs); + int err = 0; + + stack_top &= -8UL; + frame = (struct rt_sigframe __user *) stack_top - 1; + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + return 1; + + restorer = frame->retcode; + if (ka->sa.sa_flags & SA_RESTORER) + restorer = ka->sa.sa_restorer; + + /* See comment above about why this is here */ + PT_REGS_SP(regs) = (unsigned long) frame; + + err |= __put_user(restorer, &frame->pretcode); + err |= __put_user(sig, &frame->sig); + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, + save_sp); + + /* + * This is movl $,%eax ; int $0x80 + * + * WE DO NOT USE IT ANY MORE! It's only left here for historical + * reasons and because gdb uses it as a signature to notice + * signal handler stack frames. + */ + err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); + err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); + err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); + + if (err) + goto err; + + PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; + PT_REGS_EAX(regs) = (unsigned long) sig; + PT_REGS_EDX(regs) = (unsigned long) &frame->info; + PT_REGS_ECX(regs) = (unsigned long) &frame->uc; + + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + ptrace_notify(SIGTRAP); + return 0; + +err: + PT_REGS_SP(regs) = save_sp; + return err; +} + +long sys_sigreturn(struct pt_regs regs) +{ + unsigned long sp = PT_REGS_SP(¤t->thread.regs); + struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); + sigset_t set; + struct sigcontext __user *sc = &frame->sc; + unsigned long __user *oldmask = &sc->oldmask; + unsigned long __user *extramask = frame->extramask; + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); + + if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || + copy_from_user(&set.sig[1], extramask, sig_size)) + goto segfault; + + sigdelsetmask(&set, ~_BLOCKABLE); + set_current_blocked(&set); + + if (copy_sc_from_user(¤t->thread.regs, sc)) + goto segfault; + + /* Avoid ERESTART handling */ + PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; + return PT_REGS_SYSCALL_RET(¤t->thread.regs); + + segfault: + force_sig(SIGSEGV, current); + return 0; +} + +long sys_rt_sigreturn(struct pt_regs regs) +{ + unsigned long sp = PT_REGS_SP(¤t->thread.regs); + struct rt_sigframe __user *frame = + (struct rt_sigframe __user *) (sp - 4); + sigset_t set; + struct ucontext __user *uc = &frame->uc; + int sig_size = _NSIG_WORDS * sizeof(unsigned long); + + if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) + goto segfault; + + sigdelsetmask(&set, ~_BLOCKABLE); + set_current_blocked(&set); + + if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) + goto segfault; + + /* Avoid ERESTART handling */ + PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; + return PT_REGS_SYSCALL_RET(¤t->thread.regs); + + segfault: + force_sig(SIGSEGV, current); + return 0; +} diff --git a/arch/um/sys-x86/signal_64.c b/arch/um/sys-x86/signal_64.c new file mode 100644 index 0000000..255b2ca --- /dev/null +++ b/arch/um/sys-x86/signal_64.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include "frame_kern.h" +#include "skas.h" + +static int copy_sc_from_user(struct pt_regs *regs, + struct sigcontext __user *from) +{ + struct sigcontext sc; + struct user_i387_struct fp; + void __user *buf; + int err; + + err = copy_from_user(&sc, from, sizeof(sc)); + if (err) + return err; + +#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname + + GETREG(R8, r8); + GETREG(R9, r9); + GETREG(R10, r10); + GETREG(R11, r11); + GETREG(R12, r12); + GETREG(R13, r13); + GETREG(R14, r14); + GETREG(R15, r15); + GETREG(RDI, di); + GETREG(RSI, si); + GETREG(RBP, bp); + GETREG(RBX, bx); + GETREG(RDX, dx); + GETREG(RAX, ax); + GETREG(RCX, cx); + GETREG(SP, sp); + GETREG(IP, ip); + GETREG(EFLAGS, flags); + GETREG(CS, cs); +#undef GETREG + + buf = sc.fpstate; + + err = copy_from_user(&fp, buf, sizeof(struct user_i387_struct)); + if (err) + return 1; + + err = restore_fp_registers(userspace_pid[current_thread_info()->cpu], + (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - " + "restore_fp_registers failed, errno = %d\n", + -err); + return 1; + } + + return 0; +} + +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, + unsigned long mask, unsigned long sp) +{ + struct faultinfo * fi = ¤t->thread.arch.faultinfo; + struct sigcontext sc; + struct user_i387_struct fp; + int err = 0; + memset(&sc, 0, sizeof(struct sigcontext)); + +#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno] + + PUTREG(RDI, di); + PUTREG(RSI, si); + PUTREG(RBP, bp); + /* + * Must use original RSP, which is passed in, rather than what's in + * signal frame. + */ + sc.sp = sp; + PUTREG(RBX, bx); + PUTREG(RDX, dx); + PUTREG(RCX, cx); + PUTREG(RAX, ax); + PUTREG(R8, r8); + PUTREG(R9, r9); + PUTREG(R10, r10); + PUTREG(R11, r11); + PUTREG(R12, r12); + PUTREG(R13, r13); + PUTREG(R14, r14); + PUTREG(R15, r15); + PUTREG(CS, cs); /* XXX x86_64 doesn't do this */ + + sc.cr2 = fi->cr2; + sc.err = fi->error_code; + sc.trapno = fi->trap_no; + + PUTREG(IP, ip); + PUTREG(EFLAGS, flags); +#undef PUTREG + + sc.oldmask = mask; + + err = copy_to_user(to, &sc, sizeof(struct sigcontext)); + if (err) + return 1; + + err = save_fp_registers(userspace_pid[current_thread_info()->cpu], + (unsigned long *) &fp); + if (err < 0) { + printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " + "failed, errno = %d\n", -err); + return 1; + } + + if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) + return 1; + + return err; +} + +struct rt_sigframe +{ + char __user *pretcode; + struct ucontext uc; + struct siginfo info; + struct _fpstate fpstate; +}; + +int setup_signal_stack_si(unsigned long stack_top, int sig, + struct k_sigaction *ka, struct pt_regs * regs, + siginfo_t *info, sigset_t *set) +{ + struct rt_sigframe __user *frame; + unsigned long save_sp = PT_REGS_RSP(regs); + int err = 0; + struct task_struct *me = current; + + frame = (struct rt_sigframe __user *) + round_down(stack_top - sizeof(struct rt_sigframe), 16); + /* Subtract 128 for a red zone and 8 for proper alignment */ + frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto out; + + if (ka->sa.sa_flags & SA_SIGINFO) { + err |= copy_siginfo_to_user(&frame->info, info); + if (err) + goto out; + } + + /* + * Update SP now because the page fault handler refuses to extend + * the stack if the faulting address is too far below the current + * SP, which frame now certainly is. If there's an error, the original + * value is restored on the way out. + * When writing the sigcontext to the stack, we have to write the + * original value, so that's passed to copy_sc_to_user, which does + * the right thing with it. + */ + PT_REGS_RSP(regs) = (unsigned long) frame; + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(save_sp), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, + set->sig[0], save_sp); + err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); + if (sizeof(*set) == 16) { + __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); + __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); + } + else + err |= __copy_to_user(&frame->uc.uc_sigmask, set, + sizeof(*set)); + + /* + * Set up to return from userspace. If provided, use a stub + * already in userspace. + */ + /* x86-64 should always use SA_RESTORER. */ + if (ka->sa.sa_flags & SA_RESTORER) + err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); + else + /* could use a vstub here */ + goto restore_sp; + + if (err) + goto restore_sp; + + /* Set up registers for signal handler */ + { + struct exec_domain *ed = current_thread_info()->exec_domain; + if (unlikely(ed && ed->signal_invmap && sig < 32)) + sig = ed->signal_invmap[sig]; + } + + PT_REGS_RDI(regs) = sig; + /* In case the signal handler was declared without prototypes */ + PT_REGS_RAX(regs) = 0; + + /* + * This also works for non SA_SIGINFO handlers because they expect the + * next argument after the signal number on the stack. + */ + PT_REGS_RSI(regs) = (unsigned long) &frame->info; + PT_REGS_RDX(regs) = (unsigned long) &frame->uc; + PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; + out: + return err; + +restore_sp: + PT_REGS_RSP(regs) = save_sp; + return err; +} + +long sys_rt_sigreturn(struct pt_regs *regs) +{ + unsigned long sp = PT_REGS_SP(¤t->thread.regs); + struct rt_sigframe __user *frame = + (struct rt_sigframe __user *)(sp - 8); + struct ucontext __user *uc = &frame->uc; + sigset_t set; + + if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) + goto segfault; + + sigdelsetmask(&set, ~_BLOCKABLE); + set_current_blocked(&set); + + if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) + goto segfault; + + /* Avoid ERESTART handling */ + PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; + return PT_REGS_SYSCALL_RET(¤t->thread.regs); + + segfault: + force_sig(SIGSEGV, current); + return 0; +} diff --git a/arch/um/sys-x86/stub_32.S b/arch/um/sys-x86/stub_32.S new file mode 100644 index 0000000..54a36ec --- /dev/null +++ b/arch/um/sys-x86/stub_32.S @@ -0,0 +1,51 @@ +#include "as-layout.h" + + .globl syscall_stub +.section .__syscall_stub, "ax" + + .globl batch_syscall_stub +batch_syscall_stub: + /* load pointer to first operation */ + mov $(STUB_DATA+8), %esp + +again: + /* load length of additional data */ + mov 0x0(%esp), %eax + + /* if(length == 0) : end of list */ + /* write possible 0 to header */ + mov %eax, STUB_DATA+4 + cmpl $0, %eax + jz done + + /* save current pointer */ + mov %esp, STUB_DATA+4 + + /* skip additional data */ + add %eax, %esp + + /* load syscall-# */ + pop %eax + + /* load syscall params */ + pop %ebx + pop %ecx + pop %edx + pop %esi + pop %edi + pop %ebp + + /* execute syscall */ + int $0x80 + + /* check return value */ + pop %ebx + cmp %ebx, %eax + je again + +done: + /* save return value */ + mov %eax, STUB_DATA + + /* stop */ + int3 diff --git a/arch/um/sys-x86/stub_64.S b/arch/um/sys-x86/stub_64.S new file mode 100644 index 0000000..20e4a96 --- /dev/null +++ b/arch/um/sys-x86/stub_64.S @@ -0,0 +1,66 @@ +#include "as-layout.h" + + .globl syscall_stub +.section .__syscall_stub, "ax" +syscall_stub: + syscall + /* We don't have 64-bit constants, so this constructs the address + * we need. + */ + movq $(STUB_DATA >> 32), %rbx + salq $32, %rbx + movq $(STUB_DATA & 0xffffffff), %rcx + or %rcx, %rbx + movq %rax, (%rbx) + int3 + + .globl batch_syscall_stub +batch_syscall_stub: + mov $(STUB_DATA >> 32), %rbx + sal $32, %rbx + mov $(STUB_DATA & 0xffffffff), %rax + or %rax, %rbx + /* load pointer to first operation */ + mov %rbx, %rsp + add $0x10, %rsp +again: + /* load length of additional data */ + mov 0x0(%rsp), %rax + + /* if(length == 0) : end of list */ + /* write possible 0 to header */ + mov %rax, 8(%rbx) + cmp $0, %rax + jz done + + /* save current pointer */ + mov %rsp, 8(%rbx) + + /* skip additional data */ + add %rax, %rsp + + /* load syscall-# */ + pop %rax + + /* load syscall params */ + pop %rdi + pop %rsi + pop %rdx + pop %r10 + pop %r8 + pop %r9 + + /* execute syscall */ + syscall + + /* check return value */ + pop %rcx + cmp %rcx, %rax + je again + +done: + /* save return value */ + mov %rax, (%rbx) + + /* stop */ + int3 diff --git a/arch/um/sys-x86/stub_segv_32.c b/arch/um/sys-x86/stub_segv_32.c new file mode 100644 index 0000000..28ccf73 --- /dev/null +++ b/arch/um/sys-x86/stub_segv_32.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include "sysdep/stub.h" +#include "sysdep/sigcontext.h" + +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_segv_handler(int sig) +{ + struct sigcontext *sc = (struct sigcontext *) (&sig + 1); + + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); + + trap_myself(); +} diff --git a/arch/um/sys-x86/stub_segv_64.c b/arch/um/sys-x86/stub_segv_64.c new file mode 100644 index 0000000..ced051a --- /dev/null +++ b/arch/um/sys-x86/stub_segv_64.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include "as-layout.h" +#include "sysdep/stub.h" +#include "sysdep/faultinfo.h" +#include "sysdep/sigcontext.h" + +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_segv_handler(int sig) +{ + struct ucontext *uc; + + __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), + &uc->uc_mcontext); + trap_myself(); +} + diff --git a/arch/um/sys-x86/sys_call_table_32.S b/arch/um/sys-x86/sys_call_table_32.S new file mode 100644 index 0000000..de274071 --- /dev/null +++ b/arch/um/sys-x86/sys_call_table_32.S @@ -0,0 +1,28 @@ +#include +/* Steal i386 syscall table for our purposes, but with some slight changes.*/ + +#define sys_iopl sys_ni_syscall +#define sys_ioperm sys_ni_syscall + +#define sys_vm86old sys_ni_syscall +#define sys_vm86 sys_ni_syscall + +#define old_mmap sys_old_mmap + +#define ptregs_fork sys_fork +#define ptregs_execve sys_execve +#define ptregs_iopl sys_iopl +#define ptregs_vm86old sys_vm86old +#define ptregs_sigreturn sys_sigreturn +#define ptregs_clone sys_clone +#define ptregs_vm86 sys_vm86 +#define ptregs_rt_sigreturn sys_rt_sigreturn +#define ptregs_sigaltstack sys_sigaltstack +#define ptregs_vfork sys_vfork + +.section .rodata,"a" + +#include "../../x86/kernel/syscall_table_32.S" + +ENTRY(syscall_table_size) +.long .-sys_call_table diff --git a/arch/um/sys-x86/sys_call_table_64.c b/arch/um/sys-x86/sys_call_table_64.c new file mode 100644 index 0000000..f46de82 --- /dev/null +++ b/arch/um/sys-x86/sys_call_table_64.c @@ -0,0 +1,64 @@ +/* + * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c + * with some changes for UML. + */ + +#include +#include +#include + +#define __NO_STUBS + +/* + * Below you can see, in terms of #define's, the differences between the x86-64 + * and the UML syscall table. + */ + +/* Not going to be implemented by UML, since we have no hardware. */ +#define stub_iopl sys_ni_syscall +#define sys_ioperm sys_ni_syscall + +/* + * The UML TLS problem. Note that x86_64 does not implement this, so the below + * is needed only for the ia32 compatibility. + */ + +/* On UML we call it this way ("old" means it's not mmap2) */ +#define sys_mmap old_mmap + +#define stub_clone sys_clone +#define stub_fork sys_fork +#define stub_vfork sys_vfork +#define stub_execve sys_execve +#define stub_rt_sigsuspend sys_rt_sigsuspend +#define stub_sigaltstack sys_sigaltstack +#define stub_rt_sigreturn sys_rt_sigreturn + +#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; +#undef _ASM_X86_UNISTD_64_H +#include "../../x86/include/asm/unistd_64.h" + +#undef __SYSCALL +#define __SYSCALL(nr, sym) [ nr ] = sym, +#undef _ASM_X86_UNISTD_64_H + +typedef void (*sys_call_ptr_t)(void); + +extern void sys_ni_syscall(void); + +/* + * We used to have a trick here which made sure that holes in the + * x86_64 table were filled in with sys_ni_syscall, but a comment in + * unistd_64.h says that holes aren't allowed, so the trick was + * removed. + * The trick looked like this + * [0 ... UM_NR_syscall_max] = &sys_ni_syscall + * before including unistd_64.h - the later initializations overwrote + * the sys_ni_syscall filler. + */ + +sys_call_ptr_t sys_call_table[] __cacheline_aligned = { +#include "../../x86/include/asm/unistd_64.h" +}; + +int syscall_table_size = sizeof(sys_call_table); diff --git a/arch/um/sys-x86/syscalls_32.c b/arch/um/sys-x86/syscalls_32.c new file mode 100644 index 0000000..70ca357 --- /dev/null +++ b/arch/um/sys-x86/syscalls_32.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#include "linux/sched.h" +#include "linux/shm.h" +#include "linux/ipc.h" +#include "linux/syscalls.h" +#include "asm/mman.h" +#include "asm/uaccess.h" +#include "asm/unistd.h" + +/* + * The prototype on i386 is: + * + * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) + * + * and the "newtls" arg. on i386 is read by copy_thread directly from the + * register saved on the stack. + */ +long sys_clone(unsigned long clone_flags, unsigned long newsp, + int __user *parent_tid, void *newtls, int __user *child_tid) +{ + long ret; + + if (!newsp) + newsp = UPT_SP(¤t->thread.regs.regs); + + current->thread.forking = 1; + ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, + child_tid); + current->thread.forking = 0; + return ret; +} + +long sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} diff --git a/arch/um/sys-x86/syscalls_64.c b/arch/um/sys-x86/syscalls_64.c new file mode 100644 index 0000000..f3d82bb --- /dev/null +++ b/arch/um/sys-x86/syscalls_64.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#include "linux/linkage.h" +#include "linux/personality.h" +#include "linux/utsname.h" +#include "asm/prctl.h" /* XXX This should get the constants from libc */ +#include "asm/uaccess.h" +#include "os.h" + +long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) +{ + unsigned long *ptr = addr, tmp; + long ret; + int pid = task->mm->context.id.u.pid; + + /* + * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to + * be safe), we need to call arch_prctl on the host because + * setting %fs may result in something else happening (like a + * GDT or thread.fs being set instead). So, we let the host + * fiddle the registers and thread struct and restore the + * registers afterwards. + * + * So, the saved registers are stored to the process (this + * needed because a stub may have been the last thing to run), + * arch_prctl is run on the host, then the registers are read + * back. + */ + switch (code) { + case ARCH_SET_FS: + case ARCH_SET_GS: + ret = restore_registers(pid, ¤t->thread.regs.regs); + if (ret) + return ret; + break; + case ARCH_GET_FS: + case ARCH_GET_GS: + /* + * With these two, we read to a local pointer and + * put_user it to the userspace pointer that we were + * given. If addr isn't valid (because it hasn't been + * faulted in or is just bogus), we want put_user to + * fault it in (or return -EFAULT) instead of having + * the host return -EFAULT. + */ + ptr = &tmp; + } + + ret = os_arch_prctl(pid, code, ptr); + if (ret) + return ret; + + switch (code) { + case ARCH_SET_FS: + current->thread.arch.fs = (unsigned long) ptr; + ret = save_registers(pid, ¤t->thread.regs.regs); + break; + case ARCH_SET_GS: + ret = save_registers(pid, ¤t->thread.regs.regs); + break; + case ARCH_GET_FS: + ret = put_user(tmp, addr); + break; + case ARCH_GET_GS: + ret = put_user(tmp, addr); + break; + } + + return ret; +} + +long sys_arch_prctl(int code, unsigned long addr) +{ + return arch_prctl(current, code, (unsigned long __user *) addr); +} + +long sys_clone(unsigned long clone_flags, unsigned long newsp, + void __user *parent_tid, void __user *child_tid) +{ + long ret; + + if (!newsp) + newsp = UPT_SP(¤t->thread.regs.regs); + current->thread.forking = 1; + ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, + child_tid); + current->thread.forking = 0; + return ret; +} + +void arch_switch_to(struct task_struct *to) +{ + if ((to->thread.arch.fs == 0) || (to->mm == NULL)) + return; + + arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); +} diff --git a/arch/um/sys-x86/sysrq_32.c b/arch/um/sys-x86/sysrq_32.c new file mode 100644 index 0000000..171b3e9 --- /dev/null +++ b/arch/um/sys-x86/sysrq_32.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#include "linux/kernel.h" +#include "linux/smp.h" +#include "linux/sched.h" +#include "linux/kallsyms.h" +#include "asm/ptrace.h" +#include "sysrq.h" + +/* This is declared by */ +void show_regs(struct pt_regs *regs) +{ + printk("\n"); + printk("EIP: %04lx:[<%08lx>] CPU: %d %s", + 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs), + smp_processor_id(), print_tainted()); + if (PT_REGS_CS(regs) & 3) + printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs), + PT_REGS_SP(regs)); + printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs), + print_tainted()); + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + PT_REGS_EAX(regs), PT_REGS_EBX(regs), + PT_REGS_ECX(regs), + PT_REGS_EDX(regs)); + printk("ESI: %08lx EDI: %08lx EBP: %08lx", + PT_REGS_ESI(regs), PT_REGS_EDI(regs), + PT_REGS_EBP(regs)); + printk(" DS: %04lx ES: %04lx\n", + 0xffff & PT_REGS_DS(regs), + 0xffff & PT_REGS_ES(regs)); + + show_trace(NULL, (unsigned long *) ®s); +} + +/* Copied from i386. */ +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +{ + return p > (void *)tinfo && + p < (void *)tinfo + THREAD_SIZE - 3; +} + +/* Adapted from i386 (we also print the address we read from). */ +static inline unsigned long print_context_stack(struct thread_info *tinfo, + unsigned long *stack, unsigned long ebp) +{ + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + while (valid_stack_ptr(tinfo, (void *)ebp)) { + addr = *(unsigned long *)(ebp + 4); + printk("%08lx: [<%08lx>]", ebp + 4, addr); + print_symbol(" %s", addr); + printk("\n"); + ebp = *(unsigned long *)ebp; + } +#else + while (valid_stack_ptr(tinfo, stack)) { + addr = *stack; + if (__kernel_text_address(addr)) { + printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); + print_symbol(" %s", addr); + printk("\n"); + } + stack++; + } +#endif + return ebp; +} + +void show_trace(struct task_struct* task, unsigned long * stack) +{ + unsigned long ebp; + struct thread_info *context; + + /* Turn this into BUG_ON if possible. */ + if (!stack) { + stack = (unsigned long*) &stack; + printk("show_trace: got NULL stack, implicit assumption task == current"); + WARN_ON(1); + } + + if (!task) + task = current; + + if (task != current) { + ebp = (unsigned long) KSTK_EBP(task); + } else { + asm ("movl %%ebp, %0" : "=r" (ebp) : ); + } + + context = (struct thread_info *) + ((unsigned long)stack & (~(THREAD_SIZE - 1))); + print_context_stack(context, stack, ebp); + + printk("\n"); +} + diff --git a/arch/um/sys-x86/sysrq_64.c b/arch/um/sys-x86/sysrq_64.c new file mode 100644 index 0000000..f4f82be --- /dev/null +++ b/arch/um/sys-x86/sysrq_64.c @@ -0,0 +1,41 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include "sysrq.h" + +void __show_regs(struct pt_regs *regs) +{ + printk("\n"); + print_modules(); + printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), + current->comm, print_tainted(), init_utsname()->release); + printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, + PT_REGS_RIP(regs)); + printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), + PT_REGS_EFLAGS(regs)); + printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", + PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); + printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", + PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); + printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", + PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); + printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", + PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); + printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", + PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); +} + +void show_regs(struct pt_regs *regs) +{ + __show_regs(regs); + show_trace(current, (unsigned long *) ®s); +} diff --git a/arch/um/sys-x86/tls_32.c b/arch/um/sys-x86/tls_32.c new file mode 100644 index 0000000..c6c7131 --- /dev/null +++ b/arch/um/sys-x86/tls_32.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso + * Licensed under the GPL + */ + +#include "linux/percpu.h" +#include "linux/sched.h" +#include "asm/uaccess.h" +#include "os.h" +#include "skas.h" +#include "sysdep/tls.h" + +/* + * If needed we can detect when it's uninitialized. + * + * These are initialized in an initcall and unchanged thereafter. + */ +static int host_supports_tls = -1; +int host_gdt_entry_tls_min; + +int do_set_thread_area(struct user_desc *info) +{ + int ret; + u32 cpu; + + cpu = get_cpu(); + ret = os_set_thread_area(info, userspace_pid[cpu]); + put_cpu(); + + if (ret) + printk(KERN_ERR "PTRACE_SET_THREAD_AREA failed, err = %d, " + "index = %d\n", ret, info->entry_number); + + return ret; +} + +int do_get_thread_area(struct user_desc *info) +{ + int ret; + u32 cpu; + + cpu = get_cpu(); + ret = os_get_thread_area(info, userspace_pid[cpu]); + put_cpu(); + + if (ret) + printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, " + "index = %d\n", ret, info->entry_number); + + return ret; +} + +/* + * sys_get_thread_area: get a yet unused TLS descriptor index. + * XXX: Consider leaving one free slot for glibc usage at first place. This must + * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else. + * + * Also, this must be tested when compiling in SKAS mode with dynamic linking + * and running against NPTL. + */ +static int get_free_idx(struct task_struct* task) +{ + struct thread_struct *t = &task->thread; + int idx; + + if (!t->arch.tls_array) + return GDT_ENTRY_TLS_MIN; + + for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) + if (!t->arch.tls_array[idx].present) + return idx + GDT_ENTRY_TLS_MIN; + return -ESRCH; +} + +static inline void clear_user_desc(struct user_desc* info) +{ + /* Postcondition: LDT_empty(info) returns true. */ + memset(info, 0, sizeof(*info)); + + /* + * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain + * indeed an empty user_desc. + */ + info->read_exec_only = 1; + info->seg_not_present = 1; +} + +#define O_FORCE 1 + +static int load_TLS(int flags, struct task_struct *to) +{ + int ret = 0; + int idx; + + for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { + struct uml_tls_struct* curr = + &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; + + /* + * Actually, now if it wasn't flushed it gets cleared and + * flushed to the host, which will clear it. + */ + if (!curr->present) { + if (!curr->flushed) { + clear_user_desc(&curr->tls); + curr->tls.entry_number = idx; + } else { + WARN_ON(!LDT_empty(&curr->tls)); + continue; + } + } + + if (!(flags & O_FORCE) && curr->flushed) + continue; + + ret = do_set_thread_area(&curr->tls); + if (ret) + goto out; + + curr->flushed = 1; + } +out: + return ret; +} + +/* + * Verify if we need to do a flush for the new process, i.e. if there are any + * present desc's, only if they haven't been flushed. + */ +static inline int needs_TLS_update(struct task_struct *task) +{ + int i; + int ret = 0; + + for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { + struct uml_tls_struct* curr = + &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; + + /* + * Can't test curr->present, we may need to clear a descriptor + * which had a value. + */ + if (curr->flushed) + continue; + ret = 1; + break; + } + return ret; +} + +/* + * On a newly forked process, the TLS descriptors haven't yet been flushed. So + * we mark them as such and the first switch_to will do the job. + */ +void clear_flushed_tls(struct task_struct *task) +{ + int i; + + for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { + struct uml_tls_struct* curr = + &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; + + /* + * Still correct to do this, if it wasn't present on the host it + * will remain as flushed as it was. + */ + if (!curr->present) + continue; + + curr->flushed = 0; + } +} + +/* + * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a + * common host process. So this is needed in SKAS0 too. + * + * However, if each thread had a different host process (and this was discussed + * for SMP support) this won't be needed. + * + * And this will not need be used when (and if) we'll add support to the host + * SKAS patch. + */ + +int arch_switch_tls(struct task_struct *to) +{ + if (!host_supports_tls) + return 0; + + /* + * We have no need whatsoever to switch TLS for kernel threads; beyond + * that, that would also result in us calling os_set_thread_area with + * userspace_pid[cpu] == 0, which gives an error. + */ + if (likely(to->mm)) + return load_TLS(O_FORCE, to); + + return 0; +} + +static int set_tls_entry(struct task_struct* task, struct user_desc *info, + int idx, int flushed) +{ + struct thread_struct *t = &task->thread; + + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + + t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info; + t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1; + t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed; + + return 0; +} + +int arch_copy_tls(struct task_struct *new) +{ + struct user_desc info; + int idx, ret = -EFAULT; + + if (copy_from_user(&info, + (void __user *) UPT_ESI(&new->thread.regs.regs), + sizeof(info))) + goto out; + + ret = -EINVAL; + if (LDT_empty(&info)) + goto out; + + idx = info.entry_number; + + ret = set_tls_entry(new, &info, idx, 0); +out: + return ret; +} + +/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ +static int get_tls_entry(struct task_struct *task, struct user_desc *info, + int idx) +{ + struct thread_struct *t = &task->thread; + + if (!t->arch.tls_array) + goto clear; + + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + + if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present) + goto clear; + + *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; + +out: + /* + * Temporary debugging check, to make sure that things have been + * flushed. This could be triggered if load_TLS() failed. + */ + if (unlikely(task == current && + !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { + printk(KERN_ERR "get_tls_entry: task with pid %d got here " + "without flushed TLS.", current->pid); + } + + return 0; +clear: + /* + * When the TLS entry has not been set, the values read to user in the + * tls_array are 0 (because it's cleared at boot, see + * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. + */ + clear_user_desc(info); + info->entry_number = idx; + goto out; +} + +int sys_set_thread_area(struct user_desc __user *user_desc) +{ + struct user_desc info; + int idx, ret; + + if (!host_supports_tls) + return -ENOSYS; + + if (copy_from_user(&info, user_desc, sizeof(info))) + return -EFAULT; + + idx = info.entry_number; + + if (idx == -1) { + idx = get_free_idx(current); + if (idx < 0) + return idx; + info.entry_number = idx; + /* Tell the user which slot we chose for him.*/ + if (put_user(idx, &user_desc->entry_number)) + return -EFAULT; + } + + ret = do_set_thread_area(&info); + if (ret) + return ret; + return set_tls_entry(current, &info, idx, 1); +} + +/* + * Perform set_thread_area on behalf of the traced child. + * Note: error handling is not done on the deferred load, and this differ from + * i386. However the only possible error are caused by bugs. + */ +int ptrace_set_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc) +{ + struct user_desc info; + + if (!host_supports_tls) + return -EIO; + + if (copy_from_user(&info, user_desc, sizeof(info))) + return -EFAULT; + + return set_tls_entry(child, &info, idx, 0); +} + +int sys_get_thread_area(struct user_desc __user *user_desc) +{ + struct user_desc info; + int idx, ret; + + if (!host_supports_tls) + return -ENOSYS; + + if (get_user(idx, &user_desc->entry_number)) + return -EFAULT; + + ret = get_tls_entry(current, &info, idx); + if (ret < 0) + goto out; + + if (copy_to_user(user_desc, &info, sizeof(info))) + ret = -EFAULT; + +out: + return ret; +} + +/* + * Perform get_thread_area on behalf of the traced child. + */ +int ptrace_get_thread_area(struct task_struct *child, int idx, + struct user_desc __user *user_desc) +{ + struct user_desc info; + int ret; + + if (!host_supports_tls) + return -EIO; + + ret = get_tls_entry(child, &info, idx); + if (ret < 0) + goto out; + + if (copy_to_user(user_desc, &info, sizeof(info))) + ret = -EFAULT; +out: + return ret; +} + +/* + * This code is really i386-only, but it detects and logs x86_64 GDT indexes + * if a 32-bit UML is running on a 64-bit host. + */ +static int __init __setup_host_supports_tls(void) +{ + check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); + if (host_supports_tls) { + printk(KERN_INFO "Host TLS support detected\n"); + printk(KERN_INFO "Detected host type: "); + switch (host_gdt_entry_tls_min) { + case GDT_ENTRY_TLS_MIN_I386: + printk(KERN_CONT "i386"); + break; + case GDT_ENTRY_TLS_MIN_X86_64: + printk(KERN_CONT "x86_64"); + break; + } + printk(KERN_CONT " (GDT indexes %d to %d)\n", + host_gdt_entry_tls_min, + host_gdt_entry_tls_min + GDT_ENTRY_TLS_ENTRIES); + } else + printk(KERN_ERR " Host TLS support NOT detected! " + "TLS support inside UML will not work\n"); + return 0; +} + +__initcall(__setup_host_supports_tls); diff --git a/arch/um/sys-x86/tls_64.c b/arch/um/sys-x86/tls_64.c new file mode 100644 index 0000000..f7ba462 --- /dev/null +++ b/arch/um/sys-x86/tls_64.c @@ -0,0 +1,17 @@ +#include "linux/sched.h" + +void clear_flushed_tls(struct task_struct *task) +{ +} + +int arch_copy_tls(struct task_struct *t) +{ + /* + * If CLONE_SETTLS is set, we need to save the thread id + * (which is argument 5, child_tid, of clone) so it can be set + * during context switches. + */ + t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; + + return 0; +} diff --git a/arch/um/sys-x86/user-offsets.c b/arch/um/sys-x86/user-offsets.c new file mode 100644 index 0000000..718f0c0 --- /dev/null +++ b/arch/um/sys-x86/user-offsets.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#define __FRAME_OFFSETS +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define DEFINE_LONGS(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) + +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)); + +void foo(void) +{ + OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); + OFFSET(HOST_SC_ERR, sigcontext, err); + OFFSET(HOST_SC_CR2, sigcontext, cr2); + +#ifdef __i386__ + DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); + DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); + + DEFINE(HOST_IP, EIP); + DEFINE(HOST_SP, UESP); + DEFINE(HOST_EFLAGS, EFL); + DEFINE(HOST_EAX, EAX); + DEFINE(HOST_EBX, EBX); + DEFINE(HOST_ECX, ECX); + DEFINE(HOST_EDX, EDX); + DEFINE(HOST_ESI, ESI); + DEFINE(HOST_EDI, EDI); + DEFINE(HOST_EBP, EBP); + DEFINE(HOST_CS, CS); + DEFINE(HOST_SS, SS); + DEFINE(HOST_DS, DS); + DEFINE(HOST_FS, FS); + DEFINE(HOST_ES, ES); + DEFINE(HOST_GS, GS); +#else + DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); + DEFINE_LONGS(HOST_RBX, RBX); + DEFINE_LONGS(HOST_RCX, RCX); + DEFINE_LONGS(HOST_RDI, RDI); + DEFINE_LONGS(HOST_RSI, RSI); + DEFINE_LONGS(HOST_RDX, RDX); + DEFINE_LONGS(HOST_RBP, RBP); + DEFINE_LONGS(HOST_RAX, RAX); + DEFINE_LONGS(HOST_R8, R8); + DEFINE_LONGS(HOST_R9, R9); + DEFINE_LONGS(HOST_R10, R10); + DEFINE_LONGS(HOST_R11, R11); + DEFINE_LONGS(HOST_R12, R12); + DEFINE_LONGS(HOST_R13, R13); + DEFINE_LONGS(HOST_R14, R14); + DEFINE_LONGS(HOST_R15, R15); + DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); + DEFINE_LONGS(HOST_CS, CS); + DEFINE_LONGS(HOST_SS, SS); + DEFINE_LONGS(HOST_EFLAGS, EFLAGS); +#if 0 + DEFINE_LONGS(HOST_FS, FS); + DEFINE_LONGS(HOST_GS, GS); + DEFINE_LONGS(HOST_DS, DS); + DEFINE_LONGS(HOST_ES, ES); +#endif + + DEFINE_LONGS(HOST_IP, RIP); + DEFINE_LONGS(HOST_SP, RSP); +#endif + + DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); + DEFINE(UM_POLLIN, POLLIN); + DEFINE(UM_POLLPRI, POLLPRI); + DEFINE(UM_POLLOUT, POLLOUT); + + DEFINE(UM_PROT_READ, PROT_READ); + DEFINE(UM_PROT_WRITE, PROT_WRITE); + DEFINE(UM_PROT_EXEC, PROT_EXEC); +} diff --git a/arch/um/sys-x86/vdso/Makefile b/arch/um/sys-x86/vdso/Makefile new file mode 100644 index 0000000..5dffe6d --- /dev/null +++ b/arch/um/sys-x86/vdso/Makefile @@ -0,0 +1,90 @@ +# +# Building vDSO images for x86. +# + +VDSO64-y := y + +vdso-install-$(VDSO64-y) += vdso.so + + +# files to link into the vdso +vobjs-y := vdso-note.o um_vdso.o + +# files to link into kernel +obj-$(VDSO64-y) += vdso.o vma.o + +vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) + +$(obj)/vdso.o: $(obj)/vdso.so + +targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) + +export CPPFLAGS_vdso.lds += -P -C + +VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ + -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 + +$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so + +$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE + $(call if_changed,vdso) + +$(obj)/%.so: OBJCOPYFLAGS := -S +$(obj)/%.so: $(obj)/%.so.dbg FORCE + $(call if_changed,objcopy) + +# +# Don't omit frame pointers for ease of userspace debugging, but do +# optimize sibling calls. +# +CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ + $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ + -fno-omit-frame-pointer -foptimize-sibling-calls + +$(vobjs): KBUILD_CFLAGS += $(CFL) + +# +# vDSO code runs in userspace and -pg doesn't help with profiling anyway. +# +CFLAGS_REMOVE_vdso-note.o = -pg +CFLAGS_REMOVE_um_vdso.o = -pg + +targets += vdso-syms.lds +obj-$(VDSO64-y) += vdso-syms.lds + +# +# Match symbols in the DSO that look like VDSO*; produce a file of constants. +# +sed-vdsosym := -e 's/^00*/0/' \ + -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' +quiet_cmd_vdsosym = VDSOSYM $@ +define cmd_vdsosym + $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +endef + +$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE + $(call if_changed,vdsosym) + +# +# The DSO images are built using a special linker script. +# +quiet_cmd_vdso = VDSO $@ + cmd_vdso = $(CC) -nostdlib -o $@ \ + $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ + -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ + sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' + +VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) +GCOV_PROFILE := n + +# +# Install the unstripped copy of vdso*.so listed in $(vdso-install-y). +# +quiet_cmd_vdso_install = INSTALL $@ + cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ +$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE + @mkdir -p $(MODLIB)/vdso + $(call cmd,vdso_install) + +PHONY += vdso_install $(vdso-install-y) +vdso_install: $(vdso-install-y) diff --git a/arch/um/sys-x86/vdso/checkundef.sh b/arch/um/sys-x86/vdso/checkundef.sh new file mode 100644 index 0000000..7ee90a9 --- /dev/null +++ b/arch/um/sys-x86/vdso/checkundef.sh @@ -0,0 +1,10 @@ +#!/bin/sh +nm="$1" +file="$2" +$nm "$file" | grep '^ *U' > /dev/null 2>&1 +if [ $? -eq 1 ]; then + exit 0 +else + echo "$file: undefined symbols found" >&2 + exit 1 +fi diff --git a/arch/um/sys-x86/vdso/um_vdso.c b/arch/um/sys-x86/vdso/um_vdso.c new file mode 100644 index 0000000..7c441b5 --- /dev/null +++ b/arch/um/sys-x86/vdso/um_vdso.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This vDSO turns all calls into a syscall so that UML can trap them. + */ + + +/* Disable profiling for userspace code */ +#define DISABLE_BRANCH_PROFILING + +#include +#include +#include + +int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) +{ + long ret; + + asm("syscall" : "=a" (ret) : + "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); + + return ret; +} +int clock_gettime(clockid_t, struct timespec *) + __attribute__((weak, alias("__vdso_clock_gettime"))); + +int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + long ret; + + asm("syscall" : "=a" (ret) : + "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); + + return ret; +} +int gettimeofday(struct timeval *, struct timezone *) + __attribute__((weak, alias("__vdso_gettimeofday"))); + +time_t __vdso_time(time_t *t) +{ + long secs; + + asm volatile("syscall" + : "=a" (secs) + : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); + + return secs; +} +int time(time_t *t) __attribute__((weak, alias("__vdso_time"))); + +long +__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) +{ + /* + * UML does not support SMP, we can cheat here. :) + */ + + if (cpu) + *cpu = 0; + if (node) + *node = 0; + + return 0; +} + +long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) + __attribute__((weak, alias("__vdso_getcpu"))); diff --git a/arch/um/sys-x86/vdso/vdso-layout.lds.S b/arch/um/sys-x86/vdso/vdso-layout.lds.S new file mode 100644 index 0000000..634a2cf --- /dev/null +++ b/arch/um/sys-x86/vdso/vdso-layout.lds.S @@ -0,0 +1,64 @@ +/* + * Linker script for vDSO. This is an ELF shared object prelinked to + * its virtual address, and with only one read-only segment. + * This script controls its layout. + */ + +SECTIONS +{ + . = VDSO_PRELINK + SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + .note : { *(.note.*) } :text :note + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + + .dynamic : { *(.dynamic) } :text :dynamic + + .rodata : { *(.rodata*) } :text + .data : { + *(.data*) + *(.sdata*) + *(.got.plt) *(.got) + *(.gnu.linkonce.d.*) + *(.bss*) + *(.dynbss*) + *(.gnu.linkonce.b.*) + } + + .altinstructions : { *(.altinstructions) } + .altinstr_replacement : { *(.altinstr_replacement) } + + /* + * Align the actual code well away from the non-instruction data. + * This is the best thing for the I-cache. + */ + . = ALIGN(0x100); + + .text : { *(.text*) } :text =0x90909090 +} + +/* + * Very old versions of ld do not recognize this name token; use the constant. + */ +#define PT_GNU_EH_FRAME 0x6474e550 + +/* + * We must supply the ELF program headers explicitly to get just one + * PT_LOAD segment, and set the flags explicitly to make segments read-only. + */ +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + note PT_NOTE FLAGS(4); /* PF_R */ + eh_frame_hdr PT_GNU_EH_FRAME; +} diff --git a/arch/um/sys-x86/vdso/vdso-note.S b/arch/um/sys-x86/vdso/vdso-note.S new file mode 100644 index 0000000..79a071e --- /dev/null +++ b/arch/um/sys-x86/vdso/vdso-note.S @@ -0,0 +1,12 @@ +/* + * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. + * Here we can supply some information useful to userland. + */ + +#include +#include +#include + +ELFNOTE_START(Linux, 0, "a") + .long LINUX_VERSION_CODE +ELFNOTE_END diff --git a/arch/um/sys-x86/vdso/vdso.S b/arch/um/sys-x86/vdso/vdso.S new file mode 100644 index 0000000..03b0532 --- /dev/null +++ b/arch/um/sys-x86/vdso/vdso.S @@ -0,0 +1,10 @@ +#include + +__INITDATA + + .globl vdso_start, vdso_end +vdso_start: + .incbin "arch/um/sys-x86/vdso/vdso.so" +vdso_end: + +__FINIT diff --git a/arch/um/sys-x86/vdso/vdso.lds.S b/arch/um/sys-x86/vdso/vdso.lds.S new file mode 100644 index 0000000..b96b267 --- /dev/null +++ b/arch/um/sys-x86/vdso/vdso.lds.S @@ -0,0 +1,32 @@ +/* + * Linker script for 64-bit vDSO. + * We #include the file to define the layout details. + * Here we only choose the prelinked virtual address. + * + * This file defines the version script giving the user-exported symbols in + * the DSO. We can define local symbols here called VDSO* to make their + * values visible using the asm-x86/vdso.h macros from the kernel proper. + */ + +#define VDSO_PRELINK 0xffffffffff700000 +#include "vdso-layout.lds.S" + +/* + * This controls what userland symbols we export from the vDSO. + */ +VERSION { + LINUX_2.6 { + global: + clock_gettime; + __vdso_clock_gettime; + gettimeofday; + __vdso_gettimeofday; + getcpu; + __vdso_getcpu; + time; + __vdso_time; + local: *; + }; +} + +VDSO64_PRELINK = VDSO_PRELINK; diff --git a/arch/um/sys-x86/vdso/vma.c b/arch/um/sys-x86/vdso/vma.c new file mode 100644 index 0000000..9495c8d --- /dev/null +++ b/arch/um/sys-x86/vdso/vma.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +unsigned int __read_mostly vdso_enabled = 1; +unsigned long um_vdso_addr; + +extern unsigned long task_size; +extern char vdso_start[], vdso_end[]; + +static struct page **vdsop; + +static int __init init_vdso(void) +{ + struct page *um_vdso; + + BUG_ON(vdso_end - vdso_start > PAGE_SIZE); + + um_vdso_addr = task_size - PAGE_SIZE; + + vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *)); + if (!vdsop) + goto oom; + + um_vdso = alloc_page(GFP_KERNEL); + if (!um_vdso) { + kfree(vdsop); + + goto oom; + } + + copy_page(page_address(um_vdso), vdso_start); + *vdsop = um_vdso; + + return 0; + +oom: + printk(KERN_ERR "Cannot allocate vdso\n"); + vdso_enabled = 0; + + return -ENOMEM; +} +subsys_initcall(init_vdso); + +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + int err; + struct mm_struct *mm = current->mm; + + if (!vdso_enabled) + return 0; + + down_write(&mm->mmap_sem); + + err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + vdsop); + + up_write(&mm->mmap_sem); + + return err; +} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile deleted file mode 100644 index 0971846..0000000 --- a/arch/um/sys-x86_64/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright 2003 PathScale, Inc. -# -# Licensed under the GPL -# - -obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o mem.o \ - setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ - sysrq.o ksyms.o tls.o - -obj-y += vdso/ - -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ - lib/rwsem.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -ldt-y = ../sys-i386/ldt.o - -USER_OBJS := ptrace_user.o - -extra-y += user-offsets.s -$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c deleted file mode 100644 index e8034e3..0000000 --- a/arch/um/sys-x86_64/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include - -/* - * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c deleted file mode 100644 index 44e02ba..0000000 --- a/arch/um/sys-x86_64/bugs.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -void arch_check_bugs(void) -{ -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ -} diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c deleted file mode 100644 index f3fe1a6..0000000 --- a/arch/um/sys-x86_64/delay.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * Mostly copied from arch/x86/lib/delay.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -void __delay(unsigned long loops) -{ - asm volatile( - "test %0,%0\n" - "jz 3f\n" - "jmp 1f\n" - - ".align 16\n" - "1: jmp 2f\n" - - ".align 16\n" - "2: dec %0\n" - " jnz 2b\n" - "3: dec %0\n" - - : /* we don't need output */ - : "a" (loops) - ); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - asm("mull %%edx" - : "=d" (xloops), "=&a" (d0) - : "1" (xloops), "0" - (loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c deleted file mode 100644 index ce85117..0000000 --- a/arch/um/sys-x86_64/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c deleted file mode 100644 index 1db2fce..0000000 --- a/arch/um/sys-x86_64/ksyms.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include - -/*XXX: we need them because they would be exported by x86_64 */ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 -EXPORT_SYMBOL(memcpy); -#else -EXPORT_SYMBOL(__memcpy); -#endif -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c deleted file mode 100644 index 5465187..0000000 --- a/arch/um/sys-x86_64/mem.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/mman.h" - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == um_vdso_addr) - return "[vdso]"; - - return NULL; -} - -struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return NULL; -} - -int in_gate_area(struct mm_struct *mm, unsigned long addr) -{ - return 0; -} - -int in_gate_area_no_mm(unsigned long addr) -{ - return 0; -} diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c deleted file mode 100644 index 44e68e0..0000000 --- a/arch/um/sys-x86_64/ptrace.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#include -#include -#include -#define __FRAME_OFFSETS -#include -#include - -/* - * determines which flags the user has access to. - * 1 = access 0 = no access - */ -#define FLAG_MASK 0x44dd5UL - -static const int reg_offsets[] = -{ - [R8 >> 3] = HOST_R8, - [R9 >> 3] = HOST_R9, - [R10 >> 3] = HOST_R10, - [R11 >> 3] = HOST_R11, - [R12 >> 3] = HOST_R12, - [R13 >> 3] = HOST_R13, - [R14 >> 3] = HOST_R14, - [R15 >> 3] = HOST_R15, - [RIP >> 3] = HOST_IP, - [RSP >> 3] = HOST_SP, - [RAX >> 3] = HOST_RAX, - [RBX >> 3] = HOST_RBX, - [RCX >> 3] = HOST_RCX, - [RDX >> 3] = HOST_RDX, - [RSI >> 3] = HOST_RSI, - [RDI >> 3] = HOST_RDI, - [RBP >> 3] = HOST_RBP, - [CS >> 3] = HOST_CS, - [SS >> 3] = HOST_SS, - [FS_BASE >> 3] = HOST_FS_BASE, - [GS_BASE >> 3] = HOST_GS_BASE, - [DS >> 3] = HOST_DS, - [ES >> 3] = HOST_ES, - [FS >> 3] = HOST_FS, - [GS >> 3] = HOST_GS, - [EFLAGS >> 3] = HOST_EFLAGS, - [ORIG_RAX >> 3] = HOST_ORIG_RAX, -}; - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ -#ifdef TIF_IA32 - /* - * Some code in the 64bit emulation may not be 64bit clean. - * Don't take any chances. - */ - if (test_tsk_thread_flag(child, TIF_IA32)) - value &= 0xffffffff; -#endif - switch (regno) { - case R8: - case R9: - case R10: - case R11: - case R12: - case R13: - case R14: - case R15: - case RIP: - case RSP: - case RAX: - case RBX: - case RCX: - case RDX: - case RSI: - case RDI: - case RBP: - case ORIG_RAX: - break; - - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - - case FS_BASE: - case GS_BASE: - if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) - return -EIO; - break; - - case EFLAGS: - value &= FLAG_MASK; - child->thread.regs.regs.gp[HOST_EFLAGS] |= value; - return 0; - - default: - panic("Bad register in putreg(): %d\n", regno); - } - - child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; - return 0; -} - -int poke_user(struct task_struct *child, long addr, long data) -{ - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if ((addr == 4) || (addr == 5)) - return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; -} - -unsigned long getreg(struct task_struct *child, int regno) -{ - unsigned long mask = ~0UL; -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - mask = 0xffffffff; -#endif - switch (regno) { - case R8: - case R9: - case R10: - case R11: - case R12: - case R13: - case R14: - case R15: - case RIP: - case RSP: - case RAX: - case RBX: - case RCX: - case RDX: - case RSI: - case RDI: - case RBP: - case ORIG_RAX: - case EFLAGS: - case FS_BASE: - case GS_BASE: - break; - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - mask = 0xffff; - break; - default: - panic("Bad register in getreg: %d\n", regno); - } - return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; -} - -int peek_user(struct task_struct *child, long addr, long data) -{ - /* read the word at location addr in the USER area. */ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if (addr < MAX_REG_OFFSET) - tmp = getreg(child, addr); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long *) data); -} - -/* XXX Mostly copied from sys-i386 */ -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* - * access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk("is_syscall : failed to read instruction from " - "0x%lx\n", addr); - return 1; - } - } - /* sysenter */ - return instr == 0x050f; -} - -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - err = save_fp_registers(userspace_pid[cpu], fpregs); - if (err) - return err; - - n = copy_to_user(buf, fpregs, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - n = copy_from_user(fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EIO; - void __user *datap = (void __user *) data; - - switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; - } - - return ret; -} diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c deleted file mode 100644 index c57a496..0000000 --- a/arch/um/sys-x86_64/ptrace_user.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include -#include "ptrace_user.h" - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} - -int ptrace_setregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} diff --git a/arch/um/sys-x86_64/setjmp.S b/arch/um/sys-x86_64/setjmp.S deleted file mode 100644 index 45f547b..0000000 --- a/arch/um/sys-x86_64/setjmp.S +++ /dev/null @@ -1,54 +0,0 @@ -# -# arch/x86_64/setjmp.S -# -# setjmp/longjmp for the x86-64 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %rbx -# %rsp (post-return) -# %rbp -# %r12 -# %r13 -# %r14 -# %r15 -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - pop %rsi # Return address, and adjust the stack - xorl %eax,%eax # Return value - movq %rbx,(%rdi) - movq %rsp,8(%rdi) # Post-return %rsp! - push %rsi # Make the call/return stack happy - movq %rbp,16(%rdi) - movq %r12,24(%rdi) - movq %r13,32(%rdi) - movq %r14,40(%rdi) - movq %r15,48(%rdi) - movq %rsi,56(%rdi) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - movl %esi,%eax # Return value (int) - movq (%rdi),%rbx - movq 8(%rdi),%rsp - movq 16(%rdi),%rbp - movq 24(%rdi),%r12 - movq 32(%rdi),%r13 - movq 40(%rdi),%r14 - movq 48(%rdi),%r15 - jmp *56(%rdi) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c deleted file mode 100644 index 255b2ca..0000000 --- a/arch/um/sys-x86_64/signal.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "frame_kern.h" -#include "skas.h" - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from) -{ - struct sigcontext sc; - struct user_i387_struct fp; - void __user *buf; - int err; - - err = copy_from_user(&sc, from, sizeof(sc)); - if (err) - return err; - -#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname - - GETREG(R8, r8); - GETREG(R9, r9); - GETREG(R10, r10); - GETREG(R11, r11); - GETREG(R12, r12); - GETREG(R13, r13); - GETREG(R14, r14); - GETREG(R15, r15); - GETREG(RDI, di); - GETREG(RSI, si); - GETREG(RBP, bp); - GETREG(RBX, bx); - GETREG(RDX, dx); - GETREG(RAX, ax); - GETREG(RCX, cx); - GETREG(SP, sp); - GETREG(IP, ip); - GETREG(EFLAGS, flags); - GETREG(CS, cs); -#undef GETREG - - buf = sc.fpstate; - - err = copy_from_user(&fp, buf, sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long mask, unsigned long sp) -{ - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - struct sigcontext sc; - struct user_i387_struct fp; - int err = 0; - memset(&sc, 0, sizeof(struct sigcontext)); - -#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno] - - PUTREG(RDI, di); - PUTREG(RSI, si); - PUTREG(RBP, bp); - /* - * Must use original RSP, which is passed in, rather than what's in - * signal frame. - */ - sc.sp = sp; - PUTREG(RBX, bx); - PUTREG(RDX, dx); - PUTREG(RCX, cx); - PUTREG(RAX, ax); - PUTREG(R8, r8); - PUTREG(R9, r9); - PUTREG(R10, r10); - PUTREG(R11, r11); - PUTREG(R12, r12); - PUTREG(R13, r13); - PUTREG(R14, r14); - PUTREG(R15, r15); - PUTREG(CS, cs); /* XXX x86_64 doesn't do this */ - - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - PUTREG(IP, ip); - PUTREG(EFLAGS, flags); -#undef PUTREG - - sc.oldmask = mask; - - err = copy_to_user(to, &sc, sizeof(struct sigcontext)); - if (err) - return 1; - - err = save_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " - "failed, errno = %d\n", -err); - return 1; - } - - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - - return err; -} - -struct rt_sigframe -{ - char __user *pretcode; - struct ucontext uc; - struct siginfo info; - struct _fpstate fpstate; -}; - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs * regs, - siginfo_t *info, sigset_t *set) -{ - struct rt_sigframe __user *frame; - unsigned long save_sp = PT_REGS_RSP(regs); - int err = 0; - struct task_struct *me = current; - - frame = (struct rt_sigframe __user *) - round_down(stack_top - sizeof(struct rt_sigframe), 16); - /* Subtract 128 for a red zone and 8 for proper alignment */ - frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto out; - - if (ka->sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto out; - } - - /* - * Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_RSP(regs) = (unsigned long) frame; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(save_sp), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, - set->sig[0], save_sp); - err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); - if (sizeof(*set) == 16) { - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); - } - else - err |= __copy_to_user(&frame->uc.uc_sigmask, set, - sizeof(*set)); - - /* - * Set up to return from userspace. If provided, use a stub - * already in userspace. - */ - /* x86-64 should always use SA_RESTORER. */ - if (ka->sa.sa_flags & SA_RESTORER) - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); - else - /* could use a vstub here */ - goto restore_sp; - - if (err) - goto restore_sp; - - /* Set up registers for signal handler */ - { - struct exec_domain *ed = current_thread_info()->exec_domain; - if (unlikely(ed && ed->signal_invmap && sig < 32)) - sig = ed->signal_invmap[sig]; - } - - PT_REGS_RDI(regs) = sig; - /* In case the signal handler was declared without prototypes */ - PT_REGS_RAX(regs) = 0; - - /* - * This also works for non SA_SIGINFO handlers because they expect the - * next argument after the signal number on the stack. - */ - PT_REGS_RSI(regs) = (unsigned long) &frame->info; - PT_REGS_RDX(regs) = (unsigned long) &frame->uc; - PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; - out: - return err; - -restore_sp: - PT_REGS_RSP(regs) = save_sp; - return err; -} - -long sys_rt_sigreturn(struct pt_regs *regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *)(sp - 8); - struct ucontext __user *uc = &frame->uc; - sigset_t set; - - if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S deleted file mode 100644 index 20e4a96..0000000 --- a/arch/um/sys-x86_64/stub.S +++ /dev/null @@ -1,66 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" -syscall_stub: - syscall - /* We don't have 64-bit constants, so this constructs the address - * we need. - */ - movq $(STUB_DATA >> 32), %rbx - salq $32, %rbx - movq $(STUB_DATA & 0xffffffff), %rcx - or %rcx, %rbx - movq %rax, (%rbx) - int3 - - .globl batch_syscall_stub -batch_syscall_stub: - mov $(STUB_DATA >> 32), %rbx - sal $32, %rbx - mov $(STUB_DATA & 0xffffffff), %rax - or %rax, %rbx - /* load pointer to first operation */ - mov %rbx, %rsp - add $0x10, %rsp -again: - /* load length of additional data */ - mov 0x0(%rsp), %rax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %rax, 8(%rbx) - cmp $0, %rax - jz done - - /* save current pointer */ - mov %rsp, 8(%rbx) - - /* skip additional data */ - add %rax, %rsp - - /* load syscall-# */ - pop %rax - - /* load syscall params */ - pop %rdi - pop %rsi - pop %rdx - pop %r10 - pop %r8 - pop %r9 - - /* execute syscall */ - syscall - - /* check return value */ - pop %rcx - cmp %rcx, %rax - je again - -done: - /* save return value */ - mov %rax, (%rbx) - - /* stop */ - int3 diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c deleted file mode 100644 index ced051a..0000000 --- a/arch/um/sys-x86_64/stub_segv.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "as-layout.h" -#include "sysdep/stub.h" -#include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct ucontext *uc; - - __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), - &uc->uc_mcontext); - trap_myself(); -} - diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c deleted file mode 100644 index f46de82..0000000 --- a/arch/um/sys-x86_64/syscall_table.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c - * with some changes for UML. - */ - -#include -#include -#include - -#define __NO_STUBS - -/* - * Below you can see, in terms of #define's, the differences between the x86-64 - * and the UML syscall table. - */ - -/* Not going to be implemented by UML, since we have no hardware. */ -#define stub_iopl sys_ni_syscall -#define sys_ioperm sys_ni_syscall - -/* - * The UML TLS problem. Note that x86_64 does not implement this, so the below - * is needed only for the ia32 compatibility. - */ - -/* On UML we call it this way ("old" means it's not mmap2) */ -#define sys_mmap old_mmap - -#define stub_clone sys_clone -#define stub_fork sys_fork -#define stub_vfork sys_vfork -#define stub_execve sys_execve -#define stub_rt_sigsuspend sys_rt_sigsuspend -#define stub_sigaltstack sys_sigaltstack -#define stub_rt_sigreturn sys_rt_sigreturn - -#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; -#undef _ASM_X86_UNISTD_64_H -#include "../../x86/include/asm/unistd_64.h" - -#undef __SYSCALL -#define __SYSCALL(nr, sym) [ nr ] = sym, -#undef _ASM_X86_UNISTD_64_H - -typedef void (*sys_call_ptr_t)(void); - -extern void sys_ni_syscall(void); - -/* - * We used to have a trick here which made sure that holes in the - * x86_64 table were filled in with sys_ni_syscall, but a comment in - * unistd_64.h says that holes aren't allowed, so the trick was - * removed. - * The trick looked like this - * [0 ... UM_NR_syscall_max] = &sys_ni_syscall - * before including unistd_64.h - the later initializations overwrote - * the sys_ni_syscall filler. - */ - -sys_call_ptr_t sys_call_table[] __cacheline_aligned = { -#include "../../x86/include/asm/unistd_64.h" -}; - -int syscall_table_size = sizeof(sys_call_table); diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c deleted file mode 100644 index f3d82bb..0000000 --- a/arch/um/sys-x86_64/syscalls.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "linux/linkage.h" -#include "linux/personality.h" -#include "linux/utsname.h" -#include "asm/prctl.h" /* XXX This should get the constants from libc */ -#include "asm/uaccess.h" -#include "os.h" - -long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) -{ - unsigned long *ptr = addr, tmp; - long ret; - int pid = task->mm->context.id.u.pid; - - /* - * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to - * be safe), we need to call arch_prctl on the host because - * setting %fs may result in something else happening (like a - * GDT or thread.fs being set instead). So, we let the host - * fiddle the registers and thread struct and restore the - * registers afterwards. - * - * So, the saved registers are stored to the process (this - * needed because a stub may have been the last thing to run), - * arch_prctl is run on the host, then the registers are read - * back. - */ - switch (code) { - case ARCH_SET_FS: - case ARCH_SET_GS: - ret = restore_registers(pid, ¤t->thread.regs.regs); - if (ret) - return ret; - break; - case ARCH_GET_FS: - case ARCH_GET_GS: - /* - * With these two, we read to a local pointer and - * put_user it to the userspace pointer that we were - * given. If addr isn't valid (because it hasn't been - * faulted in or is just bogus), we want put_user to - * fault it in (or return -EFAULT) instead of having - * the host return -EFAULT. - */ - ptr = &tmp; - } - - ret = os_arch_prctl(pid, code, ptr); - if (ret) - return ret; - - switch (code) { - case ARCH_SET_FS: - current->thread.arch.fs = (unsigned long) ptr; - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_SET_GS: - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_GET_FS: - ret = put_user(tmp, addr); - break; - case ARCH_GET_GS: - ret = put_user(tmp, addr); - break; - } - - return ret; -} - -long sys_arch_prctl(int code, unsigned long addr) -{ - return arch_prctl(current, code, (unsigned long __user *) addr); -} - -long sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -void arch_switch_to(struct task_struct *to) -{ - if ((to->thread.arch.fs == 0) || (to->mm == NULL)) - return; - - arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); -} diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c deleted file mode 100644 index f4f82be..0000000 --- a/arch/um/sys-x86_64/sysrq.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "sysrq.h" - -void __show_regs(struct pt_regs *regs) -{ - printk("\n"); - print_modules(); - printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), - current->comm, print_tainted(), init_utsname()->release); - printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, - PT_REGS_RIP(regs)); - printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), - PT_REGS_EFLAGS(regs)); - printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", - PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); - printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", - PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); - printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", - PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); - printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", - PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); - printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", - PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); -} - -void show_regs(struct pt_regs *regs) -{ - __show_regs(regs); - show_trace(current, (unsigned long *) ®s); -} diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c deleted file mode 100644 index f7ba462..0000000 --- a/arch/um/sys-x86_64/tls.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "linux/sched.h" - -void clear_flushed_tls(struct task_struct *task) -{ -} - -int arch_copy_tls(struct task_struct *t) -{ - /* - * If CLONE_SETTLS is set, we need to save the thread id - * (which is argument 5, child_tid, of clone) so it can be set - * during context switches. - */ - t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; - - return 0; -} diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c deleted file mode 100644 index 9735854..0000000 --- a/arch/um/sys-x86_64/user-offsets.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define __FRAME_OFFSETS -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ - OFFSET(HOST_SC_CR2, sigcontext, cr2); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - - DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); - DEFINE_LONGS(HOST_RBX, RBX); - DEFINE_LONGS(HOST_RCX, RCX); - DEFINE_LONGS(HOST_RDI, RDI); - DEFINE_LONGS(HOST_RSI, RSI); - DEFINE_LONGS(HOST_RDX, RDX); - DEFINE_LONGS(HOST_RBP, RBP); - DEFINE_LONGS(HOST_RAX, RAX); - DEFINE_LONGS(HOST_R8, R8); - DEFINE_LONGS(HOST_R9, R9); - DEFINE_LONGS(HOST_R10, R10); - DEFINE_LONGS(HOST_R11, R11); - DEFINE_LONGS(HOST_R12, R12); - DEFINE_LONGS(HOST_R13, R13); - DEFINE_LONGS(HOST_R14, R14); - DEFINE_LONGS(HOST_R15, R15); - DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); - DEFINE_LONGS(HOST_CS, CS); - DEFINE_LONGS(HOST_SS, SS); - DEFINE_LONGS(HOST_EFLAGS, EFLAGS); -#if 0 - DEFINE_LONGS(HOST_FS, FS); - DEFINE_LONGS(HOST_GS, GS); - DEFINE_LONGS(HOST_DS, DS); - DEFINE_LONGS(HOST_ES, ES); -#endif - - DEFINE_LONGS(HOST_IP, RIP); - DEFINE_LONGS(HOST_SP, RSP); - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); - - /* XXX Duplicated between i386 and x86_64 */ - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} diff --git a/arch/um/sys-x86_64/vdso/Makefile b/arch/um/sys-x86_64/vdso/Makefile deleted file mode 100644 index 5dffe6d..0000000 --- a/arch/um/sys-x86_64/vdso/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# -# Building vDSO images for x86. -# - -VDSO64-y := y - -vdso-install-$(VDSO64-y) += vdso.so - - -# files to link into the vdso -vobjs-y := vdso-note.o um_vdso.o - -# files to link into kernel -obj-$(VDSO64-y) += vdso.o vma.o - -vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) - -$(obj)/vdso.o: $(obj)/vdso.so - -targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) - -export CPPFLAGS_vdso.lds += -P -C - -VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 - -$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so - -$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE - $(call if_changed,vdso) - -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -# -# Don't omit frame pointers for ease of userspace debugging, but do -# optimize sibling calls. -# -CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ - $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ - -fno-omit-frame-pointer -foptimize-sibling-calls - -$(vobjs): KBUILD_CFLAGS += $(CFL) - -# -# vDSO code runs in userspace and -pg doesn't help with profiling anyway. -# -CFLAGS_REMOVE_vdso-note.o = -pg -CFLAGS_REMOVE_um_vdso.o = -pg - -targets += vdso-syms.lds -obj-$(VDSO64-y) += vdso-syms.lds - -# -# Match symbols in the DSO that look like VDSO*; produce a file of constants. -# -sed-vdsosym := -e 's/^00*/0/' \ - -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' -quiet_cmd_vdsosym = VDSOSYM $@ -define cmd_vdsosym - $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ -endef - -$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE - $(call if_changed,vdsosym) - -# -# The DSO images are built using a special linker script. -# -quiet_cmd_vdso = VDSO $@ - cmd_vdso = $(CC) -nostdlib -o $@ \ - $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ - -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ - sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' - -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) -GCOV_PROFILE := n - -# -# Install the unstripped copy of vdso*.so listed in $(vdso-install-y). -# -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ -$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -PHONY += vdso_install $(vdso-install-y) -vdso_install: $(vdso-install-y) diff --git a/arch/um/sys-x86_64/vdso/checkundef.sh b/arch/um/sys-x86_64/vdso/checkundef.sh deleted file mode 100644 index 7ee90a9..0000000 --- a/arch/um/sys-x86_64/vdso/checkundef.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -nm="$1" -file="$2" -$nm "$file" | grep '^ *U' > /dev/null 2>&1 -if [ $? -eq 1 ]; then - exit 0 -else - echo "$file: undefined symbols found" >&2 - exit 1 -fi diff --git a/arch/um/sys-x86_64/vdso/um_vdso.c b/arch/um/sys-x86_64/vdso/um_vdso.c deleted file mode 100644 index 7c441b5..0000000 --- a/arch/um/sys-x86_64/vdso/um_vdso.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This vDSO turns all calls into a syscall so that UML can trap them. - */ - - -/* Disable profiling for userspace code */ -#define DISABLE_BRANCH_PROFILING - -#include -#include -#include - -int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) -{ - long ret; - - asm("syscall" : "=a" (ret) : - "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); - - return ret; -} -int clock_gettime(clockid_t, struct timespec *) - __attribute__((weak, alias("__vdso_clock_gettime"))); - -int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) -{ - long ret; - - asm("syscall" : "=a" (ret) : - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); - - return ret; -} -int gettimeofday(struct timeval *, struct timezone *) - __attribute__((weak, alias("__vdso_gettimeofday"))); - -time_t __vdso_time(time_t *t) -{ - long secs; - - asm volatile("syscall" - : "=a" (secs) - : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); - - return secs; -} -int time(time_t *t) __attribute__((weak, alias("__vdso_time"))); - -long -__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) -{ - /* - * UML does not support SMP, we can cheat here. :) - */ - - if (cpu) - *cpu = 0; - if (node) - *node = 0; - - return 0; -} - -long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) - __attribute__((weak, alias("__vdso_getcpu"))); diff --git a/arch/um/sys-x86_64/vdso/vdso-layout.lds.S b/arch/um/sys-x86_64/vdso/vdso-layout.lds.S deleted file mode 100644 index 634a2cf..0000000 --- a/arch/um/sys-x86_64/vdso/vdso-layout.lds.S +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Linker script for vDSO. This is an ELF shared object prelinked to - * its virtual address, and with only one read-only segment. - * This script controls its layout. - */ - -SECTIONS -{ - . = VDSO_PRELINK + SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - - .dynamic : { *(.dynamic) } :text :dynamic - - .rodata : { *(.rodata*) } :text - .data : { - *(.data*) - *(.sdata*) - *(.got.plt) *(.got) - *(.gnu.linkonce.d.*) - *(.bss*) - *(.dynbss*) - *(.gnu.linkonce.b.*) - } - - .altinstructions : { *(.altinstructions) } - .altinstr_replacement : { *(.altinstr_replacement) } - - /* - * Align the actual code well away from the non-instruction data. - * This is the best thing for the I-cache. - */ - . = ALIGN(0x100); - - .text : { *(.text*) } :text =0x90909090 -} - -/* - * Very old versions of ld do not recognize this name token; use the constant. - */ -#define PT_GNU_EH_FRAME 0x6474e550 - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; -} diff --git a/arch/um/sys-x86_64/vdso/vdso-note.S b/arch/um/sys-x86_64/vdso/vdso-note.S deleted file mode 100644 index 79a071e..0000000 --- a/arch/um/sys-x86_64/vdso/vdso-note.S +++ /dev/null @@ -1,12 +0,0 @@ -/* - * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. - * Here we can supply some information useful to userland. - */ - -#include -#include -#include - -ELFNOTE_START(Linux, 0, "a") - .long LINUX_VERSION_CODE -ELFNOTE_END diff --git a/arch/um/sys-x86_64/vdso/vdso.S b/arch/um/sys-x86_64/vdso/vdso.S deleted file mode 100644 index ec82c16..0000000 --- a/arch/um/sys-x86_64/vdso/vdso.S +++ /dev/null @@ -1,10 +0,0 @@ -#include - -__INITDATA - - .globl vdso_start, vdso_end -vdso_start: - .incbin "arch/um/sys-x86_64/vdso/vdso.so" -vdso_end: - -__FINIT diff --git a/arch/um/sys-x86_64/vdso/vdso.lds.S b/arch/um/sys-x86_64/vdso/vdso.lds.S deleted file mode 100644 index b96b267..0000000 --- a/arch/um/sys-x86_64/vdso/vdso.lds.S +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Linker script for 64-bit vDSO. - * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. - * - * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. - */ - -#define VDSO_PRELINK 0xffffffffff700000 -#include "vdso-layout.lds.S" - -/* - * This controls what userland symbols we export from the vDSO. - */ -VERSION { - LINUX_2.6 { - global: - clock_gettime; - __vdso_clock_gettime; - gettimeofday; - __vdso_gettimeofday; - getcpu; - __vdso_getcpu; - time; - __vdso_time; - local: *; - }; -} - -VDSO64_PRELINK = VDSO_PRELINK; diff --git a/arch/um/sys-x86_64/vdso/vma.c b/arch/um/sys-x86_64/vdso/vma.c deleted file mode 100644 index 9495c8d..0000000 --- a/arch/um/sys-x86_64/vdso/vma.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -unsigned int __read_mostly vdso_enabled = 1; -unsigned long um_vdso_addr; - -extern unsigned long task_size; -extern char vdso_start[], vdso_end[]; - -static struct page **vdsop; - -static int __init init_vdso(void) -{ - struct page *um_vdso; - - BUG_ON(vdso_end - vdso_start > PAGE_SIZE); - - um_vdso_addr = task_size - PAGE_SIZE; - - vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *)); - if (!vdsop) - goto oom; - - um_vdso = alloc_page(GFP_KERNEL); - if (!um_vdso) { - kfree(vdsop); - - goto oom; - } - - copy_page(page_address(um_vdso), vdso_start); - *vdsop = um_vdso; - - return 0; - -oom: - printk(KERN_ERR "Cannot allocate vdso\n"); - vdso_enabled = 0; - - return -ENOMEM; -} -subsys_initcall(init_vdso); - -int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) -{ - int err; - struct mm_struct *mm = current->mm; - - if (!vdso_enabled) - return 0; - - down_write(&mm->mmap_sem); - - err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - vdsop); - - up_write(&mm->mmap_sem); - - return err; -} -- cgit v1.1 From 5d40de0f6e726dc9c48fb35815e0a6153e59e1dc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:29 +0100 Subject: um: kill dead code around uaccess Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 6 ------ arch/um/include/shared/um_uaccess.h | 3 --- arch/um/kernel/Makefile | 2 +- arch/um/kernel/uaccess.c | 33 --------------------------------- arch/um/os-Linux/Makefile | 4 ++-- arch/um/os-Linux/uaccess.c | 32 -------------------------------- 6 files changed, 3 insertions(+), 77 deletions(-) delete mode 100644 arch/um/kernel/uaccess.c delete mode 100644 arch/um/os-Linux/uaccess.c (limited to 'arch/um') diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 83c7c2e..2e2663a 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -203,12 +203,6 @@ extern int os_drop_memory(void *addr, int length); extern int can_drop_memory(void); extern void os_flush_stdout(void); -/* uaccess.c */ -extern unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out); - /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ diff --git a/arch/um/include/shared/um_uaccess.h b/arch/um/include/shared/um_uaccess.h index 45c0499..51e1cce 100644 --- a/arch/um/include/shared/um_uaccess.h +++ b/arch/um/include/shared/um_uaccess.h @@ -32,9 +32,6 @@ extern int copy_from_user(void *to, const void __user *from, int n); extern int copy_to_user(void __user *to, const void *from, int n); -extern int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher); - /* * strncpy_from_user: - Copy a NUL terminated string from userspace. * @dst: Destination address, in kernel space. This buffer must be at diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index c4491c1..bc49474 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -11,7 +11,7 @@ clean-files := obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ - signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ + signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o skas/ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c deleted file mode 100644 index dd33f04..0000000 --- a/arch/um/kernel/uaccess.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -/* - * These are here rather than tt/uaccess.c because skas mode needs them in - * order to do SIGBUS recovery when a tmpfs mount runs out of room. - */ - -#include -#include "os.h" - -static void __do_copy(void *to, const void *from, int n) -{ - memcpy(to, from, n); -} - - -int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher) -{ - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); - if (!faulted) - return 0; - else - return n - (fault - (unsigned long) to); -} diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index b33f4df..7aec5bfe 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -4,14 +4,14 @@ # obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ - registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ + registers.o sigio.o signal.o start_up.o time.o tty.o \ umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o tls.o uaccess.o umid.o util.o + tty.o tls.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c deleted file mode 100644 index 087ed74..0000000 --- a/arch/um/os-Linux/uaccess.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "longjmp.h" - -unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out) -{ - unsigned long *faddrp = (unsigned long *) fault_addr, ret; - - jmp_buf jbuf; - *fault_catcher = &jbuf; - if (UML_SETJMP(&jbuf) == 0) { - (*op)(to, from, n); - ret = 0; - *faulted_out = 0; - } - else { - ret = *faddrp; - *faulted_out = 1; - } - *fault_addr = NULL; - *fault_catcher = NULL; - return ret; -} - -- cgit v1.1 From 7eb122555c8583e1601b7a620c5a88c1e06c3eac Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:39 +0100 Subject: um: merge hard_handler() instances, switch to use of SA_SIGINFO Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/signal.c | 12 ++++++++---- arch/um/os-Linux/sys-i386/Makefile | 2 +- arch/um/os-Linux/sys-i386/signal.c | 13 ------------- arch/um/os-Linux/sys-x86_64/Makefile | 2 +- arch/um/os-Linux/sys-x86_64/signal.c | 16 ---------------- 5 files changed, 10 insertions(+), 35 deletions(-) delete mode 100644 arch/um/os-Linux/sys-i386/signal.c delete mode 100644 arch/um/os-Linux/sys-x86_64/signal.c (limited to 'arch/um') diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 4fc3cd1..2dde9f6 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -127,7 +127,7 @@ void set_sigstack(void *sig_stack, int size) static void (*handlers[_NSIG])(int sig, struct sigcontext *sc); -void handle_signal(int sig, struct sigcontext *sc) +static void handle_signal(int sig, struct sigcontext *sc) { unsigned long pending = 1UL << sig; @@ -168,7 +168,11 @@ void handle_signal(int sig, struct sigcontext *sc) } while (pending); } -extern void hard_handler(int sig); +static void hard_handler(int sig, siginfo_t *info, void *p) +{ + struct ucontext *uc = p; + handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); +} void set_handler(int sig, void (*handler)(int), int flags, ...) { @@ -178,7 +182,7 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) int mask; handlers[sig] = (void (*)(int, struct sigcontext *)) handler; - action.sa_handler = hard_handler; + action.sa_sigaction = hard_handler; sigemptyset(&action.sa_mask); @@ -190,7 +194,7 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) if (sig == SIGSEGV) flags |= SA_NODEFER; - action.sa_flags = flags; + action.sa_flags = flags | SA_SIGINFO; action.sa_restorer = NULL; if (sigaction(sig, &action, NULL) < 0) panic("sigaction failed - errno = %d\n", errno); diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile index b4bc6ac..d491754 100644 --- a/arch/um/os-Linux/sys-i386/Makefile +++ b/arch/um/os-Linux/sys-i386/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o signal.o task_size.o tls.o +obj-y = registers.o task_size.o tls.o USER_OBJS := $(obj-y) diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c deleted file mode 100644 index f311609..0000000 --- a/arch/um/os-Linux/sys-i386/signal.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - handle_signal(sig, (struct sigcontext *) (&sig + 1)); -} diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile index a44a47f..58f6e0a 100644 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ b/arch/um/os-Linux/sys-x86_64/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o prctl.o signal.o task_size.o +obj-y = registers.o prctl.o task_size.o USER_OBJS := $(obj-y) diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c deleted file mode 100644 index 82a3888..0000000 --- a/arch/um/os-Linux/sys-x86_64/signal.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - struct ucontext *uc; - asm("movq %%rdx, %0" : "=r" (uc)); - - handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); -} -- cgit v1.1 From 51d34749051a6369093e5067ef67c17f17694921 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:49 +0100 Subject: um: merge arch/um/os-Linux/sys-{i386,x86_64} Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/Makefile | 2 +- arch/um/os-Linux/sys-i386/Makefile | 10 --- arch/um/os-Linux/sys-i386/registers.c | 89 ------------------- arch/um/os-Linux/sys-i386/task_size.c | 138 ----------------------------- arch/um/os-Linux/sys-i386/tls.c | 35 -------- arch/um/os-Linux/sys-x86/Makefile | 13 +++ arch/um/os-Linux/sys-x86/prctl.c | 12 +++ arch/um/os-Linux/sys-x86/registers.c | 111 +++++++++++++++++++++++ arch/um/os-Linux/sys-x86/task_size.c | 150 ++++++++++++++++++++++++++++++++ arch/um/os-Linux/sys-x86/tls.c | 35 ++++++++ arch/um/os-Linux/sys-x86_64/Makefile | 10 --- arch/um/os-Linux/sys-x86_64/prctl.c | 12 --- arch/um/os-Linux/sys-x86_64/registers.c | 50 ----------- arch/um/os-Linux/sys-x86_64/task_size.c | 5 -- 14 files changed, 322 insertions(+), 350 deletions(-) delete mode 100644 arch/um/os-Linux/sys-i386/Makefile delete mode 100644 arch/um/os-Linux/sys-i386/registers.c delete mode 100644 arch/um/os-Linux/sys-i386/task_size.c delete mode 100644 arch/um/os-Linux/sys-i386/tls.c create mode 100644 arch/um/os-Linux/sys-x86/Makefile create mode 100644 arch/um/os-Linux/sys-x86/prctl.c create mode 100644 arch/um/os-Linux/sys-x86/registers.c create mode 100644 arch/um/os-Linux/sys-x86/task_size.c create mode 100644 arch/um/os-Linux/sys-x86/tls.c delete mode 100644 arch/um/os-Linux/sys-x86_64/Makefile delete mode 100644 arch/um/os-Linux/sys-x86_64/prctl.c delete mode 100644 arch/um/os-Linux/sys-x86_64/registers.c delete mode 100644 arch/um/os-Linux/sys-x86_64/task_size.c (limited to 'arch/um') diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 7aec5bfe..7879e76 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -5,7 +5,7 @@ obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ - umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ + umid.o tls.o user_syms.o util.o drivers/ sys-$(HEADER_ARCH)/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile deleted file mode 100644 index d491754..0000000 --- a/arch/um/os-Linux/sys-i386/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o task_size.o tls.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c deleted file mode 100644 index 913d811..0000000 --- a/arch/um/os-Linux/sys-i386/registers.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2004 PathScale, Inc - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include "longjmp.h" -#include "sysdep/ptrace_user.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int save_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case EIP: - return buf[0]->__eip; - case UESP: - return buf[0]->__esp; - case EBP: - return buf[0]->__ebp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int have_fpx_regs = 1; - -int get_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return save_fpx_registers(pid, regs); - else - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return restore_fpx_registers(pid, regs); - else - return restore_fp_registers(pid, regs); -} - -void arch_init_registers(int pid) -{ - struct user_fpxregs_struct fpx_regs; - int err; - - err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); - if (!err) - return; - - if (errno != EIO) - panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", - errno); - - have_fpx_regs = 0; -} diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/um/os-Linux/sys-i386/task_size.c deleted file mode 100644 index 4ce09b8..0000000 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include "longjmp.h" - -static jmp_buf buf; - -static void segfault(int sig) -{ - longjmp(buf, 1); -} - -static int page_ok(unsigned long page) -{ - unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT); - unsigned long n = ~0UL; - void *mapped = NULL; - int ok = 0; - - /* - * First see if the page is readable. If it is, it may still - * be a VDSO, so we go on to see if it's writable. If not - * then try mapping memory there. If that fails, then we're - * still in the kernel area. As a sanity check, we'll fail if - * the mmap succeeds, but gives us an address different from - * what we wanted. - */ - if (setjmp(buf) == 0) - n = *address; - else { - mapped = mmap(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (mapped == MAP_FAILED) - return 0; - if (mapped != address) - goto out; - } - - /* - * Now, is it writeable? If so, then we're in user address - * space. If not, then try mprotecting it and try the write - * again. - */ - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - goto out; - } else if (mprotect(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE) != 0) - goto out; - - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - } - - out: - if (mapped != NULL) - munmap(mapped, UM_KERN_PAGE_SIZE); - return ok; -} - -unsigned long os_get_top_address(void) -{ - struct sigaction sa, old; - unsigned long bottom = 0; - /* - * A 32-bit UML on a 64-bit host gets confused about the VDSO at - * 0xffffe000. It is mapped, is readable, can be reprotected writeable - * and written. However, exec discovers later that it can't be - * unmapped. So, just set the highest address to be checked to just - * below it. This might waste some address space on 4G/4G 32-bit - * hosts, but shouldn't hurt otherwise. - */ - unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test, original; - - printf("Locating the bottom of the address space ... "); - fflush(stdout); - - /* - * We're going to be longjmping out of the signal handler, so - * SA_DEFER needs to be set. - */ - sa.sa_handler = segfault; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; - if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_top_address"); - exit(1); - } - - /* Manually scan the address space, bottom-up, until we find - * the first valid page (or run out of them). - */ - for (bottom = 0; bottom < top; bottom++) { - if (page_ok(bottom)) - break; - } - - /* If we've got this far, we ran out of pages. */ - if (bottom == top) { - fprintf(stderr, "Unable to determine bottom of address " - "space.\n"); - exit(1); - } - - printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); - printf("Locating the top of the address space ... "); - fflush(stdout); - - original = bottom; - - /* This could happen with a 4G/4G split */ - if (page_ok(top)) - goto out; - - do { - test = bottom + (top - bottom) / 2; - if (page_ok(test)) - bottom = test; - else - top = test; - } while (top - bottom > 1); - -out: - /* Restore the old SIGSEGV handling */ - if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_top_address"); - exit(1); - } - top <<= UM_KERN_PAGE_SHIFT; - printf("0x%x\n", top); - - return top; -} diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c deleted file mode 100644 index 281e83e..0000000 --- a/arch/um/os-Linux/sys-i386/tls.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -#include -#include - -#include "sysdep/tls.h" - -/* Checks whether host supports TLS, and sets *tls_min according to the value - * valid on the host. - * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ -void check_host_supports_tls(int *supports_tls, int *tls_min) { - /* Values for x86 and x86_64.*/ - int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; - int i; - - for (i = 0; i < ARRAY_SIZE(val); i++) { - user_desc_t info; - info.entry_number = val[i]; - - if (syscall(__NR_get_thread_area, &info) == 0) { - *tls_min = val[i]; - *supports_tls = 1; - return; - } else { - if (errno == EINVAL) - continue; - else if (errno == ENOSYS) - *supports_tls = 0; - return; - } - } - - *supports_tls = 0; -} diff --git a/arch/um/os-Linux/sys-x86/Makefile b/arch/um/os-Linux/sys-x86/Makefile new file mode 100644 index 0000000..22cc507 --- /dev/null +++ b/arch/um/os-Linux/sys-x86/Makefile @@ -0,0 +1,13 @@ +# +# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +# Licensed under the GPL +# + +obj-y = registers.o task_size.o + +obj-$(CONFIG_X86_32) += tls.o +obj-$(CONFIG_64BIT) += prctl.o + +USER_OBJS := $(obj-y) + +include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-x86/prctl.c b/arch/um/os-Linux/sys-x86/prctl.c new file mode 100644 index 0000000..9d34edd --- /dev/null +++ b/arch/um/os-Linux/sys-x86/prctl.c @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com}) + * Licensed under the GPL + */ + +#include +#include + +int os_arch_prctl(int pid, int code, unsigned long *addr) +{ + return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); +} diff --git a/arch/um/os-Linux/sys-x86/registers.c b/arch/um/os-Linux/sys-x86/registers.c new file mode 100644 index 0000000..3a9b624 --- /dev/null +++ b/arch/um/os-Linux/sys-x86/registers.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2004 PathScale, Inc + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include "longjmp.h" +#include "sysdep/ptrace_user.h" + +int save_fp_registers(int pid, unsigned long *fp_regs) +{ + if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + +int restore_fp_registers(int pid, unsigned long *fp_regs) +{ + if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + +#ifdef __i386__ +int have_fpx_regs = 1; +int save_fpx_registers(int pid, unsigned long *fp_regs) +{ + if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + +int restore_fpx_registers(int pid, unsigned long *fp_regs) +{ + if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + +int get_fp_registers(int pid, unsigned long *regs) +{ + if (have_fpx_regs) + return save_fpx_registers(pid, regs); + else + return save_fp_registers(pid, regs); +} + +int put_fp_registers(int pid, unsigned long *regs) +{ + if (have_fpx_regs) + return restore_fpx_registers(pid, regs); + else + return restore_fp_registers(pid, regs); +} + +void arch_init_registers(int pid) +{ + struct user_fpxregs_struct fpx_regs; + int err; + + err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); + if (!err) + return; + + if (errno != EIO) + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", + errno); + + have_fpx_regs = 0; +} +#else + +int get_fp_registers(int pid, unsigned long *regs) +{ + return save_fp_registers(pid, regs); +} + +int put_fp_registers(int pid, unsigned long *regs) +{ + return restore_fp_registers(pid, regs); +} + +#endif + +unsigned long get_thread_reg(int reg, jmp_buf *buf) +{ + switch (reg) { +#ifdef __i386__ + case EIP: + return buf[0]->__eip; + case UESP: + return buf[0]->__esp; + case EBP: + return buf[0]->__ebp; +#else + case RIP: + return buf[0]->__rip; + case RSP: + return buf[0]->__rsp; + case RBP: + return buf[0]->__rbp; +#endif + default: + printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", + reg); + return 0; + } +} diff --git a/arch/um/os-Linux/sys-x86/task_size.c b/arch/um/os-Linux/sys-x86/task_size.c new file mode 100644 index 0000000..efb16c5 --- /dev/null +++ b/arch/um/os-Linux/sys-x86/task_size.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include "longjmp.h" + +#ifdef __i386__ + +static jmp_buf buf; + +static void segfault(int sig) +{ + longjmp(buf, 1); +} + +static int page_ok(unsigned long page) +{ + unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT); + unsigned long n = ~0UL; + void *mapped = NULL; + int ok = 0; + + /* + * First see if the page is readable. If it is, it may still + * be a VDSO, so we go on to see if it's writable. If not + * then try mapping memory there. If that fails, then we're + * still in the kernel area. As a sanity check, we'll fail if + * the mmap succeeds, but gives us an address different from + * what we wanted. + */ + if (setjmp(buf) == 0) + n = *address; + else { + mapped = mmap(address, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (mapped == MAP_FAILED) + return 0; + if (mapped != address) + goto out; + } + + /* + * Now, is it writeable? If so, then we're in user address + * space. If not, then try mprotecting it and try the write + * again. + */ + if (setjmp(buf) == 0) { + *address = n; + ok = 1; + goto out; + } else if (mprotect(address, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE) != 0) + goto out; + + if (setjmp(buf) == 0) { + *address = n; + ok = 1; + } + + out: + if (mapped != NULL) + munmap(mapped, UM_KERN_PAGE_SIZE); + return ok; +} + +unsigned long os_get_top_address(void) +{ + struct sigaction sa, old; + unsigned long bottom = 0; + /* + * A 32-bit UML on a 64-bit host gets confused about the VDSO at + * 0xffffe000. It is mapped, is readable, can be reprotected writeable + * and written. However, exec discovers later that it can't be + * unmapped. So, just set the highest address to be checked to just + * below it. This might waste some address space on 4G/4G 32-bit + * hosts, but shouldn't hurt otherwise. + */ + unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; + unsigned long test, original; + + printf("Locating the bottom of the address space ... "); + fflush(stdout); + + /* + * We're going to be longjmping out of the signal handler, so + * SA_DEFER needs to be set. + */ + sa.sa_handler = segfault; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NODEFER; + if (sigaction(SIGSEGV, &sa, &old)) { + perror("os_get_top_address"); + exit(1); + } + + /* Manually scan the address space, bottom-up, until we find + * the first valid page (or run out of them). + */ + for (bottom = 0; bottom < top; bottom++) { + if (page_ok(bottom)) + break; + } + + /* If we've got this far, we ran out of pages. */ + if (bottom == top) { + fprintf(stderr, "Unable to determine bottom of address " + "space.\n"); + exit(1); + } + + printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); + printf("Locating the top of the address space ... "); + fflush(stdout); + + original = bottom; + + /* This could happen with a 4G/4G split */ + if (page_ok(top)) + goto out; + + do { + test = bottom + (top - bottom) / 2; + if (page_ok(test)) + bottom = test; + else + top = test; + } while (top - bottom > 1); + +out: + /* Restore the old SIGSEGV handling */ + if (sigaction(SIGSEGV, &old, NULL)) { + perror("os_get_top_address"); + exit(1); + } + top <<= UM_KERN_PAGE_SHIFT; + printf("0x%x\n", top); + + return top; +} + +#else + +unsigned long os_get_top_address(void) +{ + /* The old value of CONFIG_TOP_ADDR */ + return 0x7fc0000000; +} + +#endif diff --git a/arch/um/os-Linux/sys-x86/tls.c b/arch/um/os-Linux/sys-x86/tls.c new file mode 100644 index 0000000..281e83e --- /dev/null +++ b/arch/um/os-Linux/sys-x86/tls.c @@ -0,0 +1,35 @@ +#include +#include + +#include +#include + +#include "sysdep/tls.h" + +/* Checks whether host supports TLS, and sets *tls_min according to the value + * valid on the host. + * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ +void check_host_supports_tls(int *supports_tls, int *tls_min) { + /* Values for x86 and x86_64.*/ + int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; + int i; + + for (i = 0; i < ARRAY_SIZE(val); i++) { + user_desc_t info; + info.entry_number = val[i]; + + if (syscall(__NR_get_thread_area, &info) == 0) { + *tls_min = val[i]; + *supports_tls = 1; + return; + } else { + if (errno == EINVAL) + continue; + else if (errno == ENOSYS) + *supports_tls = 0; + return; + } + } + + *supports_tls = 0; +} diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile deleted file mode 100644 index 58f6e0a..0000000 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o prctl.o task_size.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-x86_64/prctl.c b/arch/um/os-Linux/sys-x86_64/prctl.c deleted file mode 100644 index 9d34edd..0000000 --- a/arch/um/os-Linux/sys-x86_64/prctl.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com}) - * Licensed under the GPL - */ - -#include -#include - -int os_arch_prctl(int pid, int code, unsigned long *addr) -{ - return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); -} diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c deleted file mode 100644 index 0594d55..0000000 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2006 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#define __FRAME_OFFSETS -#include -#include "longjmp.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case RIP: - return buf[0]->__rip; - case RSP: - return buf[0]->__rsp; - case RBP: - return buf[0]->__rbp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int get_fp_registers(int pid, unsigned long *regs) -{ - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - return restore_fp_registers(pid, regs); -} diff --git a/arch/um/os-Linux/sys-x86_64/task_size.c b/arch/um/os-Linux/sys-x86_64/task_size.c deleted file mode 100644 index 26a0dd1..0000000 --- a/arch/um/os-Linux/sys-x86_64/task_size.c +++ /dev/null @@ -1,5 +0,0 @@ -unsigned long os_get_top_address(unsigned long shift) -{ - /* The old value of CONFIG_TOP_ADDR */ - return 0x7fc0000000; -} -- cgit v1.1 From adcfb9852d8f2ddba908da0d023c280e23a40452 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:03:59 +0100 Subject: um: kill includes of sysdep/sigcontext.h from stuff built with kernel headers Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/kernel/signal.c | 1 - arch/um/kernel/trap.c | 1 - arch/um/sys-x86/shared/sysdep/faultinfo_32.h | 6 ++++++ arch/um/sys-x86/shared/sysdep/faultinfo_64.h | 6 ++++++ arch/um/sys-x86/shared/sysdep/ptrace_32.h | 1 + arch/um/sys-x86/shared/sysdep/ptrace_64.h | 5 +---- arch/um/sys-x86/shared/sysdep/sigcontext_32.h | 8 -------- arch/um/sys-x86/shared/sysdep/sigcontext_64.h | 8 -------- 8 files changed, 14 insertions(+), 22 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index b5c094c..e8b889d 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -11,7 +11,6 @@ #include #include "frame_kern.h" #include "kern_util.h" -#include EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 8c7b882..f2a2036 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -14,7 +14,6 @@ #include "kern_util.h" #include "os.h" #include "skas.h" -#include "sysdep/sigcontext.h" /* * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_32.h b/arch/um/sys-x86/shared/sysdep/faultinfo_32.h index db437cc..a26086b 100644 --- a/arch/um/sys-x86/shared/sysdep/faultinfo_32.h +++ b/arch/um/sys-x86/shared/sysdep/faultinfo_32.h @@ -24,6 +24,12 @@ struct faultinfo { #define FAULT_WRITE(fi) ((fi).error_code & 2) #define FAULT_ADDRESS(fi) ((fi).cr2) +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ +#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) + #define PTRACE_FULL_FAULTINFO 0 #endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_64.h b/arch/um/sys-x86/shared/sysdep/faultinfo_64.h index cb917b0..f811cbe 100644 --- a/arch/um/sys-x86/shared/sysdep/faultinfo_64.h +++ b/arch/um/sys-x86/shared/sysdep/faultinfo_64.h @@ -24,6 +24,12 @@ struct faultinfo { #define FAULT_WRITE(fi) ((fi).error_code & 2) #define FAULT_ADDRESS(fi) ((fi).cr2) +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* No broken SKAS API, which doesn't pass trap_no, here. */ +#define SEGV_MAYBE_FIXABLE(fi) 0 + #define PTRACE_FULL_FAULTINFO 1 #endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_32.h b/arch/um/sys-x86/shared/sysdep/ptrace_32.h index 6096c8f..ce77fa1 100644 --- a/arch/um/sys-x86/shared/sysdep/ptrace_32.h +++ b/arch/um/sys-x86/shared/sysdep/ptrace_32.h @@ -43,6 +43,7 @@ extern int sysemu_supported; #define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) #ifndef PTRACE_SYSEMU_SINGLESTEP diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_64.h b/arch/um/sys-x86/shared/sysdep/ptrace_64.h index 9ed4597..866fe7e 100644 --- a/arch/um/sys-x86/shared/sysdep/ptrace_64.h +++ b/arch/um/sys-x86/shared/sysdep/ptrace_64.h @@ -69,10 +69,9 @@ #define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) -#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) - #define REGS_FAULT_ADDR(r) ((r)->fault_addr) #define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) @@ -152,8 +151,6 @@ struct syscall_args { #define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) -#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) - #define UPT_FAULTINFO(r) (&(r)->faultinfo) static inline void arch_init_registers(int pid) diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h index 3827864..aebc2dd61 100644 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h @@ -8,8 +8,6 @@ #include -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - #define SC_OFFSET(sc, field) \ *((unsigned long *) &(((char *) (sc))[HOST_##field])) @@ -24,10 +22,4 @@ (fi).trap_no = SC_TRAPNO(sc); \ } -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) - #endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h index 9fb5277..60d89a2 100644 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h @@ -15,8 +15,6 @@ #define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) #define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - #define GET_FAULTINFO_FROM_SC(fi, sc) \ { \ (fi).cr2 = SC_CR2(sc); \ @@ -24,10 +22,4 @@ (fi).trap_no = SC_TRAPNO(sc); \ } -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* No broken SKAS API, which doesn't pass trap_no, here. */ -#define SEGV_MAYBE_FIXABLE(fi) 0 - #endif -- cgit v1.1 From 9b25fcbdc64369f4cce41e73fc0f57f3fd367d20 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:09 +0100 Subject: um: switch stub_segv_handler to SA_SIGINFO variant, get rid of magic crap in there Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/skas/process.c | 4 ++-- arch/um/sys-x86/Makefile | 2 +- arch/um/sys-x86/shared/sysdep/stub.h | 9 +++++++++ arch/um/sys-x86/shared/sysdep/stub_32.h | 7 ------- arch/um/sys-x86/shared/sysdep/stub_64.h | 7 ------- arch/um/sys-x86/stub_segv.c | 19 +++++++++++++++++++ arch/um/sys-x86/stub_segv_32.c | 17 ----------------- arch/um/sys-x86/stub_segv_64.c | 22 ---------------------- 8 files changed, 31 insertions(+), 56 deletions(-) create mode 100644 arch/um/sys-x86/stub_segv.c delete mode 100644 arch/um/sys-x86/stub_segv_32.c delete mode 100644 arch/um/sys-x86/stub_segv_64.c (limited to 'arch/um') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 2a72bfc..f481d74 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -255,8 +255,8 @@ static int userspace_tramp(void *stack) set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_NODEFER; - sa.sa_handler = (void *) v; + sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO; + sa.sa_sigaction = (void *) v; sa.sa_restorer = NULL; if (sigaction(SIGSEGV, &sa, NULL) < 0) { printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV " diff --git a/arch/um/sys-x86/Makefile b/arch/um/sys-x86/Makefile index 671de0b..81ab348 100644 --- a/arch/um/sys-x86/Makefile +++ b/arch/um/sys-x86/Makefile @@ -10,7 +10,7 @@ endif obj-y = bug.o bugs_$(BITS).o delay_$(BITS).o fault.o ksyms.o ldt.o \ ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal_$(BITS).o \ - stub_$(BITS).o stub_segv_$(BITS).o syscalls_$(BITS).o \ + stub_$(BITS).o stub_segv.o syscalls_$(BITS).o \ sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o mem_$(BITS).o ifeq ($(CONFIG_X86_32),y) diff --git a/arch/um/sys-x86/shared/sysdep/stub.h b/arch/um/sys-x86/shared/sysdep/stub.h index 13f523a..bd161e3 100644 --- a/arch/um/sys-x86/shared/sysdep/stub.h +++ b/arch/um/sys-x86/shared/sysdep/stub.h @@ -1,5 +1,14 @@ +#include +#include +#include +#include "as-layout.h" +#include "stub-data.h" + #ifdef __i386__ #include "stub_32.h" #else #include "stub_64.h" #endif + +extern void stub_segv_handler(int, siginfo_t *, void *); +extern void stub_clone_handler(void); diff --git a/arch/um/sys-x86/shared/sysdep/stub_32.h b/arch/um/sys-x86/shared/sysdep/stub_32.h index cca14d4..51fd256 100644 --- a/arch/um/sys-x86/shared/sysdep/stub_32.h +++ b/arch/um/sys-x86/shared/sysdep/stub_32.h @@ -6,14 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H -#include #include -#include -#include "as-layout.h" -#include "stub-data.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); #define STUB_SYSCALL_RET EAX #define STUB_MMAP_NR __NR_mmap2 diff --git a/arch/um/sys-x86/shared/sysdep/stub_64.h b/arch/um/sys-x86/shared/sysdep/stub_64.h index 922a570..994df93 100644 --- a/arch/um/sys-x86/shared/sysdep/stub_64.h +++ b/arch/um/sys-x86/shared/sysdep/stub_64.h @@ -6,14 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H -#include -#include #include -#include "as-layout.h" -#include "stub-data.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); #define STUB_SYSCALL_RET PT_INDEX(RAX) #define STUB_MMAP_NR __NR_mmap diff --git a/arch/um/sys-x86/stub_segv.c b/arch/um/sys-x86/stub_segv.c new file mode 100644 index 0000000..f62771cf --- /dev/null +++ b/arch/um/sys-x86/stub_segv.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include "sysdep/stub.h" +#include "sysdep/faultinfo.h" +#include "sysdep/sigcontext.h" + +void __attribute__ ((__section__ (".__syscall_stub"))) +stub_segv_handler(int sig, siginfo_t *info, void *p) +{ + struct ucontext *uc = p; + + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), + &uc->uc_mcontext); + trap_myself(); +} + diff --git a/arch/um/sys-x86/stub_segv_32.c b/arch/um/sys-x86/stub_segv_32.c deleted file mode 100644 index 28ccf73..0000000 --- a/arch/um/sys-x86/stub_segv_32.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/stub.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct sigcontext *sc = (struct sigcontext *) (&sig + 1); - - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); - - trap_myself(); -} diff --git a/arch/um/sys-x86/stub_segv_64.c b/arch/um/sys-x86/stub_segv_64.c deleted file mode 100644 index ced051a..0000000 --- a/arch/um/sys-x86/stub_segv_64.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "as-layout.h" -#include "sysdep/stub.h" -#include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct ucontext *uc; - - __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), - &uc->uc_mcontext); - trap_myself(); -} - -- cgit v1.1 From d5c7e8b4ec4795ed0b8943cad8f87801fde371d7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:19 +0100 Subject: um: don't bother blocking SIGARLM and SIGUSR1 We used to generate those, but we hadn't done that for a long time. No need to bother blocking them for signal handlers. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/process.c | 13 ++++++------- arch/um/os-Linux/signal.c | 2 +- arch/um/os-Linux/skas/process.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 0ced30c..c1a8fa7 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -236,20 +236,19 @@ out: void init_new_thread_signals(void) { set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + SIGIO, SIGWINCH, SIGVTALRM, -1); set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + SIGIO, SIGWINCH, SIGVTALRM, -1); signal(SIGHUP, SIG_IGN); set_handler(SIGIO, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, - SIGVTALRM, -1); + SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, SIGVTALRM, -1); signal(SIGWINCH, SIG_IGN); signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 2dde9f6..75c3e9c 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -112,7 +112,7 @@ void alarm_handler(int sig, struct sigcontext *sc) void timer_init(void) { set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1); + SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, -1); } void set_sigstack(void *sig_stack, int size) diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index f481d74..20b34dc 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -660,7 +660,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) int n; set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1); + SA_ONSTACK | SA_RESTART, SIGIO, SIGVTALRM, -1); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save -- cgit v1.1 From e87df986ed053d25dbd57b8b137edec5022874f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:29 +0100 Subject: um: simplify set_handler() For one thing, we always block the same signals (IRQ ones - IO, WINCH, VTALRM), so there's no need to pass sa_mask elements in arguments. For another, the flags depend only on whether it's an IRQ signal or not (we add SA_RESTART for them). Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 2 +- arch/um/os-Linux/process.c | 19 ++++++------------- arch/um/os-Linux/signal.c | 22 +++++++++++----------- arch/um/os-Linux/skas/process.c | 3 +-- 4 files changed, 19 insertions(+), 27 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 2e2663a..598ca82 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -225,7 +225,7 @@ extern char *get_umid(void); extern void timer_init(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); -extern void set_handler(int sig, void (*handler)(int), int flags, ...); +extern void set_handler(int sig, void (*handler)(int)); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index c1a8fa7..075ae92 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -235,20 +235,13 @@ out: void init_new_thread_signals(void) { - set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGIO, SIGWINCH, SIGVTALRM, -1); + set_handler(SIGSEGV, (__sighandler_t) sig_handler); + set_handler(SIGTRAP, (__sighandler_t) sig_handler); + set_handler(SIGFPE, (__sighandler_t) sig_handler); + set_handler(SIGILL, (__sighandler_t) sig_handler); + set_handler(SIGBUS, (__sighandler_t) sig_handler); signal(SIGHUP, SIG_IGN); - - set_handler(SIGIO, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, SIGVTALRM, -1); + set_handler(SIGIO, (__sighandler_t) sig_handler); signal(SIGWINCH, SIG_IGN); signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 75c3e9c..f248fb2 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -111,8 +111,7 @@ void alarm_handler(int sig, struct sigcontext *sc) void timer_init(void) { - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, -1); + set_handler(SIGVTALRM, (__sighandler_t) alarm_handler); } void set_sigstack(void *sig_stack, int size) @@ -174,27 +173,28 @@ static void hard_handler(int sig, siginfo_t *info, void *p) handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); } -void set_handler(int sig, void (*handler)(int), int flags, ...) +void set_handler(int sig, void (*handler)(int)) { struct sigaction action; - va_list ap; + int flags = SA_SIGINFO | SA_ONSTACK; sigset_t sig_mask; - int mask; handlers[sig] = (void (*)(int, struct sigcontext *)) handler; action.sa_sigaction = hard_handler; + /* block irq ones */ sigemptyset(&action.sa_mask); - - va_start(ap, flags); - while ((mask = va_arg(ap, int)) != -1) - sigaddset(&action.sa_mask, mask); - va_end(ap); + sigaddset(&action.sa_mask, SIGVTALRM); + sigaddset(&action.sa_mask, SIGIO); + sigaddset(&action.sa_mask, SIGWINCH); if (sig == SIGSEGV) flags |= SA_NODEFER; - action.sa_flags = flags | SA_SIGINFO; + if (sigismember(&action.sa_mask, sig)) + flags |= SA_RESTART; /* if it's an irq signal */ + + action.sa_flags = flags; action.sa_restorer = NULL; if (sigaction(sig, &action, NULL) < 0) panic("sigaction failed - errno = %d\n", errno); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 20b34dc..31743f1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -659,8 +659,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; - set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGIO, SIGVTALRM, -1); + set_handler(SIGWINCH, (__sighandler_t) sig_handler); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save -- cgit v1.1 From 00361683ce562402a189362f43370a459b166645 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:39 +0100 Subject: um: fill the handlers array at build time Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 2 +- arch/um/os-Linux/process.c | 12 ++++++------ arch/um/os-Linux/signal.c | 17 +++++++++++++---- arch/um/os-Linux/skas/process.c | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 598ca82..caa6661 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -225,7 +225,7 @@ extern char *get_umid(void); extern void timer_init(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); -extern void set_handler(int sig, void (*handler)(int)); +extern void set_handler(int sig); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 075ae92..e08fe30 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -235,13 +235,13 @@ out: void init_new_thread_signals(void) { - set_handler(SIGSEGV, (__sighandler_t) sig_handler); - set_handler(SIGTRAP, (__sighandler_t) sig_handler); - set_handler(SIGFPE, (__sighandler_t) sig_handler); - set_handler(SIGILL, (__sighandler_t) sig_handler); - set_handler(SIGBUS, (__sighandler_t) sig_handler); + set_handler(SIGSEGV); + set_handler(SIGTRAP); + set_handler(SIGFPE); + set_handler(SIGILL); + set_handler(SIGBUS); signal(SIGHUP, SIG_IGN); - set_handler(SIGIO, (__sighandler_t) sig_handler); + set_handler(SIGIO); signal(SIGWINCH, SIG_IGN); signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index f248fb2..c4a4e20 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -111,7 +111,7 @@ void alarm_handler(int sig, struct sigcontext *sc) void timer_init(void) { - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler); + set_handler(SIGVTALRM); } void set_sigstack(void *sig_stack, int size) @@ -124,7 +124,17 @@ void set_sigstack(void *sig_stack, int size) panic("enabling signal stack failed, errno = %d\n", errno); } -static void (*handlers[_NSIG])(int sig, struct sigcontext *sc); +static void (*handlers[_NSIG])(int sig, struct sigcontext *sc) = { + [SIGSEGV] = sig_handler, + [SIGBUS] = sig_handler, + [SIGILL] = sig_handler, + [SIGFPE] = sig_handler, + [SIGTRAP] = sig_handler, + + [SIGIO] = sig_handler, + [SIGWINCH] = sig_handler, + [SIGVTALRM] = alarm_handler +}; static void handle_signal(int sig, struct sigcontext *sc) { @@ -173,13 +183,12 @@ static void hard_handler(int sig, siginfo_t *info, void *p) handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); } -void set_handler(int sig, void (*handler)(int)) +void set_handler(int sig) { struct sigaction action; int flags = SA_SIGINFO | SA_ONSTACK; sigset_t sig_mask; - handlers[sig] = (void (*)(int, struct sigcontext *)) handler; action.sa_sigaction = hard_handler; /* block irq ones */ diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 31743f1..f4e02ad 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -659,7 +659,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; - set_handler(SIGWINCH, (__sighandler_t) sig_handler); + set_handler(SIGWINCH); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save -- cgit v1.1 From dd768c56da44f6c06486da3b33b41e9c13e985c5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:49 +0100 Subject: um: take system.h out of shared/sysdep Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/system-um.h | 45 +++++++++++ arch/um/include/asm/system.h | 47 ------------ arch/um/sys-x86/asm/system.h | 133 +++++++++++++++++++++++++++++++++ arch/um/sys-x86/shared/sysdep/system.h | 132 -------------------------------- 4 files changed, 178 insertions(+), 179 deletions(-) create mode 100644 arch/um/include/asm/system-um.h delete mode 100644 arch/um/include/asm/system.h create mode 100644 arch/um/sys-x86/asm/system.h delete mode 100644 arch/um/sys-x86/shared/sysdep/system.h (limited to 'arch/um') diff --git a/arch/um/include/asm/system-um.h b/arch/um/include/asm/system-um.h new file mode 100644 index 0000000..0eec245 --- /dev/null +++ b/arch/um/include/asm/system-um.h @@ -0,0 +1,45 @@ +#ifndef __UM_SYSTEM_GENERIC_H +#define __UM_SYSTEM_GENERIC_H + +extern int get_signals(void); +extern int set_signals(int enable); +extern void block_signals(void); +extern void unblock_signals(void); + +static inline unsigned long arch_local_save_flags(void) +{ + return get_signals(); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + set_signals(flags); +} + +static inline void arch_local_irq_enable(void) +{ + unblock_signals(); +} + +static inline void arch_local_irq_disable(void) +{ + block_signals(); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_local_save_flags() == 0; +} + +extern void *_switch_to(void *prev, void *next, void *last); +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) + +#endif diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h deleted file mode 100644 index 68a90ec..0000000 --- a/arch/um/include/asm/system.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __UM_SYSTEM_GENERIC_H -#define __UM_SYSTEM_GENERIC_H - -#include "sysdep/system.h" - -extern int get_signals(void); -extern int set_signals(int enable); -extern void block_signals(void); -extern void unblock_signals(void); - -static inline unsigned long arch_local_save_flags(void) -{ - return get_signals(); -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - set_signals(flags); -} - -static inline void arch_local_irq_enable(void) -{ - unblock_signals(); -} - -static inline void arch_local_irq_disable(void) -{ - block_signals(); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_local_save_flags() == 0; -} - -extern void *_switch_to(void *prev, void *next, void *last); -#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) - -#endif diff --git a/arch/um/sys-x86/asm/system.h b/arch/um/sys-x86/asm/system.h new file mode 100644 index 0000000..a89113b --- /dev/null +++ b/arch/um/sys-x86/asm/system.h @@ -0,0 +1,133 @@ +#ifndef _ASM_X86_SYSTEM_H_ +#define _ASM_X86_SYSTEM_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + +extern unsigned long arch_align_stack(unsigned long sp); + +void default_idle(void); + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + */ +#ifdef CONFIG_X86_32 +/* + * Some non-Intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ +#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) +#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) +#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#else +#define mb() asm volatile("mfence":::"memory") +#define rmb() asm volatile("lfence":::"memory") +#define wmb() asm volatile("sfence" ::: "memory") +#endif + +/** + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like this where there are no data dependencies. + **/ + +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#ifdef CONFIG_X86_PPRO_FENCE +# define smp_rmb() rmb() +#else +# define smp_rmb() barrier() +#endif +#ifdef CONFIG_X86_OOSTORE +# define smp_wmb() wmb() +#else +# define smp_wmb() barrier() +#endif +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + +/* + * Stop RDTSC speculation. This is needed when you need to use RDTSC + * (or get_cycles or vread that possibly accesses the TSC) in a defined + * code region. + * + * (Could use an alternative three way for this if there was one.) + */ +static inline void rdtsc_barrier(void) +{ + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); +} + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/system.h b/arch/um/sys-x86/shared/sysdep/system.h deleted file mode 100644 index d1b93c4..0000000 --- a/arch/um/sys-x86/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include -#include -#include -#include -#include - -#include -#include - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif -- cgit v1.1 From 05c46db4d7d51af969e09f9f1adbff66ee2e84b4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:04:59 +0100 Subject: um: take userland definition of barrier() to user.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/process.h | 3 --- arch/um/include/shared/user.h | 3 +++ arch/um/os-Linux/signal.c | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h index bb873a5..2821530 100644 --- a/arch/um/include/shared/process.h +++ b/arch/um/include/shared/process.h @@ -8,9 +8,6 @@ #include -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") - extern void sig_handler(int sig, struct sigcontext *sc); extern void alarm_handler(int sig, struct sigcontext *sc); diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 58c0581..4fa82c0 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -40,4 +40,7 @@ extern int in_aton(char *str); extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); +/* Copied from linux/compiler-gcc.h since we can't include it directly */ +#define barrier() __asm__ __volatile__("": : :"memory") + #endif diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index c4a4e20..08d3061 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -16,9 +16,6 @@ #include "sysdep/barrier.h" #include "sysdep/sigcontext.h" -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") - void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, [SIGFPE] = relay_signal, -- cgit v1.1 From 248b74c79ebb9fb55e146797a808836d90418c4b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:09 +0100 Subject: um: start switching the references to host mcontext_t to its userland type Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/process.h | 5 ---- arch/um/os-Linux/internal.h | 1 + arch/um/os-Linux/signal.c | 35 ++++++++++++--------------- arch/um/os-Linux/time.c | 2 +- arch/um/sys-x86/shared/sysdep/sigcontext_32.h | 7 ++++++ arch/um/sys-x86/shared/sysdep/sigcontext_64.h | 7 ++++++ arch/um/sys-x86/stub_segv.c | 2 +- 7 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 arch/um/os-Linux/internal.h (limited to 'arch/um') diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h index 2821530..2ba310e 100644 --- a/arch/um/include/shared/process.h +++ b/arch/um/include/shared/process.h @@ -6,9 +6,4 @@ #ifndef __PROCESS_H__ #define __PROCESS_H__ -#include - -extern void sig_handler(int sig, struct sigcontext *sc); -extern void alarm_handler(int sig, struct sigcontext *sc); - #endif diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h new file mode 100644 index 0000000..2c3c3ec --- /dev/null +++ b/arch/um/os-Linux/internal.h @@ -0,0 +1 @@ +void alarm_handler(int, mcontext_t *); diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 08d3061..07d9905 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -26,7 +26,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGIO] = sigio_handler, [SIGVTALRM] = timer_handler }; -static void sig_handler_common(int sig, struct sigcontext *sc) +static void sig_handler_common(int sig, mcontext_t *mc) { struct uml_pt_regs r; int save_errno = errno; @@ -34,8 +34,8 @@ static void sig_handler_common(int sig, struct sigcontext *sc) r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ - copy_sc(&r, sc); - GET_FAULTINFO_FROM_SC(r.faultinfo, sc); + copy_sc(&r, (struct sigcontext *)mc); + GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } /* enable signals if sig isn't IRQ signal */ @@ -62,7 +62,7 @@ static void sig_handler_common(int sig, struct sigcontext *sc) static int signals_enabled; static unsigned int signals_pending; -void sig_handler(int sig, struct sigcontext *sc) +void sig_handler(int sig, mcontext_t *mc) { int enabled; @@ -74,23 +74,23 @@ void sig_handler(int sig, struct sigcontext *sc) block_signals(); - sig_handler_common(sig, sc); + sig_handler_common(sig, mc); set_signals(enabled); } -static void real_alarm_handler(struct sigcontext *sc) +static void real_alarm_handler(mcontext_t *mc) { struct uml_pt_regs regs; - if (sc != NULL) - copy_sc(®s, sc); + if (mc != NULL) + copy_sc(®s, (struct sigcontext *)mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); } -void alarm_handler(int sig, struct sigcontext *sc) +void alarm_handler(int sig, mcontext_t *mc) { int enabled; @@ -102,7 +102,7 @@ void alarm_handler(int sig, struct sigcontext *sc) block_signals(); - real_alarm_handler(sc); + real_alarm_handler(mc); set_signals(enabled); } @@ -121,7 +121,7 @@ void set_sigstack(void *sig_stack, int size) panic("enabling signal stack failed, errno = %d\n", errno); } -static void (*handlers[_NSIG])(int sig, struct sigcontext *sc) = { +static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { [SIGSEGV] = sig_handler, [SIGBUS] = sig_handler, [SIGILL] = sig_handler, @@ -133,8 +133,11 @@ static void (*handlers[_NSIG])(int sig, struct sigcontext *sc) = { [SIGVTALRM] = alarm_handler }; -static void handle_signal(int sig, struct sigcontext *sc) + +static void hard_handler(int sig, siginfo_t *info, void *p) { + struct ucontext *uc = p; + mcontext_t *mc = &uc->uc_mcontext; unsigned long pending = 1UL << sig; do { @@ -160,7 +163,7 @@ static void handle_signal(int sig, struct sigcontext *sc) while ((sig = ffs(pending)) != 0){ sig--; pending &= ~(1 << sig); - (*handlers[sig])(sig, sc); + (*handlers[sig])(sig, mc); } /* @@ -174,12 +177,6 @@ static void handle_signal(int sig, struct sigcontext *sc) } while (pending); } -static void hard_handler(int sig, siginfo_t *info, void *p) -{ - struct ucontext *uc = p; - handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); -} - void set_handler(int sig) { struct sigaction action; diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 995ca30..910499d 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -10,7 +10,7 @@ #include #include "kern_util.h" #include "os.h" -#include "process.h" +#include "internal.h" int set_interval(void) { diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h index aebc2dd61..548c3cd 100644 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h @@ -22,4 +22,11 @@ (fi).trap_no = SC_TRAPNO(sc); \ } +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->cr2; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + #endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h index 60d89a2..5c4a6a3 100644 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h +++ b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h @@ -22,4 +22,11 @@ (fi).trap_no = SC_TRAPNO(sc); \ } +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->gregs[REG_CR2]; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + #endif diff --git a/arch/um/sys-x86/stub_segv.c b/arch/um/sys-x86/stub_segv.c index f62771cf..bd2eaf6 100644 --- a/arch/um/sys-x86/stub_segv.c +++ b/arch/um/sys-x86/stub_segv.c @@ -12,7 +12,7 @@ stub_segv_handler(int sig, siginfo_t *info, void *p) { struct ucontext *uc = p; - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), + GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA), &uc->uc_mcontext); trap_myself(); } -- cgit v1.1 From ab1c0cc7c96c17ea903ca6d3e42e7d2696b32b6c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:19 +0100 Subject: um: finish conversion to mcontext_t now we don't mix host and guest signal frame layouts anymore; moreover, we don't need host's struct sigcontext at all. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/signal.c | 6 ++--- arch/um/os-Linux/sys-x86/Makefile | 2 +- arch/um/os-Linux/sys-x86/mcontext.c | 31 ++++++++++++++++++++++++++ arch/um/sys-x86/shared/sysdep/mcontext.h | 31 ++++++++++++++++++++++++++ arch/um/sys-x86/shared/sysdep/sigcontext.h | 5 ----- arch/um/sys-x86/shared/sysdep/sigcontext_32.h | 32 --------------------------- arch/um/sys-x86/shared/sysdep/sigcontext_64.h | 32 --------------------------- arch/um/sys-x86/stub_segv.c | 2 +- arch/um/sys-x86/user-offsets.c | 7 ------ 9 files changed, 67 insertions(+), 81 deletions(-) create mode 100644 arch/um/os-Linux/sys-x86/mcontext.c create mode 100644 arch/um/sys-x86/shared/sysdep/mcontext.h delete mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext.h delete mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/sigcontext_64.h (limited to 'arch/um') diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 07d9905..9f2c222 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -14,7 +14,7 @@ #include "os.h" #include "process.h" #include "sysdep/barrier.h" -#include "sysdep/sigcontext.h" +#include "sysdep/mcontext.h" void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, @@ -34,7 +34,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ - copy_sc(&r, (struct sigcontext *)mc); + get_regs_from_mc(&r, mc); GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } @@ -84,7 +84,7 @@ static void real_alarm_handler(mcontext_t *mc) struct uml_pt_regs regs; if (mc != NULL) - copy_sc(®s, (struct sigcontext *)mc); + get_regs_from_mc(®s, mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); diff --git a/arch/um/os-Linux/sys-x86/Makefile b/arch/um/os-Linux/sys-x86/Makefile index 22cc507..253bfb8 100644 --- a/arch/um/os-Linux/sys-x86/Makefile +++ b/arch/um/os-Linux/sys-x86/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o task_size.o +obj-y = registers.o task_size.o mcontext.o obj-$(CONFIG_X86_32) += tls.o obj-$(CONFIG_64BIT) += prctl.o diff --git a/arch/um/os-Linux/sys-x86/mcontext.c b/arch/um/os-Linux/sys-x86/mcontext.c new file mode 100644 index 0000000..1d33d72 --- /dev/null +++ b/arch/um/os-Linux/sys-x86/mcontext.c @@ -0,0 +1,31 @@ +#include +#define __FRAME_OFFSETS +#include +#include + +void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) +{ +#ifdef __i386__ +#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X] = mc->gregs[REG_##X] +#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff; +#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3; + COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); + COPY(EDI); COPY(ESI); COPY(EBP); + COPY2(UESP, ESP); /* sic */ + COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); + COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); +#else +#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X] + COPY(R8); COPY(R9); COPY(R10); COPY(R11); + COPY(R12); COPY(R13); COPY(R14); COPY(R15); + COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); + COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); + COPY(RIP); + COPY2(EFLAGS, EFL); + COPY2(CS, CSGSFS); + regs->gp[CS / sizeof(unsigned long)] &= 0xffff; + regs->gp[CS / sizeof(unsigned long)] |= 3; +#endif +} diff --git a/arch/um/sys-x86/shared/sysdep/mcontext.h b/arch/um/sys-x86/shared/sysdep/mcontext.h new file mode 100644 index 0000000..b724c54 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/mcontext.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYS_SIGCONTEXT_X86_H +#define __SYS_SIGCONTEXT_X86_H + +extern void get_regs_from_mc(struct uml_pt_regs *, mcontext_t *); + +#ifdef __i386__ + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->cr2; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#else + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->gregs[REG_CR2]; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#endif + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext.h b/arch/um/sys-x86/shared/sysdep/sigcontext.h deleted file mode 100644 index f7f49f4..0000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "sigcontext_32.h" -#else -#include "sigcontext_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h deleted file mode 100644 index 548c3cd..0000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_I386_H -#define __SYS_SIGCONTEXT_I386_H - -#include - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->cr2; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h deleted file mode 100644 index 5c4a6a3..0000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SIGCONTEXT_H -#define __SYSDEP_X86_64_SIGCONTEXT_H - -#include - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->gregs[REG_CR2]; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#endif diff --git a/arch/um/sys-x86/stub_segv.c b/arch/um/sys-x86/stub_segv.c index bd2eaf6..b7450bd 100644 --- a/arch/um/sys-x86/stub_segv.c +++ b/arch/um/sys-x86/stub_segv.c @@ -5,7 +5,7 @@ #include "sysdep/stub.h" #include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" +#include "sysdep/mcontext.h" void __attribute__ ((__section__ (".__syscall_stub"))) stub_segv_handler(int sig, siginfo_t *info, void *p) diff --git a/arch/um/sys-x86/user-offsets.c b/arch/um/sys-x86/user-offsets.c index 718f0c0..3c19c48 100644 --- a/arch/um/sys-x86/user-offsets.c +++ b/arch/um/sys-x86/user-offsets.c @@ -14,15 +14,8 @@ #define DEFINE_LONGS(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - void foo(void) { - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_CR2, sigcontext, cr2); - #ifdef __i386__ DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); -- cgit v1.1 From 0de021f797e7bd785796071aab8e14827c87d6bf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:29 +0100 Subject: um: shared/process.h is empty now; kill it Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/process.h | 9 --------- arch/um/os-Linux/irq.c | 1 - arch/um/os-Linux/process.c | 1 - arch/um/os-Linux/sigio.c | 1 - arch/um/os-Linux/signal.c | 1 - arch/um/os-Linux/skas/process.c | 1 - 6 files changed, 14 deletions(-) delete mode 100644 arch/um/include/shared/process.h (limited to 'arch/um') diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h deleted file mode 100644 index 2ba310e..0000000 --- a/arch/um/include/shared/process.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __PROCESS_H__ -#define __PROCESS_H__ - -#endif diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 59c592c..9a49908 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -10,7 +10,6 @@ #include #include "irq_user.h" #include "os.h" -#include "process.h" #include "um_malloc.h" /* diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index e08fe30..307f173 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -15,7 +15,6 @@ #include "init.h" #include "longjmp.h" #include "os.h" -#include "process.h" #include "skas_ptrace.h" #define ARBITRARY_ADDR -1 diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 34bb59b..3c16121 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -14,7 +14,6 @@ #include "kern_util.h" #include "init.h" #include "os.h" -#include "process.h" #include "sigio.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 9f2c222..4d31688 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -12,7 +12,6 @@ #include "as-layout.h" #include "kern_util.h" #include "os.h" -#include "process.h" #include "sysdep/barrier.h" #include "sysdep/mcontext.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index f4e02ad..30f1bb4 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -17,7 +17,6 @@ #include "kern_util.h" #include "mem.h" #include "os.h" -#include "process.h" #include "proc_mm.h" #include "ptrace_user.h" #include "registers.h" -- cgit v1.1 From 62982ad6b013a35c2e49caab2b90855d3ad4531d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:39 +0100 Subject: um: sysdep/barrier.h is not used for anything Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/os-Linux/signal.c | 1 - arch/um/sys-x86/shared/sysdep/barrier.h | 5 ----- arch/um/sys-x86/shared/sysdep/barrier_32.h | 9 --------- arch/um/sys-x86/shared/sysdep/barrier_64.h | 7 ------- 4 files changed, 22 deletions(-) delete mode 100644 arch/um/sys-x86/shared/sysdep/barrier.h delete mode 100644 arch/um/sys-x86/shared/sysdep/barrier_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/barrier_64.h (limited to 'arch/um') diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 4d31688..2d22f1f 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -12,7 +12,6 @@ #include "as-layout.h" #include "kern_util.h" #include "os.h" -#include "sysdep/barrier.h" #include "sysdep/mcontext.h" void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { diff --git a/arch/um/sys-x86/shared/sysdep/barrier.h b/arch/um/sys-x86/shared/sysdep/barrier.h deleted file mode 100644 index 89ee23b..0000000 --- a/arch/um/sys-x86/shared/sysdep/barrier.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "barrier_32.h" -#else -#include "barrier_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/barrier_32.h b/arch/um/sys-x86/shared/sysdep/barrier_32.h deleted file mode 100644 index b58d52c..0000000 --- a/arch/um/sys-x86/shared/sysdep/barrier_32.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYSDEP_I386_BARRIER_H -#define __SYSDEP_I386_BARRIER_H - -/* Copied from include/asm-i386 for use by userspace. i386 has the option - * of using mfence, but I'm just using this, which works everywhere, for now. - */ -#define mb() asm volatile("lock; addl $0,0(%esp)") - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/barrier_64.h b/arch/um/sys-x86/shared/sysdep/barrier_64.h deleted file mode 100644 index 7b610be..0000000 --- a/arch/um/sys-x86/shared/sysdep/barrier_64.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SYSDEP_X86_64_BARRIER_H -#define __SYSDEP_X86_64_BARRIER_H - -/* Copied from include/asm-x86_64 for use by userspace. */ -#define mb() asm volatile("mfence":::"memory") - -#endif -- cgit v1.1 From c75361bddb21761cabddde95dcae2059b021ea5d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:49 +0100 Subject: um: merge skas_ptrace.h 32/64bit variants Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-x86/shared/sysdep/skas_ptrace.h | 25 +++++++++++++++++++++---- arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h | 22 ---------------------- arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h | 22 ---------------------- 3 files changed, 21 insertions(+), 48 deletions(-) delete mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h (limited to 'arch/um') diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace.h index e63b575..453febe 100644 --- a/arch/um/sys-x86/shared/sysdep/skas_ptrace.h +++ b/arch/um/sys-x86/shared/sysdep/skas_ptrace.h @@ -1,5 +1,22 @@ -#ifdef __i386__ -#include "skas_ptrace_32.h" -#else -#include "skas_ptrace_64.h" +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_SKAS_PTRACE_H +#define __SYSDEP_X86_SKAS_PTRACE_H + +struct ptrace_faultinfo { + int is_write; + unsigned long addr; +}; + +struct ptrace_ldt { + int func; + void *ptr; + unsigned long bytecount; +}; + +#define PTRACE_LDT 54 + #endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h deleted file mode 100644 index e27b8a7..0000000 --- a/arch/um/sys-x86/shared/sysdep/skas_ptrace_32.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_SKAS_PTRACE_H -#define __SYSDEP_I386_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h deleted file mode 100644 index 95db4be7..0000000 --- a/arch/um/sys-x86/shared/sysdep/skas_ptrace_64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H -#define __SYSDEP_X86_64_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif -- cgit v1.1 From 709585063f3d3da68f29b3d706fddb74de5e33f4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:05:59 +0100 Subject: um: merge kernel_offsets_*.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/sys-x86/shared/sysdep/kernel-offsets.h | 26 ++++++++++++++++++----- arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h | 21 ------------------ arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h | 23 -------------------- 3 files changed, 21 insertions(+), 49 deletions(-) delete mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h (limited to 'arch/um') diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets.h index 346bc08..5868526 100644 --- a/arch/um/sys-x86/shared/sysdep/kernel-offsets.h +++ b/arch/um/sys-x86/shared/sysdep/kernel-offsets.h @@ -1,5 +1,21 @@ -#ifdef __i386__ -#include "kernel-offsets_32.h" -#else -#include "kernel-offsets_64.h" -#endif +#include +#include +#include +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define STR(x) #x +#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) + +#define BLANK() asm volatile("\n->" : : ) + +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)); + +void foo(void) +{ +#include +} diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h deleted file mode 100644 index 5868526..0000000 --- a/arch/um/sys-x86/shared/sysdep/kernel-offsets_32.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define STR(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include -} diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h deleted file mode 100644 index a307237..0000000 --- a/arch/um/sys-x86/shared/sysdep/kernel-offsets_64.h +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_STR1(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include -} -- cgit v1.1 From 9aecaa6a8a43965821fbc4373240ae338f7eaf14 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:09 +0100 Subject: um: arch_hweight.h is needed only on uml-x86 Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/arch_hweight.h | 6 ------ arch/um/sys-x86/asm/arch_hweight.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 arch/um/include/asm/arch_hweight.h create mode 100644 arch/um/sys-x86/asm/arch_hweight.h (limited to 'arch/um') diff --git a/arch/um/include/asm/arch_hweight.h b/arch/um/include/asm/arch_hweight.h deleted file mode 100644 index c656cf4..0000000 --- a/arch/um/include/asm/arch_hweight.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_HWEIGHT_H -#define _ASM_UM_HWEIGHT_H - -#include - -#endif diff --git a/arch/um/sys-x86/asm/arch_hweight.h b/arch/um/sys-x86/asm/arch_hweight.h new file mode 100644 index 0000000..c656cf4 --- /dev/null +++ b/arch/um/sys-x86/asm/arch_hweight.h @@ -0,0 +1,6 @@ +#ifndef _ASM_UM_HWEIGHT_H +#define _ASM_UM_HWEIGHT_H + +#include + +#endif -- cgit v1.1 From a6e77d6c74fa82675b087a79c8a145cae7c58f36 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:19 +0100 Subject: um: trim detritus from Makefile-i386 Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile-i386 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 7e5f1ba..57acfd6 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -1,13 +1,10 @@ core-y += arch/um/sys-x86/ arch/x86/crypto/ -TOP_ADDR := $(CONFIG_TOP_ADDR) - START := 0x8048000 LDFLAGS += -m elf_i386 -ELF_ARCH := $(SUBARCH) -ELF_FORMAT := elf32-$(SUBARCH) -OBJCOPYFLAGS := -O binary -R .note -R .comment -S +ELF_ARCH := i386 +ELF_FORMAT := elf32-i386 HEADER_ARCH := x86 CHECKFLAGS += -D__i386__ @@ -16,9 +13,8 @@ ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") KBUILD_CFLAGS += $(call cc-option,-m32) KBUILD_AFLAGS += $(call cc-option,-m32) LINK-y += $(call cc-option,-m32) -UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) -export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS +export LDFLAGS endif endif -- cgit v1.1 From 7bbe7204e93734fe79d8aac3e08a7cb4624b5004 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:29 +0100 Subject: um: merge Makefile-{i386,x86_64} Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Makefile | 12 +++++++++- arch/um/Makefile-i386 | 38 ------------------------------ arch/um/Makefile-x86 | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ arch/um/Makefile-x86_64 | 26 --------------------- 4 files changed, 72 insertions(+), 65 deletions(-) delete mode 100644 arch/um/Makefile-i386 create mode 100644 arch/um/Makefile-x86 delete mode 100644 arch/um/Makefile-x86_64 (limited to 'arch/um') diff --git a/arch/um/Makefile b/arch/um/Makefile index bd0587e..7492ee5 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -20,8 +20,18 @@ core-y += $(ARCH_DIR)/kernel/ \ MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas +HEADER_ARCH := $(SUBARCH) + +# Additional ARCH settings for x86 +ifeq ($(SUBARCH),i386) + HEADER_ARCH := x86 +endif +ifeq ($(SUBARCH),x86_64) + HEADER_ARCH := x86 +endif + include $(srctree)/$(ARCH_DIR)/Makefile-skas -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) +include $(srctree)/$(ARCH_DIR)/Makefile-$(HEADER_ARCH) SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 deleted file mode 100644 index 57acfd6..0000000 --- a/arch/um/Makefile-i386 +++ /dev/null @@ -1,38 +0,0 @@ -core-y += arch/um/sys-x86/ arch/x86/crypto/ - -START := 0x8048000 - -LDFLAGS += -m elf_i386 -ELF_ARCH := i386 -ELF_FORMAT := elf32-i386 -HEADER_ARCH := x86 -CHECKFLAGS += -D__i386__ - -ifeq ("$(origin SUBARCH)", "command line") -ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") -KBUILD_CFLAGS += $(call cc-option,-m32) -KBUILD_AFLAGS += $(call cc-option,-m32) -LINK-y += $(call cc-option,-m32) - -export LDFLAGS -endif -endif - -# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. -include $(srctree)/arch/x86/Makefile_32.cpu - -# prevent gcc from keeping the stack 16 byte aligned. Taken from i386. -cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) - -# Prevent sprintf in nfsd from being converted to strcpy and resulting in -# an unresolved reference. -cflags-y += -ffreestanding - -# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use -# a lot more stack due to the lack of sharing of stacklots. Also, gcc -# 4.3.0 needs -funit-at-a-time for extern inline functions. -KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ - echo $(call cc-option,-fno-unit-at-a-time); \ - else echo $(call cc-option,-funit-at-a-time); fi ;) - -KBUILD_CFLAGS += $(cflags-y) diff --git a/arch/um/Makefile-x86 b/arch/um/Makefile-x86 new file mode 100644 index 0000000..68fbd1b --- /dev/null +++ b/arch/um/Makefile-x86 @@ -0,0 +1,61 @@ +core-y += arch/um/sys-x86/ arch/x86/crypto/ + +ifeq ($(CONFIG_X86_32),y) +START := 0x8048000 + +LDFLAGS += -m elf_i386 +ELF_ARCH := i386 +ELF_FORMAT := elf32-i386 +CHECKFLAGS += -D__i386__ + +ifeq ("$(origin SUBARCH)", "command line") +ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") +KBUILD_CFLAGS += $(call cc-option,-m32) +KBUILD_AFLAGS += $(call cc-option,-m32) +LINK-y += $(call cc-option,-m32) + +export LDFLAGS +endif +endif + +# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. +include $(srctree)/arch/x86/Makefile_32.cpu + +# prevent gcc from keeping the stack 16 byte aligned. Taken from i386. +cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) + +# Prevent sprintf in nfsd from being converted to strcpy and resulting in +# an unresolved reference. +cflags-y += -ffreestanding + +# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use +# a lot more stack due to the lack of sharing of stacklots. Also, gcc +# 4.3.0 needs -funit-at-a-time for extern inline functions. +KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ + echo $(call cc-option,-fno-unit-at-a-time); \ + else echo $(call cc-option,-funit-at-a-time); fi ;) + +KBUILD_CFLAGS += $(cflags-y) + +else + +START := 0x60000000 + +KBUILD_CFLAGS += -fno-builtin -m64 + +CHECKFLAGS += -m64 -D__x86_64__ +KBUILD_AFLAGS += -m64 +LDFLAGS += -m elf_x86_64 +KBUILD_CPPFLAGS += -m64 + +ELF_ARCH := i386:x86-64 +ELF_FORMAT := elf64-x86-64 + +# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. + +LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 +LINK-y += -m64 + +# Do unit-at-a-time unconditionally on x86_64, following the host +KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) +endif diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 deleted file mode 100644 index 92d8f8f..0000000 --- a/arch/um/Makefile-x86_64 +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2003 - 2004 Pathscale, Inc -# Released under the GPL - -core-y += arch/um/sys-x86/ arch/x86/crypto/ -START := 0x60000000 - -_extra_flags_ = -fno-builtin -m64 - -KBUILD_CFLAGS += $(_extra_flags_) - -CHECKFLAGS += -m64 -D__x86_64__ -KBUILD_AFLAGS += -m64 -LDFLAGS += -m elf_x86_64 -KBUILD_CPPFLAGS += -m64 - -ELF_ARCH := i386:x86-64 -ELF_FORMAT := elf64-x86-64 -HEADER_ARCH := x86 - -# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. - -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 -LINK-y += -m64 - -# Do unit-at-a-time unconditionally on x86_64, following the host -KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) -- cgit v1.1 From 5c48b108ecbf6505d929e64d50dace13ac2bdf34 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:39 +0100 Subject: um: take arch/um/sys-x86 to arch/x86/um Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Kconfig.x86 | 70 ---- arch/um/Makefile | 22 +- arch/um/Makefile-x86 | 61 --- arch/um/os-Linux/Makefile | 2 +- arch/um/os-Linux/sys-x86/Makefile | 13 - arch/um/os-Linux/sys-x86/mcontext.c | 31 -- arch/um/os-Linux/sys-x86/prctl.c | 12 - arch/um/os-Linux/sys-x86/registers.c | 111 ------ arch/um/os-Linux/sys-x86/task_size.c | 150 -------- arch/um/os-Linux/sys-x86/tls.c | 35 -- arch/um/scripts/Makefile.rules | 5 - arch/um/sys-x86/Makefile | 45 --- arch/um/sys-x86/asm/arch_hweight.h | 6 - arch/um/sys-x86/asm/archparam.h | 20 - arch/um/sys-x86/asm/checksum.h | 10 - arch/um/sys-x86/asm/checksum_32.h | 201 ---------- arch/um/sys-x86/asm/checksum_64.h | 144 ------- arch/um/sys-x86/asm/elf.h | 221 ----------- arch/um/sys-x86/asm/module.h | 23 -- arch/um/sys-x86/asm/processor.h | 15 - arch/um/sys-x86/asm/processor_32.h | 73 ---- arch/um/sys-x86/asm/processor_64.h | 51 --- arch/um/sys-x86/asm/ptrace.h | 5 - arch/um/sys-x86/asm/ptrace_32.h | 51 --- arch/um/sys-x86/asm/ptrace_64.h | 72 ---- arch/um/sys-x86/asm/system.h | 133 ------- arch/um/sys-x86/asm/vm-flags.h | 25 -- arch/um/sys-x86/bug.c | 21 -- arch/um/sys-x86/bugs_32.c | 74 ---- arch/um/sys-x86/bugs_64.c | 15 - arch/um/sys-x86/checksum_32.S | 458 ---------------------- arch/um/sys-x86/delay_32.c | 60 --- arch/um/sys-x86/delay_64.c | 60 --- arch/um/sys-x86/elfcore.c | 83 ---- arch/um/sys-x86/fault.c | 28 -- arch/um/sys-x86/ksyms.c | 13 - arch/um/sys-x86/ldt.c | 502 ------------------------- arch/um/sys-x86/mem_32.c | 62 --- arch/um/sys-x86/mem_64.c | 26 -- arch/um/sys-x86/ptrace_32.c | 273 -------------- arch/um/sys-x86/ptrace_64.c | 271 ------------- arch/um/sys-x86/ptrace_user.c | 21 -- arch/um/sys-x86/setjmp_32.S | 58 --- arch/um/sys-x86/setjmp_64.S | 54 --- arch/um/sys-x86/shared/sysdep/archsetjmp.h | 5 - arch/um/sys-x86/shared/sysdep/archsetjmp_32.h | 22 -- arch/um/sys-x86/shared/sysdep/archsetjmp_64.h | 24 -- arch/um/sys-x86/shared/sysdep/faultinfo.h | 5 - arch/um/sys-x86/shared/sysdep/faultinfo_32.h | 35 -- arch/um/sys-x86/shared/sysdep/faultinfo_64.h | 35 -- arch/um/sys-x86/shared/sysdep/host_ldt.h | 5 - arch/um/sys-x86/shared/sysdep/host_ldt_32.h | 34 -- arch/um/sys-x86/shared/sysdep/host_ldt_64.h | 38 -- arch/um/sys-x86/shared/sysdep/kernel-offsets.h | 21 -- arch/um/sys-x86/shared/sysdep/mcontext.h | 31 -- arch/um/sys-x86/shared/sysdep/ptrace.h | 5 - arch/um/sys-x86/shared/sysdep/ptrace_32.h | 117 ------ arch/um/sys-x86/shared/sysdep/ptrace_64.h | 160 -------- arch/um/sys-x86/shared/sysdep/ptrace_user.h | 5 - arch/um/sys-x86/shared/sysdep/ptrace_user_32.h | 26 -- arch/um/sys-x86/shared/sysdep/ptrace_user_64.h | 38 -- arch/um/sys-x86/shared/sysdep/skas_ptrace.h | 22 -- arch/um/sys-x86/shared/sysdep/stub.h | 14 - arch/um/sys-x86/shared/sysdep/stub_32.h | 93 ----- arch/um/sys-x86/shared/sysdep/stub_64.h | 99 ----- arch/um/sys-x86/shared/sysdep/syscalls.h | 5 - arch/um/sys-x86/shared/sysdep/syscalls_32.h | 20 - arch/um/sys-x86/shared/sysdep/syscalls_64.h | 32 -- arch/um/sys-x86/shared/sysdep/tls.h | 5 - arch/um/sys-x86/shared/sysdep/tls_32.h | 32 -- arch/um/sys-x86/shared/sysdep/tls_64.h | 29 -- arch/um/sys-x86/signal_32.c | 498 ------------------------ arch/um/sys-x86/signal_64.c | 255 ------------- arch/um/sys-x86/stub_32.S | 51 --- arch/um/sys-x86/stub_64.S | 66 ---- arch/um/sys-x86/stub_segv.c | 19 - arch/um/sys-x86/sys_call_table_32.S | 28 -- arch/um/sys-x86/sys_call_table_64.c | 64 ---- arch/um/sys-x86/syscalls_32.c | 66 ---- arch/um/sys-x86/syscalls_64.c | 102 ----- arch/um/sys-x86/sysrq_32.c | 101 ----- arch/um/sys-x86/sysrq_64.c | 41 -- arch/um/sys-x86/tls_32.c | 396 ------------------- arch/um/sys-x86/tls_64.c | 17 - arch/um/sys-x86/user-offsets.c | 79 ---- arch/um/sys-x86/vdso/Makefile | 90 ----- arch/um/sys-x86/vdso/checkundef.sh | 10 - arch/um/sys-x86/vdso/um_vdso.c | 71 ---- arch/um/sys-x86/vdso/vdso-layout.lds.S | 64 ---- arch/um/sys-x86/vdso/vdso-note.S | 12 - arch/um/sys-x86/vdso/vdso.S | 10 - arch/um/sys-x86/vdso/vdso.lds.S | 32 -- arch/um/sys-x86/vdso/vma.c | 74 ---- 93 files changed, 14 insertions(+), 6775 deletions(-) delete mode 100644 arch/um/Kconfig.x86 delete mode 100644 arch/um/Makefile-x86 delete mode 100644 arch/um/os-Linux/sys-x86/Makefile delete mode 100644 arch/um/os-Linux/sys-x86/mcontext.c delete mode 100644 arch/um/os-Linux/sys-x86/prctl.c delete mode 100644 arch/um/os-Linux/sys-x86/registers.c delete mode 100644 arch/um/os-Linux/sys-x86/task_size.c delete mode 100644 arch/um/os-Linux/sys-x86/tls.c delete mode 100644 arch/um/sys-x86/Makefile delete mode 100644 arch/um/sys-x86/asm/arch_hweight.h delete mode 100644 arch/um/sys-x86/asm/archparam.h delete mode 100644 arch/um/sys-x86/asm/checksum.h delete mode 100644 arch/um/sys-x86/asm/checksum_32.h delete mode 100644 arch/um/sys-x86/asm/checksum_64.h delete mode 100644 arch/um/sys-x86/asm/elf.h delete mode 100644 arch/um/sys-x86/asm/module.h delete mode 100644 arch/um/sys-x86/asm/processor.h delete mode 100644 arch/um/sys-x86/asm/processor_32.h delete mode 100644 arch/um/sys-x86/asm/processor_64.h delete mode 100644 arch/um/sys-x86/asm/ptrace.h delete mode 100644 arch/um/sys-x86/asm/ptrace_32.h delete mode 100644 arch/um/sys-x86/asm/ptrace_64.h delete mode 100644 arch/um/sys-x86/asm/system.h delete mode 100644 arch/um/sys-x86/asm/vm-flags.h delete mode 100644 arch/um/sys-x86/bug.c delete mode 100644 arch/um/sys-x86/bugs_32.c delete mode 100644 arch/um/sys-x86/bugs_64.c delete mode 100644 arch/um/sys-x86/checksum_32.S delete mode 100644 arch/um/sys-x86/delay_32.c delete mode 100644 arch/um/sys-x86/delay_64.c delete mode 100644 arch/um/sys-x86/elfcore.c delete mode 100644 arch/um/sys-x86/fault.c delete mode 100644 arch/um/sys-x86/ksyms.c delete mode 100644 arch/um/sys-x86/ldt.c delete mode 100644 arch/um/sys-x86/mem_32.c delete mode 100644 arch/um/sys-x86/mem_64.c delete mode 100644 arch/um/sys-x86/ptrace_32.c delete mode 100644 arch/um/sys-x86/ptrace_64.c delete mode 100644 arch/um/sys-x86/ptrace_user.c delete mode 100644 arch/um/sys-x86/setjmp_32.S delete mode 100644 arch/um/sys-x86/setjmp_64.S delete mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp.h delete mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/archsetjmp_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo.h delete mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/faultinfo_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt.h delete mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/host_ldt_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/kernel-offsets.h delete mode 100644 arch/um/sys-x86/shared/sysdep/mcontext.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/ptrace_user_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/skas_ptrace.h delete mode 100644 arch/um/sys-x86/shared/sysdep/stub.h delete mode 100644 arch/um/sys-x86/shared/sysdep/stub_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/stub_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/syscalls.h delete mode 100644 arch/um/sys-x86/shared/sysdep/syscalls_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/syscalls_64.h delete mode 100644 arch/um/sys-x86/shared/sysdep/tls.h delete mode 100644 arch/um/sys-x86/shared/sysdep/tls_32.h delete mode 100644 arch/um/sys-x86/shared/sysdep/tls_64.h delete mode 100644 arch/um/sys-x86/signal_32.c delete mode 100644 arch/um/sys-x86/signal_64.c delete mode 100644 arch/um/sys-x86/stub_32.S delete mode 100644 arch/um/sys-x86/stub_64.S delete mode 100644 arch/um/sys-x86/stub_segv.c delete mode 100644 arch/um/sys-x86/sys_call_table_32.S delete mode 100644 arch/um/sys-x86/sys_call_table_64.c delete mode 100644 arch/um/sys-x86/syscalls_32.c delete mode 100644 arch/um/sys-x86/syscalls_64.c delete mode 100644 arch/um/sys-x86/sysrq_32.c delete mode 100644 arch/um/sys-x86/sysrq_64.c delete mode 100644 arch/um/sys-x86/tls_32.c delete mode 100644 arch/um/sys-x86/tls_64.c delete mode 100644 arch/um/sys-x86/user-offsets.c delete mode 100644 arch/um/sys-x86/vdso/Makefile delete mode 100644 arch/um/sys-x86/vdso/checkundef.sh delete mode 100644 arch/um/sys-x86/vdso/um_vdso.c delete mode 100644 arch/um/sys-x86/vdso/vdso-layout.lds.S delete mode 100644 arch/um/sys-x86/vdso/vdso-note.S delete mode 100644 arch/um/sys-x86/vdso/vdso.S delete mode 100644 arch/um/sys-x86/vdso/vdso.lds.S delete mode 100644 arch/um/sys-x86/vdso/vma.c (limited to 'arch/um') diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 deleted file mode 100644 index 21bebe6..0000000 --- a/arch/um/Kconfig.x86 +++ /dev/null @@ -1,70 +0,0 @@ -mainmenu "User Mode Linux/$SUBARCH $KERNELVERSION Kernel Configuration" - -source "arch/um/Kconfig.common" - -menu "UML-specific options" - -menu "Host processor type and features" - -config CMPXCHG_LOCAL - bool - default n - -config CMPXCHG_DOUBLE - bool - default n - -source "arch/x86/Kconfig.cpu" - -endmenu - -config UML_X86 - def_bool y - select GENERIC_FIND_FIRST_BIT - -config 64BIT - bool - default SUBARCH = "x86_64" - -config X86_32 - def_bool !64BIT - select HAVE_AOUT - -config X86_64 - def_bool 64BIT - -config RWSEM_XCHGADD_ALGORITHM - def_bool X86_XADD && 64BIT - -config RWSEM_GENERIC_SPINLOCK - def_bool !RWSEM_XCHGADD_ALGORITHM - -config 3_LEVEL_PGTABLES - bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT - default 64BIT - depends on EXPERIMENTAL - help - Three-level pagetables will let UML have more than 4G of physical - memory. All the memory that can't be mapped directly will be treated - as high memory. - - However, this it experimental on 32-bit architectures, so if unsure say - N (on x86-64 it's automatically enabled, instead, as it's safe there). - -config ARCH_HAS_SC_SIGNALS - def_bool !64BIT - -config ARCH_REUSE_HOST_VSYSCALL_AREA - def_bool !64BIT - -config SMP_BROKEN - def_bool 64BIT - -config GENERIC_HWEIGHT - def_bool y - -source "arch/um/Kconfig.um" - -endmenu - -source "arch/um/Kconfig.rest" diff --git a/arch/um/Makefile b/arch/um/Makefile index 7492ee5..7730af6 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -30,13 +30,17 @@ ifeq ($(SUBARCH),x86_64) HEADER_ARCH := x86 endif +HOST_DIR := arch/$(HEADER_ARCH) + include $(srctree)/$(ARCH_DIR)/Makefile-skas -include $(srctree)/$(ARCH_DIR)/Makefile-$(HEADER_ARCH) +include $(srctree)/$(HOST_DIR)/Makefile.um + +core-y += $(HOST_DIR)/um/ SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) -ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(HEADER_ARCH)/shared -KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(HEADER_ARCH) +ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so # named - it's a common symbol in libpcap, so we get a binary which crashes. @@ -60,7 +64,7 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) -KBUILD_CPPFLAGS += -I$(srctree)/arch/$(HEADER_ARCH)/include +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -90,7 +94,7 @@ define archhelp echo ' find in the kernel root.' endef -KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH) +KBUILD_KCONFIG := $(HOST_DIR)/um/Kconfig archprepare: include/generated/user_constants.h @@ -131,8 +135,8 @@ archclean: # Generated files -$(ARCH_DIR)/sys-$(HEADER_ARCH)/user-offsets.s: FORCE - $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(HEADER_ARCH) $@ +$(HOST_DIR)/um/user-offsets.s: FORCE + $(Q)$(MAKE) $(build)=$(HOST_DIR)/um $@ define filechk_gen-asm-offsets (set -e; \ @@ -147,7 +151,7 @@ define filechk_gen-asm-offsets echo ""; ) endef -include/generated/user_constants.h: $(ARCH_DIR)/sys-$(HEADER_ARCH)/user-offsets.s +include/generated/user_constants.h: $(HOST_DIR)/um/user-offsets.s $(call filechk,gen-asm-offsets) -export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH +export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS DEV_NULL_PATH diff --git a/arch/um/Makefile-x86 b/arch/um/Makefile-x86 deleted file mode 100644 index 68fbd1b..0000000 --- a/arch/um/Makefile-x86 +++ /dev/null @@ -1,61 +0,0 @@ -core-y += arch/um/sys-x86/ arch/x86/crypto/ - -ifeq ($(CONFIG_X86_32),y) -START := 0x8048000 - -LDFLAGS += -m elf_i386 -ELF_ARCH := i386 -ELF_FORMAT := elf32-i386 -CHECKFLAGS += -D__i386__ - -ifeq ("$(origin SUBARCH)", "command line") -ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") -KBUILD_CFLAGS += $(call cc-option,-m32) -KBUILD_AFLAGS += $(call cc-option,-m32) -LINK-y += $(call cc-option,-m32) - -export LDFLAGS -endif -endif - -# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. -include $(srctree)/arch/x86/Makefile_32.cpu - -# prevent gcc from keeping the stack 16 byte aligned. Taken from i386. -cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) - -# Prevent sprintf in nfsd from being converted to strcpy and resulting in -# an unresolved reference. -cflags-y += -ffreestanding - -# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use -# a lot more stack due to the lack of sharing of stacklots. Also, gcc -# 4.3.0 needs -funit-at-a-time for extern inline functions. -KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ - echo $(call cc-option,-fno-unit-at-a-time); \ - else echo $(call cc-option,-funit-at-a-time); fi ;) - -KBUILD_CFLAGS += $(cflags-y) - -else - -START := 0x60000000 - -KBUILD_CFLAGS += -fno-builtin -m64 - -CHECKFLAGS += -m64 -D__x86_64__ -KBUILD_AFLAGS += -m64 -LDFLAGS += -m elf_x86_64 -KBUILD_CPPFLAGS += -m64 - -ELF_ARCH := i386:x86-64 -ELF_FORMAT := elf64-x86-64 - -# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. - -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 -LINK-y += -m64 - -# Do unit-at-a-time unconditionally on x86_64, following the host -KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) -endif diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 7879e76..015d000 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -5,7 +5,7 @@ obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ - umid.o tls.o user_syms.o util.o drivers/ sys-$(HEADER_ARCH)/ skas/ + umid.o tls.o user_syms.o util.o drivers/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o diff --git a/arch/um/os-Linux/sys-x86/Makefile b/arch/um/os-Linux/sys-x86/Makefile deleted file mode 100644 index 253bfb8..0000000 --- a/arch/um/os-Linux/sys-x86/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o task_size.o mcontext.o - -obj-$(CONFIG_X86_32) += tls.o -obj-$(CONFIG_64BIT) += prctl.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-x86/mcontext.c b/arch/um/os-Linux/sys-x86/mcontext.c deleted file mode 100644 index 1d33d72..0000000 --- a/arch/um/os-Linux/sys-x86/mcontext.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#define __FRAME_OFFSETS -#include -#include - -void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) -{ -#ifdef __i386__ -#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y] -#define COPY(X) regs->gp[X] = mc->gregs[REG_##X] -#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff; -#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3; - COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); - COPY(EDI); COPY(ESI); COPY(EBP); - COPY2(UESP, ESP); /* sic */ - COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); - COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); -#else -#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y] -#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X] - COPY(R8); COPY(R9); COPY(R10); COPY(R11); - COPY(R12); COPY(R13); COPY(R14); COPY(R15); - COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); - COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); - COPY(RIP); - COPY2(EFLAGS, EFL); - COPY2(CS, CSGSFS); - regs->gp[CS / sizeof(unsigned long)] &= 0xffff; - regs->gp[CS / sizeof(unsigned long)] |= 3; -#endif -} diff --git a/arch/um/os-Linux/sys-x86/prctl.c b/arch/um/os-Linux/sys-x86/prctl.c deleted file mode 100644 index 9d34edd..0000000 --- a/arch/um/os-Linux/sys-x86/prctl.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com}) - * Licensed under the GPL - */ - -#include -#include - -int os_arch_prctl(int pid, int code, unsigned long *addr) -{ - return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); -} diff --git a/arch/um/os-Linux/sys-x86/registers.c b/arch/um/os-Linux/sys-x86/registers.c deleted file mode 100644 index 3a9b624..0000000 --- a/arch/um/os-Linux/sys-x86/registers.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2004 PathScale, Inc - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include "longjmp.h" -#include "sysdep/ptrace_user.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -#ifdef __i386__ -int have_fpx_regs = 1; -int save_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int get_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return save_fpx_registers(pid, regs); - else - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return restore_fpx_registers(pid, regs); - else - return restore_fp_registers(pid, regs); -} - -void arch_init_registers(int pid) -{ - struct user_fpxregs_struct fpx_regs; - int err; - - err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); - if (!err) - return; - - if (errno != EIO) - panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", - errno); - - have_fpx_regs = 0; -} -#else - -int get_fp_registers(int pid, unsigned long *regs) -{ - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - return restore_fp_registers(pid, regs); -} - -#endif - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { -#ifdef __i386__ - case EIP: - return buf[0]->__eip; - case UESP: - return buf[0]->__esp; - case EBP: - return buf[0]->__ebp; -#else - case RIP: - return buf[0]->__rip; - case RSP: - return buf[0]->__rsp; - case RBP: - return buf[0]->__rbp; -#endif - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} diff --git a/arch/um/os-Linux/sys-x86/task_size.c b/arch/um/os-Linux/sys-x86/task_size.c deleted file mode 100644 index efb16c5..0000000 --- a/arch/um/os-Linux/sys-x86/task_size.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include "longjmp.h" - -#ifdef __i386__ - -static jmp_buf buf; - -static void segfault(int sig) -{ - longjmp(buf, 1); -} - -static int page_ok(unsigned long page) -{ - unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT); - unsigned long n = ~0UL; - void *mapped = NULL; - int ok = 0; - - /* - * First see if the page is readable. If it is, it may still - * be a VDSO, so we go on to see if it's writable. If not - * then try mapping memory there. If that fails, then we're - * still in the kernel area. As a sanity check, we'll fail if - * the mmap succeeds, but gives us an address different from - * what we wanted. - */ - if (setjmp(buf) == 0) - n = *address; - else { - mapped = mmap(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (mapped == MAP_FAILED) - return 0; - if (mapped != address) - goto out; - } - - /* - * Now, is it writeable? If so, then we're in user address - * space. If not, then try mprotecting it and try the write - * again. - */ - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - goto out; - } else if (mprotect(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE) != 0) - goto out; - - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - } - - out: - if (mapped != NULL) - munmap(mapped, UM_KERN_PAGE_SIZE); - return ok; -} - -unsigned long os_get_top_address(void) -{ - struct sigaction sa, old; - unsigned long bottom = 0; - /* - * A 32-bit UML on a 64-bit host gets confused about the VDSO at - * 0xffffe000. It is mapped, is readable, can be reprotected writeable - * and written. However, exec discovers later that it can't be - * unmapped. So, just set the highest address to be checked to just - * below it. This might waste some address space on 4G/4G 32-bit - * hosts, but shouldn't hurt otherwise. - */ - unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test, original; - - printf("Locating the bottom of the address space ... "); - fflush(stdout); - - /* - * We're going to be longjmping out of the signal handler, so - * SA_DEFER needs to be set. - */ - sa.sa_handler = segfault; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; - if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_top_address"); - exit(1); - } - - /* Manually scan the address space, bottom-up, until we find - * the first valid page (or run out of them). - */ - for (bottom = 0; bottom < top; bottom++) { - if (page_ok(bottom)) - break; - } - - /* If we've got this far, we ran out of pages. */ - if (bottom == top) { - fprintf(stderr, "Unable to determine bottom of address " - "space.\n"); - exit(1); - } - - printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); - printf("Locating the top of the address space ... "); - fflush(stdout); - - original = bottom; - - /* This could happen with a 4G/4G split */ - if (page_ok(top)) - goto out; - - do { - test = bottom + (top - bottom) / 2; - if (page_ok(test)) - bottom = test; - else - top = test; - } while (top - bottom > 1); - -out: - /* Restore the old SIGSEGV handling */ - if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_top_address"); - exit(1); - } - top <<= UM_KERN_PAGE_SHIFT; - printf("0x%x\n", top); - - return top; -} - -#else - -unsigned long os_get_top_address(void) -{ - /* The old value of CONFIG_TOP_ADDR */ - return 0x7fc0000000; -} - -#endif diff --git a/arch/um/os-Linux/sys-x86/tls.c b/arch/um/os-Linux/sys-x86/tls.c deleted file mode 100644 index 281e83e..0000000 --- a/arch/um/os-Linux/sys-x86/tls.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -#include -#include - -#include "sysdep/tls.h" - -/* Checks whether host supports TLS, and sets *tls_min according to the value - * valid on the host. - * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ -void check_host_supports_tls(int *supports_tls, int *tls_min) { - /* Values for x86 and x86_64.*/ - int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; - int i; - - for (i = 0; i < ARRAY_SIZE(val); i++) { - user_desc_t info; - info.entry_number = val[i]; - - if (syscall(__NR_get_thread_area, &info) == 0) { - *tls_min = val[i]; - *supports_tls = 1; - return; - } else { - if (errno == EINVAL) - continue; - else if (errno == ENOSYS) - *supports_tls = 0; - return; - } - } - - *supports_tls = 0; -} diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 3a7efb0..2eb2843 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -25,8 +25,3 @@ $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ define unprofile $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) endef - -ifdef subarch-obj-y -obj-y += subarch.o -subarch-y = $(addprefix ../../$(HEADER_ARCH)/,$(subarch-obj-y)) -endif diff --git a/arch/um/sys-x86/Makefile b/arch/um/sys-x86/Makefile deleted file mode 100644 index 81ab348..0000000 --- a/arch/um/sys-x86/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# - -ifeq ($(CONFIG_X86_32),y) - BITS := 32 -else - BITS := 64 -endif - -obj-y = bug.o bugs_$(BITS).o delay_$(BITS).o fault.o ksyms.o ldt.o \ - ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal_$(BITS).o \ - stub_$(BITS).o stub_segv.o syscalls_$(BITS).o \ - sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o mem_$(BITS).o - -ifeq ($(CONFIG_X86_32),y) - -obj-y += checksum_32.o -obj-$(CONFIG_BINFMT_ELF) += elfcore.o - -subarch-obj-y = lib/string_32.o lib/atomic64_32.o lib/atomic64_cx8_32.o -subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -else - -obj-y += vdso/ - -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ - lib/rwsem.o - -endif - -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -USER_OBJS := bugs_$(BITS).o ptrace_user.o fault.o - -extra-y += user-offsets.s -$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-x86/asm/arch_hweight.h b/arch/um/sys-x86/asm/arch_hweight.h deleted file mode 100644 index c656cf4..0000000 --- a/arch/um/sys-x86/asm/arch_hweight.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_HWEIGHT_H -#define _ASM_UM_HWEIGHT_H - -#include - -#endif diff --git a/arch/um/sys-x86/asm/archparam.h b/arch/um/sys-x86/asm/archparam.h deleted file mode 100644 index c17cf68..0000000 --- a/arch/um/sys-x86/asm/archparam.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_H -#define __UM_ARCHPARAM_H - -#ifdef CONFIG_X86_32 - -#ifdef CONFIG_X86_PAE -#define LAST_PKMAP 512 -#else -#define LAST_PKMAP 1024 -#endif - -#endif - -#endif diff --git a/arch/um/sys-x86/asm/checksum.h b/arch/um/sys-x86/asm/checksum.h deleted file mode 100644 index b6efe23..0000000 --- a/arch/um/sys-x86/asm/checksum.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __UM_CHECKSUM_H -#define __UM_CHECKSUM_H - -#ifdef CONFIG_X86_32 -# include "checksum_32.h" -#else -# include "checksum_64.h" -#endif - -#endif diff --git a/arch/um/sys-x86/asm/checksum_32.h b/arch/um/sys-x86/asm/checksum_32.h deleted file mode 100644 index caab742..0000000 --- a/arch/um/sys-x86/asm/checksum_32.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/in6.h" -#include "linux/string.h" - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - -/* - * the same as csum_partial, but copies from src while it - * checksums, and handles user-space pointer exceptions correctly, when needed. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(dst, len, sum); -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - * By Jorge Cwik , adapted for linux by - * Arnt Gulbrandsen. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - __asm__ __volatile__( - "movl (%1), %0 ;\n" - "subl $4, %2 ;\n" - "jbe 2f ;\n" - "addl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" -"1: adcl 16(%1), %0 ;\n" - "lea 4(%1), %1 ;\n" - "decl %2 ;\n" - "jne 1b ;\n" - "adcl $0, %0 ;\n" - "movl %0, %2 ;\n" - "shrl $16, %0 ;\n" - "addw %w2, %w0 ;\n" - "adcl $0, %0 ;\n" - "notl %0 ;\n" -"2: ;\n" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl $0xffff, %0 ;\n" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl %2, %0 ;\n" - "adcl %3, %0 ;\n" - "adcl $0, %0 ;\n" - : "=r" (sum) - : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - __asm__( - "addl 0(%1), %0 ;\n" - "adcl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" - "adcl 0(%2), %0 ;\n" - "adcl 4(%2), %0 ;\n" - "adcl 8(%2), %0 ;\n" - "adcl 12(%2), %0 ;\n" - "adcl %3, %0 ;\n" - "adcl %4, %0 ;\n" - "adcl $0, %0 ;\n" - : "=&r" (sum) - : "r" (saddr), "r" (daddr), - "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); - - return csum_fold(sum); -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, int *err_ptr) -{ - if (access_ok(VERIFY_WRITE, dst, len)) { - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(src, len, sum); - } - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} - -#endif - diff --git a/arch/um/sys-x86/asm/checksum_64.h b/arch/um/sys-x86/asm/checksum_64.h deleted file mode 100644 index a5be903..0000000 --- a/arch/um/sys-x86/asm/checksum_64.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/string.h" -#include "linux/in6.h" -#include "asm/uaccess.h" - -extern __wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return(csum_partial(dst, len, sum)); -} - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, - int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - return csum_partial(dst, len, sum); -} - -/** - * csum_fold - Fold and invert a 32bit checksum. - * sum: 32bit unfolded sum - * - * Fold a 32bit running checksum to 16bit and invert it. This is usually - * the last step before putting a checksum into a packet. - * Make sure not to mix with 64bit checksums. - */ -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - " addl %1,%0\n" - " adcl $0xffff,%0" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -/** - * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. - * @saddr: source address - * @daddr: destination address - * @len: length of packet - * @proto: ip protocol of packet - * @sum: initial sum to be added in (32bit unfolded) - * - * Returns the pseudo header checksum the input data. Result is - * 32bit unfolded. - */ -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - asm(" addl %1, %0\n" - " adcl %2, %0\n" - " adcl %3, %0\n" - " adcl $0, %0\n" - : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/** - * ip_fast_csum - Compute the IPv4 header checksum efficiently. - * iph: ipv4 header - * ihl: length of header / 4 - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - asm( " movl (%1), %0\n" - " subl $4, %2\n" - " jbe 2f\n" - " addl 4(%1), %0\n" - " adcl 8(%1), %0\n" - " adcl 12(%1), %0\n" - "1: adcl 16(%1), %0\n" - " lea 4(%1), %1\n" - " decl %2\n" - " jne 1b\n" - " adcl $0, %0\n" - " movl %0, %2\n" - " shrl $16, %0\n" - " addw %w2, %w0\n" - " adcl $0, %0\n" - " notl %0\n" - "2:" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -static inline unsigned add32_with_carry(unsigned a, unsigned b) -{ - asm("addl %2,%0\n\t" - "adcl $0,%0" - : "=r" (a) - : "0" (a), "r" (b)); - return a; -} - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#endif diff --git a/arch/um/sys-x86/asm/elf.h b/arch/um/sys-x86/asm/elf.h deleted file mode 100644 index f3b0633..0000000 --- a/arch/um/sys-x86/asm/elf.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ -#ifndef __UM_ELF_X86_H -#define __UM_ELF_X86_H - -#include -#include "skas.h" - -#ifdef CONFIG_X86_32 - -#define R_386_NONE 0 -#define R_386_32 1 -#define R_386_PC32 2 -#define R_386_GOT32 3 -#define R_386_PLT32 4 -#define R_386_COPY 5 -#define R_386_GLOB_DAT 6 -#define R_386_JMP_SLOT 7 -#define R_386_RELATIVE 8 -#define R_386_GOTOFF 9 -#define R_386_GOTPC 10 -#define R_386_NUM 11 - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) - -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_386 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_EBX(regs) = 0; \ - PT_REGS_ECX(regs) = 0; \ - PT_REGS_EDX(regs) = 0; \ - PT_REGS_ESI(regs) = 0; \ - PT_REGS_EDI(regs) = 0; \ - PT_REGS_EBP(regs) = 0; \ - PT_REGS_EAX(regs) = 0; \ -} while (0) - -/* Shamelessly stolen from include/asm-i386/elf.h */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ - pr_reg[0] = PT_REGS_EBX(regs); \ - pr_reg[1] = PT_REGS_ECX(regs); \ - pr_reg[2] = PT_REGS_EDX(regs); \ - pr_reg[3] = PT_REGS_ESI(regs); \ - pr_reg[4] = PT_REGS_EDI(regs); \ - pr_reg[5] = PT_REGS_EBP(regs); \ - pr_reg[6] = PT_REGS_EAX(regs); \ - pr_reg[7] = PT_REGS_DS(regs); \ - pr_reg[8] = PT_REGS_ES(regs); \ - /* fake once used fs and gs selectors? */ \ - pr_reg[9] = PT_REGS_DS(regs); \ - pr_reg[10] = PT_REGS_DS(regs); \ - pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ - pr_reg[12] = PT_REGS_IP(regs); \ - pr_reg[13] = PT_REGS_CS(regs); \ - pr_reg[14] = PT_REGS_EFLAGS(regs); \ - pr_reg[15] = PT_REGS_SP(regs); \ - pr_reg[16] = PT_REGS_SS(regs); \ -} while (0); - -extern char * elf_aux_platform; -#define ELF_PLATFORM (elf_aux_platform) - -extern unsigned long vsyscall_ehdr; -extern unsigned long vsyscall_end; -extern unsigned long __kernel_vsyscall; - -/* - * This is the range that is readable by user mode, and things - * acting like user mode such as get_user_pages. - */ -#define FIXADDR_USER_START vsyscall_ehdr -#define FIXADDR_USER_END vsyscall_end - - -/* - * Architecture-neutral AT_ values in 0-17, leave some room - * for more of them, start the x86-specific ones at 32. - */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -#define ARCH_DLINFO \ -do { \ - if ( vsyscall_ehdr ) { \ - NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ - } \ -} while (0) - -#else - -/* x86-64 relocation types, taken from asm-x86_64/elf.h */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ - -#define R_X86_64_NUM 16 - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - ((x)->e_machine == EM_X86_64) - -#define ELF_CLASS ELFCLASS64 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_X86_64 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_RBX(regs) = 0; \ - PT_REGS_RCX(regs) = 0; \ - PT_REGS_RDX(regs) = 0; \ - PT_REGS_RSI(regs) = 0; \ - PT_REGS_RDI(regs) = 0; \ - PT_REGS_RBP(regs) = 0; \ - PT_REGS_RAX(regs) = 0; \ - PT_REGS_R8(regs) = 0; \ - PT_REGS_R9(regs) = 0; \ - PT_REGS_R10(regs) = 0; \ - PT_REGS_R11(regs) = 0; \ - PT_REGS_R12(regs) = 0; \ - PT_REGS_R13(regs) = 0; \ - PT_REGS_R14(regs) = 0; \ - PT_REGS_R15(regs) = 0; \ -} while (0) - -#define ELF_CORE_COPY_REGS(pr_reg, _regs) \ - (pr_reg)[0] = (_regs)->regs.gp[0]; \ - (pr_reg)[1] = (_regs)->regs.gp[1]; \ - (pr_reg)[2] = (_regs)->regs.gp[2]; \ - (pr_reg)[3] = (_regs)->regs.gp[3]; \ - (pr_reg)[4] = (_regs)->regs.gp[4]; \ - (pr_reg)[5] = (_regs)->regs.gp[5]; \ - (pr_reg)[6] = (_regs)->regs.gp[6]; \ - (pr_reg)[7] = (_regs)->regs.gp[7]; \ - (pr_reg)[8] = (_regs)->regs.gp[8]; \ - (pr_reg)[9] = (_regs)->regs.gp[9]; \ - (pr_reg)[10] = (_regs)->regs.gp[10]; \ - (pr_reg)[11] = (_regs)->regs.gp[11]; \ - (pr_reg)[12] = (_regs)->regs.gp[12]; \ - (pr_reg)[13] = (_regs)->regs.gp[13]; \ - (pr_reg)[14] = (_regs)->regs.gp[14]; \ - (pr_reg)[15] = (_regs)->regs.gp[15]; \ - (pr_reg)[16] = (_regs)->regs.gp[16]; \ - (pr_reg)[17] = (_regs)->regs.gp[17]; \ - (pr_reg)[18] = (_regs)->regs.gp[18]; \ - (pr_reg)[19] = (_regs)->regs.gp[19]; \ - (pr_reg)[20] = (_regs)->regs.gp[20]; \ - (pr_reg)[21] = current->thread.arch.fs; \ - (pr_reg)[22] = 0; \ - (pr_reg)[23] = 0; \ - (pr_reg)[24] = 0; \ - (pr_reg)[25] = 0; \ - (pr_reg)[26] = 0; - -#define ELF_PLATFORM "x86_64" - -/* No user-accessible fixmap addresses, i.e. vsyscall */ -#define FIXADDR_USER_START 0 -#define FIXADDR_USER_END 0 - -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -struct linux_binprm; -extern int arch_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp); - -extern unsigned long um_vdso_addr; -#define AT_SYSINFO_EHDR 33 -#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) - -#endif - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -#define SET_PERSONALITY(ex) do ; while(0) -#define __HAVE_ARCH_GATE_AREA 1 - -#endif diff --git a/arch/um/sys-x86/asm/module.h b/arch/um/sys-x86/asm/module.h deleted file mode 100644 index 61af80e..0000000 --- a/arch/um/sys-x86/asm/module.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __UM_MODULE_H -#define __UM_MODULE_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#ifdef CONFIG_X86_32 - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#else - -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - -#endif - -#endif diff --git a/arch/um/sys-x86/asm/processor.h b/arch/um/sys-x86/asm/processor.h deleted file mode 100644 index d3ac1ce..0000000 --- a/arch/um/sys-x86/asm/processor.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __UM_PROCESSOR_H -#define __UM_PROCESSOR_H - -/* include faultinfo structure */ -#include - -#ifdef CONFIG_X86_32 -# include "processor_32.h" -#else -# include "processor_64.h" -#endif - -#include - -#endif diff --git a/arch/um/sys-x86/asm/processor_32.h b/arch/um/sys-x86/asm/processor_32.h deleted file mode 100644 index ae0d189..0000000 --- a/arch/um/sys-x86/asm/processor_32.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_I386_H -#define __UM_PROCESSOR_I386_H - -#include -#include -#include - -extern int host_has_cmov; - -struct uml_tls_struct { - struct user_desc tls; - unsigned flushed:1; - unsigned present:1; -}; - -struct arch_thread { - struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - unsigned long debugregs[8]; - int debugregs_seq; - struct faultinfo faultinfo; -}; - -#define INIT_ARCH_THREAD { \ - .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \ - { .present = 0, .flushed = 0 } }, \ - .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .faultinfo = { 0, 0, 0 } \ -} - -static inline void arch_flush_thread(struct arch_thread *thread) -{ - /* Clear any TLS still hanging */ - memset(&thread->tls_array, 0, sizeof(thread->tls_array)); -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array)); -} - -#include - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). Stolen - * from asm-i386/processor.h - */ -#define current_text_addr() \ - ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 32 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) -#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) - -#endif diff --git a/arch/um/sys-x86/asm/processor_64.h b/arch/um/sys-x86/asm/processor_64.h deleted file mode 100644 index 6db812b..0000000 --- a/arch/um/sys-x86/asm/processor_64.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_X86_64_H -#define __UM_PROCESSOR_X86_64_H - -struct arch_thread { - unsigned long debugregs[8]; - int debugregs_seq; - unsigned long fs; - struct faultinfo faultinfo; -}; - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .fs = 0, \ - .faultinfo = { 0, 0, 0 } } - -static inline void arch_flush_thread(struct arch_thread *thread) -{ -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - to->fs = from->fs; -} - -#include - -#define current_text_addr() \ - ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 128 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP) - -#endif diff --git a/arch/um/sys-x86/asm/ptrace.h b/arch/um/sys-x86/asm/ptrace.h deleted file mode 100644 index c8aca8c..0000000 --- a/arch/um/sys-x86/asm/ptrace.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef CONFIG_X86_32 -# include "ptrace_32.h" -#else -# include "ptrace_64.h" -#endif diff --git a/arch/um/sys-x86/asm/ptrace_32.h b/arch/um/sys-x86/asm/ptrace_32.h deleted file mode 100644 index 5d2a591..0000000 --- a/arch/um/sys-x86/asm/ptrace_32.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_I386_H -#define __UM_PTRACE_I386_H - -#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 - -#include "linux/compiler.h" -#include "asm/ptrace-generic.h" - -#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) -#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) -#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) -#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) -#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) -#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) -#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) - -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -#define user_mode(r) UPT_IS_USER(&(r)->regs) - -/* - * Forward declaration to avoid including sysdep/tls.h, which causes a - * circular include, and compilation failures. - */ -struct user_desc; - -extern int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -extern int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -#endif diff --git a/arch/um/sys-x86/asm/ptrace_64.h b/arch/um/sys-x86/asm/ptrace_64.h deleted file mode 100644 index 83d8c47..0000000 --- a/arch/um/sys-x86/asm/ptrace_64.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_X86_64_H -#define __UM_PTRACE_X86_64_H - -#include "linux/compiler.h" -#include "asm/errno.h" - -#define __FRAME_OFFSETS /* Needed to get the R* macros */ -#include "asm/ptrace-generic.h" - -#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64 - -#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs) -#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs) -#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs) -#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs) -#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs) -#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs) -#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs) -#define PT_REGS_R8(r) UPT_R8(&(r)->regs) -#define PT_REGS_R9(r) UPT_R9(&(r)->regs) -#define PT_REGS_R10(r) UPT_R10(&(r)->regs) -#define PT_REGS_R11(r) UPT_R11(&(r)->regs) -#define PT_REGS_R12(r) UPT_R12(&(r)->regs) -#define PT_REGS_R13(r) UPT_R13(&(r)->regs) -#define PT_REGS_R14(r) UPT_R14(&(r)->regs) -#define PT_REGS_R15(r) UPT_R15(&(r)->regs) - -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) - -#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs) -#define PT_REGS_RIP(r) UPT_IP(&(r)->regs) -#define PT_REGS_RSP(r) UPT_SP(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -/* XXX */ -#define user_mode(r) UPT_IS_USER(&(r)->regs) -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r) - -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -struct user_desc; - -static inline int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -static inline int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -extern long arch_prctl(struct task_struct *task, int code, - unsigned long __user *addr); -#endif diff --git a/arch/um/sys-x86/asm/system.h b/arch/um/sys-x86/asm/system.h deleted file mode 100644 index a89113b..0000000 --- a/arch/um/sys-x86/asm/system.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-x86/asm/vm-flags.h b/arch/um/sys-x86/asm/vm-flags.h deleted file mode 100644 index 7c297e9..0000000 --- a/arch/um/sys-x86/asm/vm-flags.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_X86_H -#define __VM_FLAGS_X86_H - -#ifdef CONFIG_X86_32 - -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#else - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define VM_STACK_DEFAULT_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif -#endif diff --git a/arch/um/sys-x86/bug.c b/arch/um/sys-x86/bug.c deleted file mode 100644 index e8034e3..0000000 --- a/arch/um/sys-x86/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include - -/* - * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-x86/bugs_32.c b/arch/um/sys-x86/bugs_32.c deleted file mode 100644 index 7058e1f..0000000 --- a/arch/um/sys-x86/bugs_32.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "kern_util.h" -#include "longjmp.h" -#include "task.h" -#include "sysdep/ptrace.h" - -/* Set during early boot */ -static int host_has_cmov = 1; -static jmp_buf cmov_test_return; - -static void cmov_sigill_test_handler(int sig) -{ - host_has_cmov = 0; - longjmp(cmov_test_return, 1); -} - -void arch_check_bugs(void) -{ - struct sigaction old, new; - - printk(UM_KERN_INFO "Checking for host processor cmov support..."); - new.sa_handler = cmov_sigill_test_handler; - - /* Make sure that SIGILL is enabled after the handler longjmps back */ - new.sa_flags = SA_NODEFER; - sigemptyset(&new.sa_mask); - sigaction(SIGILL, &new, &old); - - if (setjmp(cmov_test_return) == 0) { - unsigned long foo = 0; - __asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo)); - printk(UM_KERN_CONT "Yes\n"); - } else - printk(UM_KERN_CONT "No\n"); - - sigaction(SIGILL, &old, &new); -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ - unsigned char tmp[2]; - - /* - * This is testing for a cmov (0x0f 0x4x) instruction causing a - * SIGILL in init. - */ - if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) - return; - - if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) { - printk(UM_KERN_ERR "SIGILL in init, could not read " - "instructions!\n"); - return; - } - - if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return; - - if (host_has_cmov == 0) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor doesn't implement. Boot a filesystem " - "compiled for older processors"); - else if (host_has_cmov == 1) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor claims to implement"); - else - printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)", - host_has_cmov); -} diff --git a/arch/um/sys-x86/bugs_64.c b/arch/um/sys-x86/bugs_64.c deleted file mode 100644 index 44e02ba..0000000 --- a/arch/um/sys-x86/bugs_64.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -void arch_check_bugs(void) -{ -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ -} diff --git a/arch/um/sys-x86/checksum_32.S b/arch/um/sys-x86/checksum_32.S deleted file mode 100644 index f058d2f..0000000 --- a/arch/um/sys-x86/checksum_32.S +++ /dev/null @@ -1,458 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Pentium Pro/II routines: - * Alexander Kjeldaas - * Finn Arne Gangstad - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception - * handling. - * Andi Kleen, add zeroing on error - * converted to pure assembler - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -/* -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) - */ - -.text -.align 4 -.globl csum_partial - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - - /* - * Experiments with Ethernet and SLIP connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. We get at - * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. - * Fortunately, it is easy to convert 2-byte alignment to 4-byte - * alignment for the unrolled loop. - */ -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: unsigned char *buff - testl $2, %esi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -1: movw (%esi), %bx - addl $2, %esi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, %edx - shrl $5, %ecx - jz 2f - testl %esi, %esi -1: movl (%esi), %ebx - adcl %ebx, %eax - movl 4(%esi), %ebx - adcl %ebx, %eax - movl 8(%esi), %ebx - adcl %ebx, %eax - movl 12(%esi), %ebx - adcl %ebx, %eax - movl 16(%esi), %ebx - adcl %ebx, %eax - movl 20(%esi), %ebx - adcl %ebx, %eax - movl 24(%esi), %ebx - adcl %ebx, %eax - movl 28(%esi), %ebx - adcl %ebx, %eax - lea 32(%esi), %esi - dec %ecx - jne 1b - adcl $0, %eax -2: movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -3: adcl (%esi), %eax - lea 4(%esi), %esi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f - movw (%esi),%cx - leal 2(%esi),%esi - je 6f - shll $16,%ecx -5: movb (%esi),%cl -6: addl %ecx,%eax - adcl $0, %eax -7: - popl %ebx - popl %esi - ret - -#else - -/* Version for PentiumII/PPro */ - -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: const unsigned char *buf - - testl $2, %esi - jnz 30f -10: - movl %ecx, %edx - movl %ecx, %ebx - andl $0x7c, %ebx - shrl $7, %ecx - addl %ebx,%esi - shrl $2, %ebx - negl %ebx - lea 45f(%ebx,%ebx,2), %ebx - testl %esi, %esi - jmp *%ebx - - # Handle 2-byte-aligned regions -20: addw (%esi), %ax - lea 2(%esi), %esi - adcl $0, %eax - jmp 10b - -30: subl $2, %ecx - ja 20b - je 32f - movzbl (%esi),%ebx # csumming 1 byte, 2-aligned - addl %ebx, %eax - adcl $0, %eax - jmp 80f -32: - addw (%esi), %ax # csumming 2 bytes, 2-aligned - adcl $0, %eax - jmp 80f - -40: - addl -128(%esi), %eax - adcl -124(%esi), %eax - adcl -120(%esi), %eax - adcl -116(%esi), %eax - adcl -112(%esi), %eax - adcl -108(%esi), %eax - adcl -104(%esi), %eax - adcl -100(%esi), %eax - adcl -96(%esi), %eax - adcl -92(%esi), %eax - adcl -88(%esi), %eax - adcl -84(%esi), %eax - adcl -80(%esi), %eax - adcl -76(%esi), %eax - adcl -72(%esi), %eax - adcl -68(%esi), %eax - adcl -64(%esi), %eax - adcl -60(%esi), %eax - adcl -56(%esi), %eax - adcl -52(%esi), %eax - adcl -48(%esi), %eax - adcl -44(%esi), %eax - adcl -40(%esi), %eax - adcl -36(%esi), %eax - adcl -32(%esi), %eax - adcl -28(%esi), %eax - adcl -24(%esi), %eax - adcl -20(%esi), %eax - adcl -16(%esi), %eax - adcl -12(%esi), %eax - adcl -8(%esi), %eax - adcl -4(%esi), %eax -45: - lea 128(%esi), %esi - adcl $0, %eax - dec %ecx - jge 40b - movl %edx, %ecx -50: andl $3, %ecx - jz 80f - - # Handle the last 1-3 bytes without jumping - notl %ecx # 1->2, 2->1, 3->0, higher bits are masked - movl $0xffffff,%ebx # by the shll and shrl instructions - shll $3,%ecx - shrl %cl,%ebx - andl -128(%esi),%ebx # esi is 4-aligned so should be ok - addl %ebx,%eax - adcl $0,%eax -80: - popl %ebx - popl %esi - ret - -#endif - -/* -unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) - */ - -/* - * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. - */ - -#define SRC(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6001f ; \ - .previous - -#define DST(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6002f ; \ - .previous - -.align 4 - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - -#define ARGBASE 16 -#define FP 12 - -csum_partial_copy_generic_i386: - subl $4,%esp - pushl %edi - pushl %esi - pushl %ebx - movl ARGBASE+16(%esp),%eax # sum - movl ARGBASE+12(%esp),%ecx # len - movl ARGBASE+4(%esp),%esi # src - movl ARGBASE+8(%esp),%edi # dst - - testl $2, %edi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -SRC(1: movw (%esi), %bx ) - addl $2, %esi -DST( movw %bx, (%edi) ) - addl $2, %edi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, FP(%esp) - shrl $5, %ecx - jz 2f - testl %esi, %esi -SRC(1: movl (%esi), %ebx ) -SRC( movl 4(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - adcl %edx, %eax -DST( movl %edx, 4(%edi) ) - -SRC( movl 8(%esi), %ebx ) -SRC( movl 12(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 8(%edi) ) - adcl %edx, %eax -DST( movl %edx, 12(%edi) ) - -SRC( movl 16(%esi), %ebx ) -SRC( movl 20(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 16(%edi) ) - adcl %edx, %eax -DST( movl %edx, 20(%edi) ) - -SRC( movl 24(%esi), %ebx ) -SRC( movl 28(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 24(%edi) ) - adcl %edx, %eax -DST( movl %edx, 28(%edi) ) - - lea 32(%esi), %esi - lea 32(%edi), %edi - dec %ecx - jne 1b - adcl $0, %eax -2: movl FP(%esp), %edx - movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -SRC(3: movl (%esi), %ebx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - lea 4(%esi), %esi - lea 4(%edi), %edi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f -SRC( movw (%esi), %cx ) - leal 2(%esi), %esi -DST( movw %cx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%ecx -SRC(5: movb (%esi), %cl ) -DST( movb %cl, (%edi) ) -6: addl %ecx, %eax - adcl $0, %eax -7: -5000: - -# Exception handler: -.section .fixup, "ax" - -6001: - movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - - # zero the complete destination - computing the rest - # is too much work - movl ARGBASE+8(%esp), %edi # dst - movl ARGBASE+12(%esp), %ecx # len - xorl %eax,%eax - rep ; stosb - - jmp 5000b - -6002: - movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT,(%ebx) - jmp 5000b - -.previous - - popl %ebx - popl %esi - popl %edi - popl %ecx # equivalent to addl $4,%esp - ret - -#else - -/* Version for PentiumII/PPro */ - -#define ROUND1(x) \ - SRC(movl x(%esi), %ebx ) ; \ - addl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ROUND(x) \ - SRC(movl x(%esi), %ebx ) ; \ - adcl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ARGBASE 12 - -csum_partial_copy_generic_i386: - pushl %ebx - pushl %edi - pushl %esi - movl ARGBASE+4(%esp),%esi #src - movl ARGBASE+8(%esp),%edi #dst - movl ARGBASE+12(%esp),%ecx #len - movl ARGBASE+16(%esp),%eax #sum -# movl %ecx, %edx - movl %ecx, %ebx - movl %esi, %edx - shrl $6, %ecx - andl $0x3c, %ebx - negl %ebx - subl %ebx, %esi - subl %ebx, %edi - lea -1(%esi),%edx - andl $-32,%edx - lea 3f(%ebx,%ebx), %ebx - testl %esi, %esi - jmp *%ebx -1: addl $64,%esi - addl $64,%edi - SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) - ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) - ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) - ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) - ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) -3: adcl $0,%eax - addl $64, %edx - dec %ecx - jge 1b -4: movl ARGBASE+12(%esp),%edx #len - andl $3, %edx - jz 7f - cmpl $2, %edx - jb 5f -SRC( movw (%esi), %dx ) - leal 2(%esi), %esi -DST( movw %dx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%edx -5: -SRC( movb (%esi), %dl ) -DST( movb %dl, (%edi) ) -6: addl %edx, %eax - adcl $0, %eax -7: -.section .fixup, "ax" -6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - # zero the complete destination (computing the rest is too much work) - movl ARGBASE+8(%esp),%edi # dst - movl ARGBASE+12(%esp),%ecx # len - xorl %eax,%eax - rep; stosb - jmp 7b -6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT, (%ebx) - jmp 7b -.previous - - popl %esi - popl %edi - popl %ebx - ret - -#undef ROUND -#undef ROUND1 - -#endif diff --git a/arch/um/sys-x86/delay_32.c b/arch/um/sys-x86/delay_32.c deleted file mode 100644 index f3fe1a6..0000000 --- a/arch/um/sys-x86/delay_32.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * Mostly copied from arch/x86/lib/delay.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -void __delay(unsigned long loops) -{ - asm volatile( - "test %0,%0\n" - "jz 3f\n" - "jmp 1f\n" - - ".align 16\n" - "1: jmp 2f\n" - - ".align 16\n" - "2: dec %0\n" - " jnz 2b\n" - "3: dec %0\n" - - : /* we don't need output */ - : "a" (loops) - ); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - asm("mull %%edx" - : "=d" (xloops), "=&a" (d0) - : "1" (xloops), "0" - (loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86/delay_64.c b/arch/um/sys-x86/delay_64.c deleted file mode 100644 index f3fe1a6..0000000 --- a/arch/um/sys-x86/delay_64.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * Mostly copied from arch/x86/lib/delay.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -void __delay(unsigned long loops) -{ - asm volatile( - "test %0,%0\n" - "jz 3f\n" - "jmp 1f\n" - - ".align 16\n" - "1: jmp 2f\n" - - ".align 16\n" - "2: dec %0\n" - " jnz 2b\n" - "3: dec %0\n" - - : /* we don't need output */ - : "a" (loops) - ); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - asm("mull %%edx" - : "=d" (xloops), "=&a" (d0) - : "1" (xloops), "0" - (loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86/elfcore.c b/arch/um/sys-x86/elfcore.c deleted file mode 100644 index 6bb49b6..0000000 --- a/arch/um/sys-x86/elfcore.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include - -#include - - -Elf32_Half elf_core_extra_phdrs(void) -{ - return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; -} - -int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - Elf32_Off ofs = 0; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - struct elf_phdr phdr = phdrp[i]; - - if (phdr.p_type == PT_LOAD) { - ofs = phdr.p_offset = offset; - offset += phdr.p_filesz; - } else { - phdr.p_offset += ofs; - } - phdr.p_paddr = 0; /* match other core phdrs */ - *size += sizeof(phdr); - if (*size > limit - || !dump_write(file, &phdr, sizeof(phdr))) - return 0; - } - } - return 1; -} - -int elf_core_write_extra_data(struct file *file, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - if (phdrp[i].p_type == PT_LOAD) { - void *addr = (void *) phdrp[i].p_vaddr; - size_t filesz = phdrp[i].p_filesz; - - *size += filesz; - if (*size > limit - || !dump_write(file, addr, filesz)) - return 0; - } - } - } - return 1; -} - -size_t elf_core_extra_data_size(void) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *)vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) - if (phdrp[i].p_type == PT_LOAD) - return (size_t) phdrp[i].p_filesz; - } - return 0; -} diff --git a/arch/um/sys-x86/fault.c b/arch/um/sys-x86/fault.c deleted file mode 100644 index d670f68..0000000 --- a/arch/um/sys-x86/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-x86/ksyms.c b/arch/um/sys-x86/ksyms.c deleted file mode 100644 index 2e8f43e..0000000 --- a/arch/um/sys-x86/ksyms.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -#ifndef CONFIG_X86_32 -/*XXX: we need them because they would be exported by x86_64 */ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 -EXPORT_SYMBOL(memcpy); -#else -EXPORT_SYMBOL(__memcpy); -#endif -#endif -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-x86/ldt.c b/arch/um/sys-x86/ldt.c deleted file mode 100644 index 3f2bf20..0000000 --- a/arch/um/sys-x86/ldt.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include "os.h" -#include "proc_mm.h" -#include "skas.h" -#include "skas_ptrace.h" -#include "sysdep/tls.h" - -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); - -static long write_ldt_entry(struct mm_id *mm_idp, int func, - struct user_desc *desc, void **addr, int done) -{ - long res; - - if (proc_mm) { - /* - * This is a special handling for the case, that the mm to - * modify isn't current->active_mm. - * If this is called directly by modify_ldt, - * (current->active_mm->context.skas.u == mm_idp) - * will be true. So no call to __switch_mm(mm_idp) is done. - * If this is called in case of init_new_ldt or PTRACE_LDT, - * mm_idp won't belong to current->active_mm, but child->mm. - * So we need to switch child's mm into our userspace, then - * later switch back. - * - * Note: I'm unsure: should interrupts be disabled here? - */ - if (!current->active_mm || current->active_mm == &init_mm || - mm_idp != ¤t->active_mm->context.id) - __switch_mm(mm_idp); - } - - if (ptrace_ldt) { - struct ptrace_ldt ldt_op = (struct ptrace_ldt) { - .func = func, - .ptr = desc, - .bytecount = sizeof(*desc)}; - u32 cpu; - int pid; - - if (!proc_mm) - pid = mm_idp->u.pid; - else { - cpu = get_cpu(); - pid = userspace_pid[cpu]; - } - - res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); - - if (proc_mm) - put_cpu(); - } - else { - void *stub_addr; - res = syscall_stub_data(mm_idp, (unsigned long *)desc, - (sizeof(*desc) + sizeof(long) - 1) & - ~(sizeof(long) - 1), - addr, &stub_addr); - if (!res) { - unsigned long args[] = { func, - (unsigned long)stub_addr, - sizeof(*desc), - 0, 0, 0 }; - res = run_syscall_stub(mm_idp, __NR_modify_ldt, args, - 0, addr, done); - } - } - - if (proc_mm) { - /* - * This is the second part of special handling, that makes - * PTRACE_LDT possible to implement. - */ - if (current->active_mm && current->active_mm != &init_mm && - mm_idp != ¤t->active_mm->context.id) - __switch_mm(¤t->active_mm->context.id); - } - - return res; -} - -static long read_ldt_from_host(void __user * ptr, unsigned long bytecount) -{ - int res, n; - struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) { - .func = 0, - .bytecount = bytecount, - .ptr = kmalloc(bytecount, GFP_KERNEL)}; - u32 cpu; - - if (ptrace_ldt.ptr == NULL) - return -ENOMEM; - - /* - * This is called from sys_modify_ldt only, so userspace_pid gives - * us the right number - */ - - cpu = get_cpu(); - res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); - put_cpu(); - if (res < 0) - goto out; - - n = copy_to_user(ptr, ptrace_ldt.ptr, res); - if (n != 0) - res = -EFAULT; - - out: - kfree(ptrace_ldt.ptr); - - return res; -} - -/* - * In skas mode, we hold our own ldt data in UML. - * Thus, the code implementing sys_modify_ldt_skas - * is very similar to (and mostly stolen from) sys_modify_ldt - * for arch/i386/kernel/ldt.c - * The routines copied and modified in part are: - * - read_ldt - * - read_default_ldt - * - write_ldt - * - sys_modify_ldt_skas - */ - -static int read_ldt(void __user * ptr, unsigned long bytecount) -{ - int i, err = 0; - unsigned long size; - uml_ldt_t * ldt = ¤t->mm->context.ldt; - - if (!ldt->entry_count) - goto out; - if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) - bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - err = bytecount; - - if (ptrace_ldt) - return read_ldt_from_host(ptr, bytecount); - - mutex_lock(&ldt->lock); - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { - size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.entries, size)) - err = -EFAULT; - bytecount -= size; - ptr += size; - } - else { - for (i=0; ientry_count/LDT_ENTRIES_PER_PAGE && bytecount; - i++) { - size = PAGE_SIZE; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.pages[i], size)) { - err = -EFAULT; - break; - } - bytecount -= size; - ptr += size; - } - } - mutex_unlock(&ldt->lock); - - if (bytecount == 0 || err == -EFAULT) - goto out; - - if (clear_user(ptr, bytecount)) - err = -EFAULT; - -out: - return err; -} - -static int read_default_ldt(void __user * ptr, unsigned long bytecount) -{ - int err; - - if (bytecount > 5*LDT_ENTRY_SIZE) - bytecount = 5*LDT_ENTRY_SIZE; - - err = bytecount; - /* - * UML doesn't support lcall7 and lcall27. - * So, we don't really have a default ldt, but emulate - * an empty ldt of common host default ldt size. - */ - if (clear_user(ptr, bytecount)) - err = -EFAULT; - - return err; -} - -static int write_ldt(void __user * ptr, unsigned long bytecount, int func) -{ - uml_ldt_t * ldt = ¤t->mm->context.ldt; - struct mm_id * mm_idp = ¤t->mm->context.id; - int i, err; - struct user_desc ldt_info; - struct ldt_entry entry0, *ldt_p; - void *addr = NULL; - - err = -EINVAL; - if (bytecount != sizeof(ldt_info)) - goto out; - err = -EFAULT; - if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) - goto out; - - err = -EINVAL; - if (ldt_info.entry_number >= LDT_ENTRIES) - goto out; - if (ldt_info.contents == 3) { - if (func == 1) - goto out; - if (ldt_info.seg_not_present == 0) - goto out; - } - - if (!ptrace_ldt) - mutex_lock(&ldt->lock); - - err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); - if (err) - goto out_unlock; - else if (ptrace_ldt) { - /* With PTRACE_LDT available, this is used as a flag only */ - ldt->entry_count = 1; - goto out; - } - - if (ldt_info.entry_number >= ldt->entry_count && - ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { - for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; - i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; - i++) { - if (i == 0) - memcpy(&entry0, ldt->u.entries, - sizeof(entry0)); - ldt->u.pages[i] = (struct ldt_entry *) - __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!ldt->u.pages[i]) { - err = -ENOMEM; - /* Undo the change in host */ - memset(&ldt_info, 0, sizeof(ldt_info)); - write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); - goto out_unlock; - } - if (i == 0) { - memcpy(ldt->u.pages[0], &entry0, - sizeof(entry0)); - memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, - sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); - } - ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; - } - } - if (ldt->entry_count <= ldt_info.entry_number) - ldt->entry_count = ldt_info.entry_number + 1; - - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) - ldt_p = ldt->u.entries + ldt_info.entry_number; - else - ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + - ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; - - if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && - (func == 1 || LDT_empty(&ldt_info))) { - ldt_p->a = 0; - ldt_p->b = 0; - } - else{ - if (func == 1) - ldt_info.useable = 0; - ldt_p->a = LDT_entry_a(&ldt_info); - ldt_p->b = LDT_entry_b(&ldt_info); - } - err = 0; - -out_unlock: - mutex_unlock(&ldt->lock); -out: - return err; -} - -static long do_modify_ldt_skas(int func, void __user *ptr, - unsigned long bytecount) -{ - int ret = -ENOSYS; - - switch (func) { - case 0: - ret = read_ldt(ptr, bytecount); - break; - case 1: - case 0x11: - ret = write_ldt(ptr, bytecount, func); - break; - case 2: - ret = read_default_ldt(ptr, bytecount); - break; - } - return ret; -} - -static DEFINE_SPINLOCK(host_ldt_lock); -static short dummy_list[9] = {0, -1}; -static short * host_ldt_entries = NULL; - -static void ldt_get_host_info(void) -{ - long ret; - struct ldt_entry * ldt; - short *tmp; - int i, size, k, order; - - spin_lock(&host_ldt_lock); - - if (host_ldt_entries != NULL) { - spin_unlock(&host_ldt_lock); - return; - } - host_ldt_entries = dummy_list+1; - - spin_unlock(&host_ldt_lock); - - for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) - ; - - ldt = (struct ldt_entry *) - __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); - if (ldt == NULL) { - printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " - "for host ldt\n"); - return; - } - - ret = modify_ldt(0, ldt, (1<ldt.lock); - - if (!from_mm) { - memset(&desc, 0, sizeof(desc)); - /* - * We have to initialize a clean ldt. - */ - if (proc_mm) { - /* - * If the new mm was created using proc_mm, host's - * default-ldt currently is assigned, which normally - * contains the call-gates for lcall7 and lcall27. - * To remove these gates, we simply write an empty - * entry as number 0 to the host. - */ - err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1); - } - else{ - /* - * Now we try to retrieve info about the ldt, we - * inherited from the host. All ldt-entries found - * will be reset in the following loop - */ - ldt_get_host_info(); - for (num_p=host_ldt_entries; *num_p != -1; num_p++) { - desc.entry_number = *num_p; - err = write_ldt_entry(&new_mm->id, 1, &desc, - &addr, *(num_p + 1) == -1); - if (err) - break; - } - } - new_mm->ldt.entry_count = 0; - - goto out; - } - - if (proc_mm) { - /* - * We have a valid from_mm, so we now have to copy the LDT of - * from_mm to new_mm, because using proc_mm an new mm with - * an empty/default LDT was created in new_mm() - */ - copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, - .u = - { .copy_segments = - from_mm->id.u.mm_fd } } ); - i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); - if (i != sizeof(copy)) - printk(KERN_ERR "new_mm : /proc/mm copy_segments " - "failed, err = %d\n", -i); - } - - if (!ptrace_ldt) { - /* - * Our local LDT is used to supply the data for - * modify_ldt(READLDT), if PTRACE_LDT isn't available, - * i.e., we have to use the stub for modify_ldt, which - * can't handle the big read buffer of up to 64kB. - */ - mutex_lock(&from_mm->ldt.lock); - if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) - memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, - sizeof(new_mm->ldt.u.entries)); - else { - i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-->0) { - page = __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!page) { - err = -ENOMEM; - break; - } - new_mm->ldt.u.pages[i] = - (struct ldt_entry *) page; - memcpy(new_mm->ldt.u.pages[i], - from_mm->ldt.u.pages[i], PAGE_SIZE); - } - } - new_mm->ldt.entry_count = from_mm->ldt.entry_count; - mutex_unlock(&from_mm->ldt.lock); - } - - out: - return err; -} - - -void free_ldt(struct mm_context *mm) -{ - int i; - - if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { - i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-- > 0) - free_page((long) mm->ldt.u.pages[i]); - } - mm->ldt.entry_count = 0; -} - -int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -{ - return do_modify_ldt_skas(func, ptr, bytecount); -} diff --git a/arch/um/sys-x86/mem_32.c b/arch/um/sys-x86/mem_32.c deleted file mode 100644 index 639900a..0000000 --- a/arch/um/sys-x86/mem_32.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -static struct vm_area_struct gate_vma; - -static int __init gate_vma_init(void) -{ - if (!FIXADDR_USER_START) - return 0; - - gate_vma.vm_mm = NULL; - gate_vma.vm_start = FIXADDR_USER_START; - gate_vma.vm_end = FIXADDR_USER_END; - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; - gate_vma.vm_page_prot = __P101; - - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - gate_vma.vm_flags |= VM_ALWAYSDUMP; - - return 0; -} -__initcall(gate_vma_init); - -struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return FIXADDR_USER_START ? &gate_vma : NULL; -} - -int in_gate_area_no_mm(unsigned long addr) -{ - if (!FIXADDR_USER_START) - return 0; - - if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) - return 1; - - return 0; -} - -int in_gate_area(struct mm_struct *mm, unsigned long addr) -{ - struct vm_area_struct *vma = get_gate_vma(mm); - - if (!vma) - return 0; - - return (addr >= vma->vm_start) && (addr < vma->vm_end); -} diff --git a/arch/um/sys-x86/mem_64.c b/arch/um/sys-x86/mem_64.c deleted file mode 100644 index 5465187..0000000 --- a/arch/um/sys-x86/mem_64.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/mman.h" - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == um_vdso_addr) - return "[vdso]"; - - return NULL; -} - -struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return NULL; -} - -int in_gate_area(struct mm_struct *mm, unsigned long addr) -{ - return 0; -} - -int in_gate_area_no_mm(unsigned long addr) -{ - return 0; -} diff --git a/arch/um/sys-x86/ptrace_32.c b/arch/um/sys-x86/ptrace_32.c deleted file mode 100644 index a174fde..0000000 --- a/arch/um/sys-x86/ptrace_32.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "skas.h" - -extern int arch_switch_tls(struct task_struct *to); - -void arch_switch_to(struct task_struct *to) -{ - int err = arch_switch_tls(to); - if (!err) - return; - - if (err != -EINVAL) - printk(KERN_WARNING "arch_switch_tls failed, errno %d, " - "not EINVAL\n", -err); - else - printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); -} - -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk(KERN_ERR "is_syscall : failed to read " - "instruction from 0x%lx\n", addr); - return 1; - } - } - /* int 0x80 or sysenter */ - return (instr == 0x80cd) || (instr == 0x340f); -} - -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ -#define FLAG_MASK 0x00044dd5 - -static const int reg_offsets[] = { - [EBX] = HOST_EBX, - [ECX] = HOST_ECX, - [EDX] = HOST_EDX, - [ESI] = HOST_ESI, - [EDI] = HOST_EDI, - [EBP] = HOST_EBP, - [EAX] = HOST_EAX, - [DS] = HOST_DS, - [ES] = HOST_ES, - [FS] = HOST_FS, - [GS] = HOST_GS, - [EIP] = HOST_IP, - [CS] = HOST_CS, - [EFL] = HOST_EFLAGS, - [UESP] = HOST_SP, - [SS] = HOST_SS, -}; - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ - regno >>= 2; - switch (regno) { - case EBX: - case ECX: - case EDX: - case ESI: - case EDI: - case EBP: - case EAX: - case EIP: - case UESP: - break; - case FS: - if (value && (value & 3) != 3) - return -EIO; - break; - case GS: - if (value && (value & 3) != 3) - return -EIO; - break; - case DS: - case ES: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case SS: - case CS: - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case EFL: - value &= FLAG_MASK; - child->thread.regs.regs.gp[HOST_EFLAGS] |= value; - return 0; - case ORIG_EAX: - child->thread.regs.regs.syscall = value; - return 0; - default : - panic("Bad register in putreg() : %d\n", regno); - } - child->thread.regs.regs.gp[reg_offsets[regno]] = value; - return 0; -} - -int poke_user(struct task_struct *child, long addr, long data) -{ - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if ((addr == 4) || (addr == 5)) - return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; -} - -unsigned long getreg(struct task_struct *child, int regno) -{ - unsigned long mask = ~0UL; - - regno >>= 2; - switch (regno) { - case ORIG_EAX: - return child->thread.regs.regs.syscall; - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - mask = 0xffff; - break; - case EIP: - case UESP: - case EAX: - case EBX: - case ECX: - case EDX: - case ESI: - case EDI: - case EBP: - case EFL: - break; - default: - panic("Bad register in getreg() : %d\n", regno); - } - return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; -} - -/* read the word at location addr in the USER area. */ -int peek_user(struct task_struct *child, long addr, long data) -{ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if (addr < MAX_REG_OFFSET) { - tmp = getreg(child, addr); - } - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long __user *) data); -} - -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fpx_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EIO; - void __user *datap = (void __user *) data; - switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpxregs(datap, child); - break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpxregs(datap, child); - break; - default: - ret = -EIO; - } - return ret; -} diff --git a/arch/um/sys-x86/ptrace_64.c b/arch/um/sys-x86/ptrace_64.c deleted file mode 100644 index 44e68e0..0000000 --- a/arch/um/sys-x86/ptrace_64.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#include -#include -#include -#define __FRAME_OFFSETS -#include -#include - -/* - * determines which flags the user has access to. - * 1 = access 0 = no access - */ -#define FLAG_MASK 0x44dd5UL - -static const int reg_offsets[] = -{ - [R8 >> 3] = HOST_R8, - [R9 >> 3] = HOST_R9, - [R10 >> 3] = HOST_R10, - [R11 >> 3] = HOST_R11, - [R12 >> 3] = HOST_R12, - [R13 >> 3] = HOST_R13, - [R14 >> 3] = HOST_R14, - [R15 >> 3] = HOST_R15, - [RIP >> 3] = HOST_IP, - [RSP >> 3] = HOST_SP, - [RAX >> 3] = HOST_RAX, - [RBX >> 3] = HOST_RBX, - [RCX >> 3] = HOST_RCX, - [RDX >> 3] = HOST_RDX, - [RSI >> 3] = HOST_RSI, - [RDI >> 3] = HOST_RDI, - [RBP >> 3] = HOST_RBP, - [CS >> 3] = HOST_CS, - [SS >> 3] = HOST_SS, - [FS_BASE >> 3] = HOST_FS_BASE, - [GS_BASE >> 3] = HOST_GS_BASE, - [DS >> 3] = HOST_DS, - [ES >> 3] = HOST_ES, - [FS >> 3] = HOST_FS, - [GS >> 3] = HOST_GS, - [EFLAGS >> 3] = HOST_EFLAGS, - [ORIG_RAX >> 3] = HOST_ORIG_RAX, -}; - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ -#ifdef TIF_IA32 - /* - * Some code in the 64bit emulation may not be 64bit clean. - * Don't take any chances. - */ - if (test_tsk_thread_flag(child, TIF_IA32)) - value &= 0xffffffff; -#endif - switch (regno) { - case R8: - case R9: - case R10: - case R11: - case R12: - case R13: - case R14: - case R15: - case RIP: - case RSP: - case RAX: - case RBX: - case RCX: - case RDX: - case RSI: - case RDI: - case RBP: - case ORIG_RAX: - break; - - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - - case FS_BASE: - case GS_BASE: - if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) - return -EIO; - break; - - case EFLAGS: - value &= FLAG_MASK; - child->thread.regs.regs.gp[HOST_EFLAGS] |= value; - return 0; - - default: - panic("Bad register in putreg(): %d\n", regno); - } - - child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; - return 0; -} - -int poke_user(struct task_struct *child, long addr, long data) -{ - if ((addr & 3) || addr < 0) - return -EIO; - - if (addr < MAX_REG_OFFSET) - return putreg(child, addr, data); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if ((addr == 4) || (addr == 5)) - return -EIO; - child->thread.arch.debugregs[addr] = data; - return 0; - } - return -EIO; -} - -unsigned long getreg(struct task_struct *child, int regno) -{ - unsigned long mask = ~0UL; -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - mask = 0xffffffff; -#endif - switch (regno) { - case R8: - case R9: - case R10: - case R11: - case R12: - case R13: - case R14: - case R15: - case RIP: - case RSP: - case RAX: - case RBX: - case RCX: - case RDX: - case RSI: - case RDI: - case RBP: - case ORIG_RAX: - case EFLAGS: - case FS_BASE: - case GS_BASE: - break; - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - mask = 0xffff; - break; - default: - panic("Bad register in getreg: %d\n", regno); - } - return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; -} - -int peek_user(struct task_struct *child, long addr, long data) -{ - /* read the word at location addr in the USER area. */ - unsigned long tmp; - - if ((addr & 3) || addr < 0) - return -EIO; - - tmp = 0; /* Default return condition */ - if (addr < MAX_REG_OFFSET) - tmp = getreg(child, addr); - else if ((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))) { - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long *) data); -} - -/* XXX Mostly copied from sys-i386 */ -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* - * access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk("is_syscall : failed to read instruction from " - "0x%lx\n", addr); - return 1; - } - } - /* sysenter */ - return instr == 0x050f; -} - -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - err = save_fp_registers(userspace_pid[cpu], fpregs); - if (err) - return err; - - n = copy_to_user(buf, fpregs, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return n; -} - -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - n = copy_from_user(fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EIO; - void __user *datap = (void __user *) data; - - switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; - } - - return ret; -} diff --git a/arch/um/sys-x86/ptrace_user.c b/arch/um/sys-x86/ptrace_user.c deleted file mode 100644 index 3960ca1..0000000 --- a/arch/um/sys-x86/ptrace_user.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include "ptrace_user.h" - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return 0; -} - -int ptrace_setregs(long pid, unsigned long *regs) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0) - return -errno; - return 0; -} diff --git a/arch/um/sys-x86/setjmp_32.S b/arch/um/sys-x86/setjmp_32.S deleted file mode 100644 index b766792..0000000 --- a/arch/um/sys-x86/setjmp_32.S +++ /dev/null @@ -1,58 +0,0 @@ -# -# arch/i386/setjmp.S -# -# setjmp/longjmp for the i386 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %ebx -# %esp -# %ebp -# %esi -# %edi -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: -#ifdef _REGPARM - movl %eax,%edx -#else - movl 4(%esp),%edx -#endif - popl %ecx # Return address, and adjust the stack - xorl %eax,%eax # Return value - movl %ebx,(%edx) - movl %esp,4(%edx) # Post-return %esp! - pushl %ecx # Make the call/return stack happy - movl %ebp,8(%edx) - movl %esi,12(%edx) - movl %edi,16(%edx) - movl %ecx,20(%edx) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: -#ifdef _REGPARM - xchgl %eax,%edx -#else - movl 4(%esp),%edx # jmp_ptr address - movl 8(%esp),%eax # Return value -#endif - movl (%edx),%ebx - movl 4(%edx),%esp - movl 8(%edx),%ebp - movl 12(%edx),%esi - movl 16(%edx),%edi - jmp *20(%edx) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-x86/setjmp_64.S b/arch/um/sys-x86/setjmp_64.S deleted file mode 100644 index 45f547b..0000000 --- a/arch/um/sys-x86/setjmp_64.S +++ /dev/null @@ -1,54 +0,0 @@ -# -# arch/x86_64/setjmp.S -# -# setjmp/longjmp for the x86-64 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %rbx -# %rsp (post-return) -# %rbp -# %r12 -# %r13 -# %r14 -# %r15 -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - pop %rsi # Return address, and adjust the stack - xorl %eax,%eax # Return value - movq %rbx,(%rdi) - movq %rsp,8(%rdi) # Post-return %rsp! - push %rsi # Make the call/return stack happy - movq %rbp,16(%rdi) - movq %r12,24(%rdi) - movq %r13,32(%rdi) - movq %r14,40(%rdi) - movq %r15,48(%rdi) - movq %rsi,56(%rdi) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - movl %esi,%eax # Return value (int) - movq (%rdi),%rbx - movq 8(%rdi),%rsp - movq 16(%rdi),%rbp - movq 24(%rdi),%r12 - movq 32(%rdi),%r13 - movq 40(%rdi),%r14 - movq 48(%rdi),%r15 - jmp *56(%rdi) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp.h b/arch/um/sys-x86/shared/sysdep/archsetjmp.h deleted file mode 100644 index ff7766d..0000000 --- a/arch/um/sys-x86/shared/sysdep/archsetjmp.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "archsetjmp_32.h" -#else -#include "archsetjmp_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h b/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h deleted file mode 100644 index 0f31208..0000000 --- a/arch/um/sys-x86/shared/sysdep/archsetjmp_32.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/um/include/sysdep-i386/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int __ebx; - unsigned int __esp; - unsigned int __ebp; - unsigned int __esi; - unsigned int __edi; - unsigned int __eip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __eip -#define JB_SP __esp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h b/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h deleted file mode 100644 index 2af8f12..0000000 --- a/arch/um/sys-x86/shared/sysdep/archsetjmp_64.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/um/include/sysdep-x86_64/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; - unsigned long __rbp; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __rip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __rip -#define JB_SP __rsp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo.h b/arch/um/sys-x86/shared/sysdep/faultinfo.h deleted file mode 100644 index 862ecb1..0000000 --- a/arch/um/sys-x86/shared/sysdep/faultinfo.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "faultinfo_32.h" -#else -#include "faultinfo_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_32.h b/arch/um/sys-x86/shared/sysdep/faultinfo_32.h deleted file mode 100644 index a26086b..0000000 --- a/arch/um/sys-x86/shared/sysdep/faultinfo_32.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Author: Bodo Stroesser - * Licensed under the GPL - */ - -#ifndef __FAULTINFO_I386_H -#define __FAULTINFO_I386_H - -/* this structure contains the full arch-specific faultinfo - * from the traps. - * On i386, ptrace_faultinfo unfortunately doesn't provide - * all the info, since trap_no is missing. - * All common elements are defined at the same position in - * both structures, thus making it easy to copy the - * contents without knowledge about the structure elements. - */ -struct faultinfo { - int error_code; /* in ptrace_faultinfo misleadingly called is_write */ - unsigned long cr2; /* in ptrace_faultinfo called addr */ - int trap_no; /* missing in ptrace_faultinfo */ -}; - -#define FAULT_WRITE(fi) ((fi).error_code & 2) -#define FAULT_ADDRESS(fi) ((fi).cr2) - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) - -#define PTRACE_FULL_FAULTINFO 0 - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/faultinfo_64.h b/arch/um/sys-x86/shared/sysdep/faultinfo_64.h deleted file mode 100644 index f811cbe..0000000 --- a/arch/um/sys-x86/shared/sysdep/faultinfo_64.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Author: Bodo Stroesser - * Licensed under the GPL - */ - -#ifndef __FAULTINFO_X86_64_H -#define __FAULTINFO_X86_64_H - -/* this structure contains the full arch-specific faultinfo - * from the traps. - * On i386, ptrace_faultinfo unfortunately doesn't provide - * all the info, since trap_no is missing. - * All common elements are defined at the same position in - * both structures, thus making it easy to copy the - * contents without knowledge about the structure elements. - */ -struct faultinfo { - int error_code; /* in ptrace_faultinfo misleadingly called is_write */ - unsigned long cr2; /* in ptrace_faultinfo called addr */ - int trap_no; /* missing in ptrace_faultinfo */ -}; - -#define FAULT_WRITE(fi) ((fi).error_code & 2) -#define FAULT_ADDRESS(fi) ((fi).cr2) - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* No broken SKAS API, which doesn't pass trap_no, here. */ -#define SEGV_MAYBE_FIXABLE(fi) 0 - -#define PTRACE_FULL_FAULTINFO 1 - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt.h b/arch/um/sys-x86/shared/sysdep/host_ldt.h deleted file mode 100644 index 94518b3..0000000 --- a/arch/um/sys-x86/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "host_ldt_32.h" -#else -#include "host_ldt_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt_32.h b/arch/um/sys-x86/shared/sysdep/host_ldt_32.h deleted file mode 100644 index 0953cc4..0000000 --- a/arch/um/sys-x86/shared/sysdep/host_ldt_32.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ASM_HOST_LDT_I386_H -#define __ASM_HOST_LDT_I386_H - -#include - -/* - * macros stolen from include/asm-i386/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/host_ldt_64.h b/arch/um/sys-x86/shared/sysdep/host_ldt_64.h deleted file mode 100644 index e8b1be1..0000000 --- a/arch/um/sys-x86/shared/sysdep/host_ldt_64.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_HOST_LDT_X86_64_H -#define __ASM_HOST_LDT_X86_64_H - -#include - -/* - * macros stolen from include/asm-x86_64/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -/* Don't allow setting of the lm bit. It is useless anyways because - * 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 && \ - (info)->lm == 0) - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86/shared/sysdep/kernel-offsets.h deleted file mode 100644 index 5868526..0000000 --- a/arch/um/sys-x86/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define STR(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include -} diff --git a/arch/um/sys-x86/shared/sysdep/mcontext.h b/arch/um/sys-x86/shared/sysdep/mcontext.h deleted file mode 100644 index b724c54..0000000 --- a/arch/um/sys-x86/shared/sysdep/mcontext.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_X86_H -#define __SYS_SIGCONTEXT_X86_H - -extern void get_regs_from_mc(struct uml_pt_regs *, mcontext_t *); - -#ifdef __i386__ - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->cr2; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#else - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->gregs[REG_CR2]; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#endif - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace.h b/arch/um/sys-x86/shared/sysdep/ptrace.h deleted file mode 100644 index 711b162..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "ptrace_32.h" -#else -#include "ptrace_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_32.h b/arch/um/sys-x86/shared/sysdep/ptrace_32.h deleted file mode 100644 index ce77fa1..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace_32.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_H -#define __SYSDEP_I386_PTRACE_H - -#include -#include "sysdep/faultinfo.h" - -#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) -#define MAX_REG_OFFSET (UM_FRAME_SIZE) - -static inline void update_debugregs(int seq) {} - -/* syscall emulation path in ptrace */ - -#ifndef PTRACE_SYSEMU -#define PTRACE_SYSEMU 31 -#endif - -void set_using_sysemu(int value); -int get_using_sysemu(void); -extern int sysemu_supported; - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_EAX(r) ((r)[HOST_EAX]) -#define REGS_EBX(r) ((r)[HOST_EBX]) -#define REGS_ECX(r) ((r)[HOST_ECX]) -#define REGS_EDX(r) ((r)[HOST_EDX]) -#define REGS_ESI(r) ((r)[HOST_ESI]) -#define REGS_EDI(r) ((r)[HOST_EDI]) -#define REGS_EBP(r) ((r)[HOST_EBP]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_SS(r) ((r)[HOST_SS]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) - -#ifndef PTRACE_SYSEMU_SINGLESTEP -#define PTRACE_SYSEMU_SINGLESTEP 32 -#endif - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FPX_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_EAX(r) REGS_EAX((r)->gp) -#define UPT_EBX(r) REGS_EBX((r)->gp) -#define UPT_ECX(r) REGS_ECX((r)->gp) -#define UPT_EDX(r) REGS_EDX((r)->gp) -#define UPT_ESI(r) REGS_ESI((r)->gp) -#define UPT_EDI(r) REGS_EDI((r)->gp) -#define UPT_EBP(r) REGS_EBP((r)->gp) -#define UPT_ORIG_EAX(r) ((r)->syscall) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) - -#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) -#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) -#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) -#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) -#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) -#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) -#define UPT_SYSCALL_RET(r) UPT_EAX(r) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -extern void arch_init_registers(int pid); - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_64.h b/arch/um/sys-x86/shared/sysdep/ptrace_64.h deleted file mode 100644 index 866fe7e..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace_64.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_H -#define __SYSDEP_X86_64_PTRACE_H - -#include -#include "sysdep/faultinfo.h" - -#define MAX_REG_OFFSET (UM_FRAME_SIZE) -#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) - -#define REGS_RBX(r) ((r)[HOST_RBX]) -#define REGS_RCX(r) ((r)[HOST_RCX]) -#define REGS_RDX(r) ((r)[HOST_RDX]) -#define REGS_RSI(r) ((r)[HOST_RSI]) -#define REGS_RDI(r) ((r)[HOST_RDI]) -#define REGS_RBP(r) ((r)[HOST_RBP]) -#define REGS_RAX(r) ((r)[HOST_RAX]) -#define REGS_R8(r) ((r)[HOST_R8]) -#define REGS_R9(r) ((r)[HOST_R9]) -#define REGS_R10(r) ((r)[HOST_R10]) -#define REGS_R11(r) ((r)[HOST_R11]) -#define REGS_R12(r) ((r)[HOST_R12]) -#define REGS_R13(r) ((r)[HOST_R13]) -#define REGS_R14(r) ((r)[HOST_R14]) -#define REGS_R15(r) ((r)[HOST_R15]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_SS(r) ((r)[HOST_SS]) - -#define HOST_FS_BASE 21 -#define HOST_GS_BASE 22 -#define HOST_DS 23 -#define HOST_ES 24 -#define HOST_FS 25 -#define HOST_GS 26 - -/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these - * are already defined for kernel code, but not for userspace code. - */ -#ifndef FS_BASE -/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, - * which is what x86_64 ptrace actually uses. - */ -#define FS_BASE (HOST_FS_BASE * sizeof(long)) -#define GS_BASE (HOST_GS_BASE * sizeof(long)) -#define DS (HOST_DS * sizeof(long)) -#define ES (HOST_ES * sizeof(long)) -#define FS (HOST_FS * sizeof(long)) -#define GS (HOST_GS * sizeof(long)) -#endif - -#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) -#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) - -#define REGS_FAULT_ADDR(r) ((r)->fault_addr) - -#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) - -#define REGS_TRAP(r) ((r)->trap_type) - -#define REGS_ERR(r) ((r)->fault_type) - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FP_SIZE]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_RBX(r) REGS_RBX((r)->gp) -#define UPT_RCX(r) REGS_RCX((r)->gp) -#define UPT_RDX(r) REGS_RDX((r)->gp) -#define UPT_RSI(r) REGS_RSI((r)->gp) -#define UPT_RDI(r) REGS_RDI((r)->gp) -#define UPT_RBP(r) REGS_RBP((r)->gp) -#define UPT_RAX(r) REGS_RAX((r)->gp) -#define UPT_R8(r) REGS_R8((r)->gp) -#define UPT_R9(r) REGS_R9((r)->gp) -#define UPT_R10(r) REGS_R10((r)->gp) -#define UPT_R11(r) REGS_R11((r)->gp) -#define UPT_R12(r) REGS_R12((r)->gp) -#define UPT_R13(r) REGS_R13((r)->gp) -#define UPT_R14(r) REGS_R14((r)->gp) -#define UPT_R15(r) REGS_R15((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp) - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) - -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_SYSCALL_NR(r) ((r)->syscall) -#define UPT_SYSCALL_RET(r) UPT_RAX(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -#define UPT_SYSCALL_ARG1(r) UPT_RDI(r) -#define UPT_SYSCALL_ARG2(r) UPT_RSI(r) -#define UPT_SYSCALL_ARG3(r) UPT_RDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_R10(r) -#define UPT_SYSCALL_ARG5(r) UPT_R8(r) -#define UPT_SYSCALL_ARG6(r) UPT_R9(r) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -static inline void arch_init_registers(int pid) -{ -} - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user.h b/arch/um/sys-x86/shared/sysdep/ptrace_user.h deleted file mode 100644 index a92f883..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "ptrace_user_32.h" -#else -#include "ptrace_user_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h b/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h deleted file mode 100644 index 9d88a79..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace_user_32.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_USER_H__ -#define __SYSDEP_I386_PTRACE_USER_H__ - -#include -#include -#include -#include - -#define PT_OFFSET(r) ((r) * sizeof(long)) - -#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) -#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) - -#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) - -#define REGS_IP_INDEX EIP -#define REGS_SP_INDEX UESP - -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h b/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h deleted file mode 100644 index 2f1b6e3..0000000 --- a/arch/um/sys-x86/shared/sysdep/ptrace_user_64.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_USER_H__ -#define __SYSDEP_X86_64_PTRACE_USER_H__ - -#define __FRAME_OFFSETS -#include -#include -#include -#undef __FRAME_OFFSETS -#include - -#define PT_INDEX(off) ((off) / sizeof(unsigned long)) - -#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) -#define PT_SYSCALL_NR_OFFSET (ORIG_RAX) - -#define PT_SYSCALL_RET_OFFSET (RAX) - -/* - * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though - * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the - * 2.4 name and value for 2.4 host compatibility. - */ -#ifndef PTRACE_OLDSETOPTIONS -#define PTRACE_OLDSETOPTIONS 21 -#endif - -#define REGS_IP_INDEX PT_INDEX(RIP) -#define REGS_SP_INDEX PT_INDEX(RSP) - -#define FP_SIZE (HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86/shared/sysdep/skas_ptrace.h deleted file mode 100644 index 453febe..0000000 --- a/arch/um/sys-x86/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_SKAS_PTRACE_H -#define __SYSDEP_X86_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/stub.h b/arch/um/sys-x86/shared/sysdep/stub.h deleted file mode 100644 index bd161e3..0000000 --- a/arch/um/sys-x86/shared/sysdep/stub.h +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include "as-layout.h" -#include "stub-data.h" - -#ifdef __i386__ -#include "stub_32.h" -#else -#include "stub_64.h" -#endif - -extern void stub_segv_handler(int, siginfo_t *, void *); -extern void stub_clone_handler(void); diff --git a/arch/um/sys-x86/shared/sysdep/stub_32.h b/arch/um/sys-x86/shared/sysdep/stub_32.h deleted file mode 100644 index 51fd256..0000000 --- a/arch/um/sys-x86/shared/sysdep/stub_32.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include - -#define STUB_SYSCALL_RET EAX -#define STUB_MMAP_NR __NR_mmap2 -#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); - - return ret; -} - -static inline long stub_syscall1(long syscall, long arg1) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2)); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3)); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4)); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(int fd, unsigned long offset) -{ - __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" - "movl %7, %%ebx ; movl %%eax, (%%ebx)" - : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), - "c" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED), "D" (fd), - "a" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : "memory"); -} - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/stub_64.h b/arch/um/sys-x86/shared/sysdep/stub_64.h deleted file mode 100644 index 994df93..0000000 --- a/arch/um/sys-x86/shared/sysdep/stub_64.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include - -#define STUB_SYSCALL_RET PT_INDEX(RAX) -#define STUB_MMAP_NR __NR_mmap -#define MMAP_OFFSET(o) (o) - -#define __syscall_clobber "r11","rcx","memory" -#define __syscall "syscall" - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3) - : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4) - : __syscall_clobber, "r10" ); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4), "g" (arg5) - : __syscall_clobber, "r10", "r8" ); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(long fd, unsigned long offset) -{ - __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " - "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " - "movq %%rax, (%%rbx)": - : "a" (STUB_MMAP_NR), "D" (STUB_DATA), - "S" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "g" (MAP_FIXED | MAP_SHARED), "g" (fd), - "g" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : __syscall_clobber, "r10", "r8", "r9" ); -} - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/syscalls.h b/arch/um/sys-x86/shared/sysdep/syscalls.h deleted file mode 100644 index bd9a89b..0000000 --- a/arch/um/sys-x86/shared/sysdep/syscalls.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "syscalls_32.h" -#else -#include "syscalls_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/syscalls_32.h b/arch/um/sys-x86/shared/sysdep/syscalls_32.h deleted file mode 100644 index 05cb796..0000000 --- a/arch/um/sys-x86/shared/sysdep/syscalls_32.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "asm/unistd.h" -#include "sysdep/ptrace.h" - -typedef long syscall_handler_t(struct pt_regs); - -/* Not declared on x86, incompatible declarations on x86_64, so these have - * to go here rather than in sys_call_table.c - */ -extern syscall_handler_t sys_rt_sigaction; - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - ((long (*)(struct syscall_args)) \ - (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) diff --git a/arch/um/sys-x86/shared/sysdep/syscalls_64.h b/arch/um/sys-x86/shared/sysdep/syscalls_64.h deleted file mode 100644 index 8a7d5e1..0000000 --- a/arch/um/sys-x86/shared/sysdep/syscalls_64.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SYSCALLS_H__ -#define __SYSDEP_X86_64_SYSCALLS_H__ - -#include -#include - -typedef long syscall_handler_t(void); - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - (((long (*)(long, long, long, long, long, long)) \ - (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ - UPT_SYSCALL_ARG2(®s->regs), \ - UPT_SYSCALL_ARG3(®s->regs), \ - UPT_SYSCALL_ARG4(®s->regs), \ - UPT_SYSCALL_ARG5(®s->regs), \ - UPT_SYSCALL_ARG6(®s->regs))) - -extern long old_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff); -extern syscall_handler_t sys_modify_ldt; -extern syscall_handler_t sys_arch_prctl; - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/tls.h b/arch/um/sys-x86/shared/sysdep/tls.h deleted file mode 100644 index 4d8f752..0000000 --- a/arch/um/sys-x86/shared/sysdep/tls.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "tls_32.h" -#else -#include "tls_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/tls_32.h b/arch/um/sys-x86/shared/sysdep/tls_32.h deleted file mode 100644 index 3455075..0000000 --- a/arch/um/sys-x86/shared/sysdep/tls_32.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ - -#define GDT_ENTRY_TLS_MIN_I386 6 -#define GDT_ENTRY_TLS_MIN_X86_64 12 - -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86/shared/sysdep/tls_64.h b/arch/um/sys-x86/shared/sysdep/tls_64.h deleted file mode 100644 index 18c000d..0000000 --- a/arch/um/sys-x86/shared/sysdep/tls_64.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int lm:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86/signal_32.c b/arch/um/sys-x86/signal_32.c deleted file mode 100644 index bcbfb0d..0000000 --- a/arch/um/sys-x86/signal_32.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include "frame_kern.h" -#include "skas.h" - -/* - * FPU tag word conversions. - */ - -static inline unsigned short twd_i387_to_fxsr(unsigned short twd) -{ - unsigned int tmp; /* to avoid 16 bit prefixes in the code */ - - /* Transform each pair of bits into 01 (valid) or 00 (empty) */ - tmp = ~twd; - tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ - /* and move the valid bits to the lower byte. */ - tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ - tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ - tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ - return tmp; -} - -static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) -{ - struct _fpxreg *st = NULL; - unsigned long twd = (unsigned long) fxsave->twd; - unsigned long tag; - unsigned long ret = 0xffff0000; - int i; - -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16) - - for (i = 0; i < 8; i++) { - if (twd & 0x1) { - st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); - - switch (st->exponent & 0x7fff) { - case 0x7fff: - tag = 2; /* Special */ - break; - case 0x0000: - if ( !st->significand[0] && - !st->significand[1] && - !st->significand[2] && - !st->significand[3] ) { - tag = 1; /* Zero */ - } else { - tag = 2; /* Special */ - } - break; - default: - if (st->significand[3] & 0x8000) { - tag = 0; /* Valid */ - } else { - tag = 2; /* Special */ - } - break; - } - } else { - tag = 3; /* Empty */ - } - ret |= (tag << (2 * i)); - twd = twd >> 1; - } - return ret; -} - -static int convert_fxsr_to_user(struct _fpstate __user *buf, - struct user_fxsr_struct *fxsave) -{ - unsigned long env[7]; - struct _fpreg __user *to; - struct _fpxreg *from; - int i; - - env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; - env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; - env[2] = twd_fxsr_to_i387(fxsave); - env[3] = fxsave->fip; - env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); - env[5] = fxsave->foo; - env[6] = fxsave->fos; - - if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) - return 1; - - to = &buf->_st[0]; - from = (struct _fpxreg *) &fxsave->st_space[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long __user *t = (unsigned long __user *)to; - unsigned long *f = (unsigned long *)from; - - if (__put_user(*f, t) || - __put_user(*(f + 1), t + 1) || - __put_user(from->exponent, &to->exponent)) - return 1; - } - return 0; -} - -static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, - struct _fpstate __user *buf) -{ - unsigned long env[7]; - struct _fpxreg *to; - struct _fpreg __user *from; - int i; - - if (copy_from_user( env, buf, 7 * sizeof(long))) - return 1; - - fxsave->cwd = (unsigned short)(env[0] & 0xffff); - fxsave->swd = (unsigned short)(env[1] & 0xffff); - fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); - fxsave->fip = env[3]; - fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); - fxsave->fcs = (env[4] & 0xffff); - fxsave->foo = env[5]; - fxsave->fos = env[6]; - - to = (struct _fpxreg *) &fxsave->st_space[0]; - from = &buf->_st[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long *t = (unsigned long *)to; - unsigned long __user *f = (unsigned long __user *)from; - - if (__get_user(*t, f) || - __get_user(*(t + 1), f + 1) || - __get_user(to->exponent, &from->exponent)) - return 1; - } - return 0; -} - -extern int have_fpx_regs; - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from) -{ - struct sigcontext sc; - int err, pid; - - err = copy_from_user(&sc, from, sizeof(sc)); - if (err) - return err; - - pid = userspace_pid[current_thread_info()->cpu]; - -#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname - - GETREG(GS, gs); - GETREG(FS, fs); - GETREG(ES, es); - GETREG(DS, ds); - GETREG(EDI, di); - GETREG(ESI, si); - GETREG(EBP, bp); - GETREG(SP, sp); - GETREG(EBX, bx); - GETREG(EDX, dx); - GETREG(ECX, cx); - GETREG(EAX, ax); - GETREG(IP, ip); - GETREG(CS, cs); - GETREG(EFLAGS, flags); - GETREG(SS, ss); - -#undef GETREG - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = copy_from_user(&fpx, - &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0], - sizeof(struct user_fxsr_struct)); - if (err) - return 1; - - err = convert_fxsr_from_user(&fpx, sc.fpstate); - if (err) - return 1; - - err = restore_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fpx_registers failed, errno = %d\n", - -err); - return 1; - } - } else { - struct user_i387_struct fp; - - err = copy_from_user(&fp, sc.fpstate, - sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(pid, (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long sp) -{ - struct sigcontext sc; - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - int err, pid; - memset(&sc, 0, sizeof(struct sigcontext)); - - sc.gs = REGS_GS(regs->regs.gp); - sc.fs = REGS_FS(regs->regs.gp); - sc.es = REGS_ES(regs->regs.gp); - sc.ds = REGS_DS(regs->regs.gp); - sc.di = REGS_EDI(regs->regs.gp); - sc.si = REGS_ESI(regs->regs.gp); - sc.bp = REGS_EBP(regs->regs.gp); - sc.sp = sp; - sc.bx = REGS_EBX(regs->regs.gp); - sc.dx = REGS_EDX(regs->regs.gp); - sc.cx = REGS_ECX(regs->regs.gp); - sc.ax = REGS_EAX(regs->regs.gp); - sc.ip = REGS_IP(regs->regs.gp); - sc.cs = REGS_CS(regs->regs.gp); - sc.flags = REGS_EFLAGS(regs->regs.gp); - sc.sp_at_signal = regs->regs.gp[UESP]; - sc.ss = regs->regs.gp[SS]; - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); - sc.fpstate = to_fp; - - pid = userspace_pid[current_thread_info()->cpu]; - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = save_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0){ - printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " - "failed, errno = %d\n", err); - return 1; - } - - err = convert_fxsr_to_user(to_fp, &fpx); - if (err) - return 1; - - err |= __put_user(fpx.swd, &to_fp->status); - err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic); - if (err) - return 1; - - if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, - sizeof(struct user_fxsr_struct))) - return 1; - } - else { - struct user_i387_struct fp; - - err = save_fp_registers(pid, (unsigned long *) &fp); - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - } - - return copy_to_user(to, &sc, sizeof(sc)); -} - -static int copy_ucontext_to_user(struct ucontext __user *uc, - struct _fpstate __user *fp, sigset_t *set, - unsigned long sp) -{ - int err = 0; - - err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); - err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); - err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); - err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); - err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return err; -} - -struct sigframe -{ - char __user *pretcode; - int sig; - struct sigcontext sc; - struct _fpstate fpstate; - unsigned long extramask[_NSIG_WORDS-1]; - char retcode[8]; -}; - -struct rt_sigframe -{ - char __user *pretcode; - int sig; - struct siginfo __user *pinfo; - void __user *puc; - struct siginfo info; - struct ucontext uc; - struct _fpstate fpstate; - char retcode[8]; -}; - -int setup_signal_stack_sc(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - sigset_t *mask) -{ - struct sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ - stack_top = ((stack_top + 4) & -16UL) - 4; - frame = (struct sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); - err |= __put_user(mask->sig[0], &frame->sc.oldmask); - if (_NSIG_WORDS > 1) - err |= __copy_to_user(&frame->extramask, &mask->sig[1], - sizeof(frame->extramask)); - - /* - * This is popl %eax ; movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); - err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); - - if (err) - goto err; - - PT_REGS_SP(regs) = (unsigned long) frame; - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) 0; - PT_REGS_ECX(regs) = (unsigned long) 0; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - siginfo_t *info, sigset_t *mask) -{ - struct rt_sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - stack_top &= -8UL; - frame = (struct rt_sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* See comment above about why this is here */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, - save_sp); - - /* - * This is movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); - err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); - - if (err) - goto err; - - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) &frame->info; - PT_REGS_ECX(regs) = (unsigned long) &frame->uc; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -long sys_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); - sigset_t set; - struct sigcontext __user *sc = &frame->sc; - unsigned long __user *oldmask = &sc->oldmask; - unsigned long __user *extramask = frame->extramask; - int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - - if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || - copy_from_user(&set.sig[1], extramask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, sc)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} - -long sys_rt_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *) (sp - 4); - sigset_t set; - struct ucontext __user *uc = &frame->uc; - int sig_size = _NSIG_WORDS * sizeof(unsigned long); - - if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-x86/signal_64.c b/arch/um/sys-x86/signal_64.c deleted file mode 100644 index 255b2ca..0000000 --- a/arch/um/sys-x86/signal_64.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "frame_kern.h" -#include "skas.h" - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from) -{ - struct sigcontext sc; - struct user_i387_struct fp; - void __user *buf; - int err; - - err = copy_from_user(&sc, from, sizeof(sc)); - if (err) - return err; - -#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname - - GETREG(R8, r8); - GETREG(R9, r9); - GETREG(R10, r10); - GETREG(R11, r11); - GETREG(R12, r12); - GETREG(R13, r13); - GETREG(R14, r14); - GETREG(R15, r15); - GETREG(RDI, di); - GETREG(RSI, si); - GETREG(RBP, bp); - GETREG(RBX, bx); - GETREG(RDX, dx); - GETREG(RAX, ax); - GETREG(RCX, cx); - GETREG(SP, sp); - GETREG(IP, ip); - GETREG(EFLAGS, flags); - GETREG(CS, cs); -#undef GETREG - - buf = sc.fpstate; - - err = copy_from_user(&fp, buf, sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long mask, unsigned long sp) -{ - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - struct sigcontext sc; - struct user_i387_struct fp; - int err = 0; - memset(&sc, 0, sizeof(struct sigcontext)); - -#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno] - - PUTREG(RDI, di); - PUTREG(RSI, si); - PUTREG(RBP, bp); - /* - * Must use original RSP, which is passed in, rather than what's in - * signal frame. - */ - sc.sp = sp; - PUTREG(RBX, bx); - PUTREG(RDX, dx); - PUTREG(RCX, cx); - PUTREG(RAX, ax); - PUTREG(R8, r8); - PUTREG(R9, r9); - PUTREG(R10, r10); - PUTREG(R11, r11); - PUTREG(R12, r12); - PUTREG(R13, r13); - PUTREG(R14, r14); - PUTREG(R15, r15); - PUTREG(CS, cs); /* XXX x86_64 doesn't do this */ - - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - PUTREG(IP, ip); - PUTREG(EFLAGS, flags); -#undef PUTREG - - sc.oldmask = mask; - - err = copy_to_user(to, &sc, sizeof(struct sigcontext)); - if (err) - return 1; - - err = save_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " - "failed, errno = %d\n", -err); - return 1; - } - - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - - return err; -} - -struct rt_sigframe -{ - char __user *pretcode; - struct ucontext uc; - struct siginfo info; - struct _fpstate fpstate; -}; - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs * regs, - siginfo_t *info, sigset_t *set) -{ - struct rt_sigframe __user *frame; - unsigned long save_sp = PT_REGS_RSP(regs); - int err = 0; - struct task_struct *me = current; - - frame = (struct rt_sigframe __user *) - round_down(stack_top - sizeof(struct rt_sigframe), 16); - /* Subtract 128 for a red zone and 8 for proper alignment */ - frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto out; - - if (ka->sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto out; - } - - /* - * Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_RSP(regs) = (unsigned long) frame; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(save_sp), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, - set->sig[0], save_sp); - err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); - if (sizeof(*set) == 16) { - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); - } - else - err |= __copy_to_user(&frame->uc.uc_sigmask, set, - sizeof(*set)); - - /* - * Set up to return from userspace. If provided, use a stub - * already in userspace. - */ - /* x86-64 should always use SA_RESTORER. */ - if (ka->sa.sa_flags & SA_RESTORER) - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); - else - /* could use a vstub here */ - goto restore_sp; - - if (err) - goto restore_sp; - - /* Set up registers for signal handler */ - { - struct exec_domain *ed = current_thread_info()->exec_domain; - if (unlikely(ed && ed->signal_invmap && sig < 32)) - sig = ed->signal_invmap[sig]; - } - - PT_REGS_RDI(regs) = sig; - /* In case the signal handler was declared without prototypes */ - PT_REGS_RAX(regs) = 0; - - /* - * This also works for non SA_SIGINFO handlers because they expect the - * next argument after the signal number on the stack. - */ - PT_REGS_RSI(regs) = (unsigned long) &frame->info; - PT_REGS_RDX(regs) = (unsigned long) &frame->uc; - PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; - out: - return err; - -restore_sp: - PT_REGS_RSP(regs) = save_sp; - return err; -} - -long sys_rt_sigreturn(struct pt_regs *regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *)(sp - 8); - struct ucontext __user *uc = &frame->uc; - sigset_t set; - - if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-x86/stub_32.S b/arch/um/sys-x86/stub_32.S deleted file mode 100644 index 54a36ec..0000000 --- a/arch/um/sys-x86/stub_32.S +++ /dev/null @@ -1,51 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" - - .globl batch_syscall_stub -batch_syscall_stub: - /* load pointer to first operation */ - mov $(STUB_DATA+8), %esp - -again: - /* load length of additional data */ - mov 0x0(%esp), %eax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %eax, STUB_DATA+4 - cmpl $0, %eax - jz done - - /* save current pointer */ - mov %esp, STUB_DATA+4 - - /* skip additional data */ - add %eax, %esp - - /* load syscall-# */ - pop %eax - - /* load syscall params */ - pop %ebx - pop %ecx - pop %edx - pop %esi - pop %edi - pop %ebp - - /* execute syscall */ - int $0x80 - - /* check return value */ - pop %ebx - cmp %ebx, %eax - je again - -done: - /* save return value */ - mov %eax, STUB_DATA - - /* stop */ - int3 diff --git a/arch/um/sys-x86/stub_64.S b/arch/um/sys-x86/stub_64.S deleted file mode 100644 index 20e4a96..0000000 --- a/arch/um/sys-x86/stub_64.S +++ /dev/null @@ -1,66 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" -syscall_stub: - syscall - /* We don't have 64-bit constants, so this constructs the address - * we need. - */ - movq $(STUB_DATA >> 32), %rbx - salq $32, %rbx - movq $(STUB_DATA & 0xffffffff), %rcx - or %rcx, %rbx - movq %rax, (%rbx) - int3 - - .globl batch_syscall_stub -batch_syscall_stub: - mov $(STUB_DATA >> 32), %rbx - sal $32, %rbx - mov $(STUB_DATA & 0xffffffff), %rax - or %rax, %rbx - /* load pointer to first operation */ - mov %rbx, %rsp - add $0x10, %rsp -again: - /* load length of additional data */ - mov 0x0(%rsp), %rax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %rax, 8(%rbx) - cmp $0, %rax - jz done - - /* save current pointer */ - mov %rsp, 8(%rbx) - - /* skip additional data */ - add %rax, %rsp - - /* load syscall-# */ - pop %rax - - /* load syscall params */ - pop %rdi - pop %rsi - pop %rdx - pop %r10 - pop %r8 - pop %r9 - - /* execute syscall */ - syscall - - /* check return value */ - pop %rcx - cmp %rcx, %rax - je again - -done: - /* save return value */ - mov %rax, (%rbx) - - /* stop */ - int3 diff --git a/arch/um/sys-x86/stub_segv.c b/arch/um/sys-x86/stub_segv.c deleted file mode 100644 index b7450bd..0000000 --- a/arch/um/sys-x86/stub_segv.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/stub.h" -#include "sysdep/faultinfo.h" -#include "sysdep/mcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig, siginfo_t *info, void *p) -{ - struct ucontext *uc = p; - - GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA), - &uc->uc_mcontext); - trap_myself(); -} - diff --git a/arch/um/sys-x86/sys_call_table_32.S b/arch/um/sys-x86/sys_call_table_32.S deleted file mode 100644 index de274071..0000000 --- a/arch/um/sys-x86/sys_call_table_32.S +++ /dev/null @@ -1,28 +0,0 @@ -#include -/* Steal i386 syscall table for our purposes, but with some slight changes.*/ - -#define sys_iopl sys_ni_syscall -#define sys_ioperm sys_ni_syscall - -#define sys_vm86old sys_ni_syscall -#define sys_vm86 sys_ni_syscall - -#define old_mmap sys_old_mmap - -#define ptregs_fork sys_fork -#define ptregs_execve sys_execve -#define ptregs_iopl sys_iopl -#define ptregs_vm86old sys_vm86old -#define ptregs_sigreturn sys_sigreturn -#define ptregs_clone sys_clone -#define ptregs_vm86 sys_vm86 -#define ptregs_rt_sigreturn sys_rt_sigreturn -#define ptregs_sigaltstack sys_sigaltstack -#define ptregs_vfork sys_vfork - -.section .rodata,"a" - -#include "../../x86/kernel/syscall_table_32.S" - -ENTRY(syscall_table_size) -.long .-sys_call_table diff --git a/arch/um/sys-x86/sys_call_table_64.c b/arch/um/sys-x86/sys_call_table_64.c deleted file mode 100644 index f46de82..0000000 --- a/arch/um/sys-x86/sys_call_table_64.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c - * with some changes for UML. - */ - -#include -#include -#include - -#define __NO_STUBS - -/* - * Below you can see, in terms of #define's, the differences between the x86-64 - * and the UML syscall table. - */ - -/* Not going to be implemented by UML, since we have no hardware. */ -#define stub_iopl sys_ni_syscall -#define sys_ioperm sys_ni_syscall - -/* - * The UML TLS problem. Note that x86_64 does not implement this, so the below - * is needed only for the ia32 compatibility. - */ - -/* On UML we call it this way ("old" means it's not mmap2) */ -#define sys_mmap old_mmap - -#define stub_clone sys_clone -#define stub_fork sys_fork -#define stub_vfork sys_vfork -#define stub_execve sys_execve -#define stub_rt_sigsuspend sys_rt_sigsuspend -#define stub_sigaltstack sys_sigaltstack -#define stub_rt_sigreturn sys_rt_sigreturn - -#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; -#undef _ASM_X86_UNISTD_64_H -#include "../../x86/include/asm/unistd_64.h" - -#undef __SYSCALL -#define __SYSCALL(nr, sym) [ nr ] = sym, -#undef _ASM_X86_UNISTD_64_H - -typedef void (*sys_call_ptr_t)(void); - -extern void sys_ni_syscall(void); - -/* - * We used to have a trick here which made sure that holes in the - * x86_64 table were filled in with sys_ni_syscall, but a comment in - * unistd_64.h says that holes aren't allowed, so the trick was - * removed. - * The trick looked like this - * [0 ... UM_NR_syscall_max] = &sys_ni_syscall - * before including unistd_64.h - the later initializations overwrote - * the sys_ni_syscall filler. - */ - -sys_call_ptr_t sys_call_table[] __cacheline_aligned = { -#include "../../x86/include/asm/unistd_64.h" -}; - -int syscall_table_size = sizeof(sys_call_table); diff --git a/arch/um/sys-x86/syscalls_32.c b/arch/um/sys-x86/syscalls_32.c deleted file mode 100644 index 70ca357..0000000 --- a/arch/um/sys-x86/syscalls_32.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "linux/shm.h" -#include "linux/ipc.h" -#include "linux/syscalls.h" -#include "asm/mman.h" -#include "asm/uaccess.h" -#include "asm/unistd.h" - -/* - * The prototype on i386 is: - * - * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) - * - * and the "newtls" arg. on i386 is read by copy_thread directly from the - * register saved on the stack. - */ -long sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tid, void *newtls, int __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -long sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} diff --git a/arch/um/sys-x86/syscalls_64.c b/arch/um/sys-x86/syscalls_64.c deleted file mode 100644 index f3d82bb..0000000 --- a/arch/um/sys-x86/syscalls_64.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "linux/linkage.h" -#include "linux/personality.h" -#include "linux/utsname.h" -#include "asm/prctl.h" /* XXX This should get the constants from libc */ -#include "asm/uaccess.h" -#include "os.h" - -long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) -{ - unsigned long *ptr = addr, tmp; - long ret; - int pid = task->mm->context.id.u.pid; - - /* - * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to - * be safe), we need to call arch_prctl on the host because - * setting %fs may result in something else happening (like a - * GDT or thread.fs being set instead). So, we let the host - * fiddle the registers and thread struct and restore the - * registers afterwards. - * - * So, the saved registers are stored to the process (this - * needed because a stub may have been the last thing to run), - * arch_prctl is run on the host, then the registers are read - * back. - */ - switch (code) { - case ARCH_SET_FS: - case ARCH_SET_GS: - ret = restore_registers(pid, ¤t->thread.regs.regs); - if (ret) - return ret; - break; - case ARCH_GET_FS: - case ARCH_GET_GS: - /* - * With these two, we read to a local pointer and - * put_user it to the userspace pointer that we were - * given. If addr isn't valid (because it hasn't been - * faulted in or is just bogus), we want put_user to - * fault it in (or return -EFAULT) instead of having - * the host return -EFAULT. - */ - ptr = &tmp; - } - - ret = os_arch_prctl(pid, code, ptr); - if (ret) - return ret; - - switch (code) { - case ARCH_SET_FS: - current->thread.arch.fs = (unsigned long) ptr; - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_SET_GS: - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_GET_FS: - ret = put_user(tmp, addr); - break; - case ARCH_GET_GS: - ret = put_user(tmp, addr); - break; - } - - return ret; -} - -long sys_arch_prctl(int code, unsigned long addr) -{ - return arch_prctl(current, code, (unsigned long __user *) addr); -} - -long sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -void arch_switch_to(struct task_struct *to) -{ - if ((to->thread.arch.fs == 0) || (to->mm == NULL)) - return; - - arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); -} diff --git a/arch/um/sys-x86/sysrq_32.c b/arch/um/sys-x86/sysrq_32.c deleted file mode 100644 index 171b3e9..0000000 --- a/arch/um/sys-x86/sysrq_32.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "linux/smp.h" -#include "linux/sched.h" -#include "linux/kallsyms.h" -#include "asm/ptrace.h" -#include "sysrq.h" - -/* This is declared by */ -void show_regs(struct pt_regs *regs) -{ - printk("\n"); - printk("EIP: %04lx:[<%08lx>] CPU: %d %s", - 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs), - smp_processor_id(), print_tainted()); - if (PT_REGS_CS(regs) & 3) - printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs), - PT_REGS_SP(regs)); - printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs), - print_tainted()); - printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - PT_REGS_EAX(regs), PT_REGS_EBX(regs), - PT_REGS_ECX(regs), - PT_REGS_EDX(regs)); - printk("ESI: %08lx EDI: %08lx EBP: %08lx", - PT_REGS_ESI(regs), PT_REGS_EDI(regs), - PT_REGS_EBP(regs)); - printk(" DS: %04lx ES: %04lx\n", - 0xffff & PT_REGS_DS(regs), - 0xffff & PT_REGS_ES(regs)); - - show_trace(NULL, (unsigned long *) ®s); -} - -/* Copied from i386. */ -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - return p > (void *)tinfo && - p < (void *)tinfo + THREAD_SIZE - 3; -} - -/* Adapted from i386 (we also print the address we read from). */ -static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long ebp) -{ - unsigned long addr; - -#ifdef CONFIG_FRAME_POINTER - while (valid_stack_ptr(tinfo, (void *)ebp)) { - addr = *(unsigned long *)(ebp + 4); - printk("%08lx: [<%08lx>]", ebp + 4, addr); - print_symbol(" %s", addr); - printk("\n"); - ebp = *(unsigned long *)ebp; - } -#else - while (valid_stack_ptr(tinfo, stack)) { - addr = *stack; - if (__kernel_text_address(addr)) { - printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); - print_symbol(" %s", addr); - printk("\n"); - } - stack++; - } -#endif - return ebp; -} - -void show_trace(struct task_struct* task, unsigned long * stack) -{ - unsigned long ebp; - struct thread_info *context; - - /* Turn this into BUG_ON if possible. */ - if (!stack) { - stack = (unsigned long*) &stack; - printk("show_trace: got NULL stack, implicit assumption task == current"); - WARN_ON(1); - } - - if (!task) - task = current; - - if (task != current) { - ebp = (unsigned long) KSTK_EBP(task); - } else { - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - print_context_stack(context, stack, ebp); - - printk("\n"); -} - diff --git a/arch/um/sys-x86/sysrq_64.c b/arch/um/sys-x86/sysrq_64.c deleted file mode 100644 index f4f82be..0000000 --- a/arch/um/sys-x86/sysrq_64.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include "sysrq.h" - -void __show_regs(struct pt_regs *regs) -{ - printk("\n"); - print_modules(); - printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), - current->comm, print_tainted(), init_utsname()->release); - printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, - PT_REGS_RIP(regs)); - printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), - PT_REGS_EFLAGS(regs)); - printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", - PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); - printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", - PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); - printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", - PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); - printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", - PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); - printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", - PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); -} - -void show_regs(struct pt_regs *regs) -{ - __show_regs(regs); - show_trace(current, (unsigned long *) ®s); -} diff --git a/arch/um/sys-x86/tls_32.c b/arch/um/sys-x86/tls_32.c deleted file mode 100644 index c6c7131..0000000 --- a/arch/um/sys-x86/tls_32.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso - * Licensed under the GPL - */ - -#include "linux/percpu.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "os.h" -#include "skas.h" -#include "sysdep/tls.h" - -/* - * If needed we can detect when it's uninitialized. - * - * These are initialized in an initcall and unchanged thereafter. - */ -static int host_supports_tls = -1; -int host_gdt_entry_tls_min; - -int do_set_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_set_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_SET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -int do_get_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_get_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -/* - * sys_get_thread_area: get a yet unused TLS descriptor index. - * XXX: Consider leaving one free slot for glibc usage at first place. This must - * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else. - * - * Also, this must be tested when compiling in SKAS mode with dynamic linking - * and running against NPTL. - */ -static int get_free_idx(struct task_struct* task) -{ - struct thread_struct *t = &task->thread; - int idx; - - if (!t->arch.tls_array) - return GDT_ENTRY_TLS_MIN; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (!t->arch.tls_array[idx].present) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -static inline void clear_user_desc(struct user_desc* info) -{ - /* Postcondition: LDT_empty(info) returns true. */ - memset(info, 0, sizeof(*info)); - - /* - * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain - * indeed an empty user_desc. - */ - info->read_exec_only = 1; - info->seg_not_present = 1; -} - -#define O_FORCE 1 - -static int load_TLS(int flags, struct task_struct *to) -{ - int ret = 0; - int idx; - - for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { - struct uml_tls_struct* curr = - &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; - - /* - * Actually, now if it wasn't flushed it gets cleared and - * flushed to the host, which will clear it. - */ - if (!curr->present) { - if (!curr->flushed) { - clear_user_desc(&curr->tls); - curr->tls.entry_number = idx; - } else { - WARN_ON(!LDT_empty(&curr->tls)); - continue; - } - } - - if (!(flags & O_FORCE) && curr->flushed) - continue; - - ret = do_set_thread_area(&curr->tls); - if (ret) - goto out; - - curr->flushed = 1; - } -out: - return ret; -} - -/* - * Verify if we need to do a flush for the new process, i.e. if there are any - * present desc's, only if they haven't been flushed. - */ -static inline int needs_TLS_update(struct task_struct *task) -{ - int i; - int ret = 0; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Can't test curr->present, we may need to clear a descriptor - * which had a value. - */ - if (curr->flushed) - continue; - ret = 1; - break; - } - return ret; -} - -/* - * On a newly forked process, the TLS descriptors haven't yet been flushed. So - * we mark them as such and the first switch_to will do the job. - */ -void clear_flushed_tls(struct task_struct *task) -{ - int i; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Still correct to do this, if it wasn't present on the host it - * will remain as flushed as it was. - */ - if (!curr->present) - continue; - - curr->flushed = 0; - } -} - -/* - * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a - * common host process. So this is needed in SKAS0 too. - * - * However, if each thread had a different host process (and this was discussed - * for SMP support) this won't be needed. - * - * And this will not need be used when (and if) we'll add support to the host - * SKAS patch. - */ - -int arch_switch_tls(struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - /* - * We have no need whatsoever to switch TLS for kernel threads; beyond - * that, that would also result in us calling os_set_thread_area with - * userspace_pid[cpu] == 0, which gives an error. - */ - if (likely(to->mm)) - return load_TLS(O_FORCE, to); - - return 0; -} - -static int set_tls_entry(struct task_struct* task, struct user_desc *info, - int idx, int flushed) -{ - struct thread_struct *t = &task->thread; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed; - - return 0; -} - -int arch_copy_tls(struct task_struct *new) -{ - struct user_desc info; - int idx, ret = -EFAULT; - - if (copy_from_user(&info, - (void __user *) UPT_ESI(&new->thread.regs.regs), - sizeof(info))) - goto out; - - ret = -EINVAL; - if (LDT_empty(&info)) - goto out; - - idx = info.entry_number; - - ret = set_tls_entry(new, &info, idx, 0); -out: - return ret; -} - -/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ -static int get_tls_entry(struct task_struct *task, struct user_desc *info, - int idx) -{ - struct thread_struct *t = &task->thread; - - if (!t->arch.tls_array) - goto clear; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present) - goto clear; - - *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; - -out: - /* - * Temporary debugging check, to make sure that things have been - * flushed. This could be triggered if load_TLS() failed. - */ - if (unlikely(task == current && - !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { - printk(KERN_ERR "get_tls_entry: task with pid %d got here " - "without flushed TLS.", current->pid); - } - - return 0; -clear: - /* - * When the TLS entry has not been set, the values read to user in the - * tls_array are 0 (because it's cleared at boot, see - * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. - */ - clear_user_desc(info); - info->entry_number = idx; - goto out; -} - -int sys_set_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - idx = info.entry_number; - - if (idx == -1) { - idx = get_free_idx(current); - if (idx < 0) - return idx; - info.entry_number = idx; - /* Tell the user which slot we chose for him.*/ - if (put_user(idx, &user_desc->entry_number)) - return -EFAULT; - } - - ret = do_set_thread_area(&info); - if (ret) - return ret; - return set_tls_entry(current, &info, idx, 1); -} - -/* - * Perform set_thread_area on behalf of the traced child. - * Note: error handling is not done on the deferred load, and this differ from - * i386. However the only possible error are caused by bugs. - */ -int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - - if (!host_supports_tls) - return -EIO; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - return set_tls_entry(child, &info, idx, 0); -} - -int sys_get_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (get_user(idx, &user_desc->entry_number)) - return -EFAULT; - - ret = get_tls_entry(current, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; - -out: - return ret; -} - -/* - * Perform get_thread_area on behalf of the traced child. - */ -int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - int ret; - - if (!host_supports_tls) - return -EIO; - - ret = get_tls_entry(child, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; -out: - return ret; -} - -/* - * This code is really i386-only, but it detects and logs x86_64 GDT indexes - * if a 32-bit UML is running on a 64-bit host. - */ -static int __init __setup_host_supports_tls(void) -{ - check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); - if (host_supports_tls) { - printk(KERN_INFO "Host TLS support detected\n"); - printk(KERN_INFO "Detected host type: "); - switch (host_gdt_entry_tls_min) { - case GDT_ENTRY_TLS_MIN_I386: - printk(KERN_CONT "i386"); - break; - case GDT_ENTRY_TLS_MIN_X86_64: - printk(KERN_CONT "x86_64"); - break; - } - printk(KERN_CONT " (GDT indexes %d to %d)\n", - host_gdt_entry_tls_min, - host_gdt_entry_tls_min + GDT_ENTRY_TLS_ENTRIES); - } else - printk(KERN_ERR " Host TLS support NOT detected! " - "TLS support inside UML will not work\n"); - return 0; -} - -__initcall(__setup_host_supports_tls); diff --git a/arch/um/sys-x86/tls_64.c b/arch/um/sys-x86/tls_64.c deleted file mode 100644 index f7ba462..0000000 --- a/arch/um/sys-x86/tls_64.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "linux/sched.h" - -void clear_flushed_tls(struct task_struct *task) -{ -} - -int arch_copy_tls(struct task_struct *t) -{ - /* - * If CLONE_SETTLS is set, we need to save the thread id - * (which is argument 5, child_tid, of clone) so it can be set - * during context switches. - */ - t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; - - return 0; -} diff --git a/arch/um/sys-x86/user-offsets.c b/arch/um/sys-x86/user-offsets.c deleted file mode 100644 index 3c19c48..0000000 --- a/arch/um/sys-x86/user-offsets.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define __FRAME_OFFSETS -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -void foo(void) -{ -#ifdef __i386__ - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); - - DEFINE(HOST_IP, EIP); - DEFINE(HOST_SP, UESP); - DEFINE(HOST_EFLAGS, EFL); - DEFINE(HOST_EAX, EAX); - DEFINE(HOST_EBX, EBX); - DEFINE(HOST_ECX, ECX); - DEFINE(HOST_EDX, EDX); - DEFINE(HOST_ESI, ESI); - DEFINE(HOST_EDI, EDI); - DEFINE(HOST_EBP, EBP); - DEFINE(HOST_CS, CS); - DEFINE(HOST_SS, SS); - DEFINE(HOST_DS, DS); - DEFINE(HOST_FS, FS); - DEFINE(HOST_ES, ES); - DEFINE(HOST_GS, GS); -#else - DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); - DEFINE_LONGS(HOST_RBX, RBX); - DEFINE_LONGS(HOST_RCX, RCX); - DEFINE_LONGS(HOST_RDI, RDI); - DEFINE_LONGS(HOST_RSI, RSI); - DEFINE_LONGS(HOST_RDX, RDX); - DEFINE_LONGS(HOST_RBP, RBP); - DEFINE_LONGS(HOST_RAX, RAX); - DEFINE_LONGS(HOST_R8, R8); - DEFINE_LONGS(HOST_R9, R9); - DEFINE_LONGS(HOST_R10, R10); - DEFINE_LONGS(HOST_R11, R11); - DEFINE_LONGS(HOST_R12, R12); - DEFINE_LONGS(HOST_R13, R13); - DEFINE_LONGS(HOST_R14, R14); - DEFINE_LONGS(HOST_R15, R15); - DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); - DEFINE_LONGS(HOST_CS, CS); - DEFINE_LONGS(HOST_SS, SS); - DEFINE_LONGS(HOST_EFLAGS, EFLAGS); -#if 0 - DEFINE_LONGS(HOST_FS, FS); - DEFINE_LONGS(HOST_GS, GS); - DEFINE_LONGS(HOST_DS, DS); - DEFINE_LONGS(HOST_ES, ES); -#endif - - DEFINE_LONGS(HOST_IP, RIP); - DEFINE_LONGS(HOST_SP, RSP); -#endif - - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} diff --git a/arch/um/sys-x86/vdso/Makefile b/arch/um/sys-x86/vdso/Makefile deleted file mode 100644 index 5dffe6d..0000000 --- a/arch/um/sys-x86/vdso/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# -# Building vDSO images for x86. -# - -VDSO64-y := y - -vdso-install-$(VDSO64-y) += vdso.so - - -# files to link into the vdso -vobjs-y := vdso-note.o um_vdso.o - -# files to link into kernel -obj-$(VDSO64-y) += vdso.o vma.o - -vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) - -$(obj)/vdso.o: $(obj)/vdso.so - -targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) - -export CPPFLAGS_vdso.lds += -P -C - -VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 - -$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so - -$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE - $(call if_changed,vdso) - -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -# -# Don't omit frame pointers for ease of userspace debugging, but do -# optimize sibling calls. -# -CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ - $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ - -fno-omit-frame-pointer -foptimize-sibling-calls - -$(vobjs): KBUILD_CFLAGS += $(CFL) - -# -# vDSO code runs in userspace and -pg doesn't help with profiling anyway. -# -CFLAGS_REMOVE_vdso-note.o = -pg -CFLAGS_REMOVE_um_vdso.o = -pg - -targets += vdso-syms.lds -obj-$(VDSO64-y) += vdso-syms.lds - -# -# Match symbols in the DSO that look like VDSO*; produce a file of constants. -# -sed-vdsosym := -e 's/^00*/0/' \ - -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' -quiet_cmd_vdsosym = VDSOSYM $@ -define cmd_vdsosym - $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ -endef - -$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE - $(call if_changed,vdsosym) - -# -# The DSO images are built using a special linker script. -# -quiet_cmd_vdso = VDSO $@ - cmd_vdso = $(CC) -nostdlib -o $@ \ - $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ - -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ - sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' - -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) -GCOV_PROFILE := n - -# -# Install the unstripped copy of vdso*.so listed in $(vdso-install-y). -# -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ -$(vdso-install-y): %.so: $(obj)/%.so.dbg FORCE - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -PHONY += vdso_install $(vdso-install-y) -vdso_install: $(vdso-install-y) diff --git a/arch/um/sys-x86/vdso/checkundef.sh b/arch/um/sys-x86/vdso/checkundef.sh deleted file mode 100644 index 7ee90a9..0000000 --- a/arch/um/sys-x86/vdso/checkundef.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -nm="$1" -file="$2" -$nm "$file" | grep '^ *U' > /dev/null 2>&1 -if [ $? -eq 1 ]; then - exit 0 -else - echo "$file: undefined symbols found" >&2 - exit 1 -fi diff --git a/arch/um/sys-x86/vdso/um_vdso.c b/arch/um/sys-x86/vdso/um_vdso.c deleted file mode 100644 index 7c441b5..0000000 --- a/arch/um/sys-x86/vdso/um_vdso.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This vDSO turns all calls into a syscall so that UML can trap them. - */ - - -/* Disable profiling for userspace code */ -#define DISABLE_BRANCH_PROFILING - -#include -#include -#include - -int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) -{ - long ret; - - asm("syscall" : "=a" (ret) : - "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); - - return ret; -} -int clock_gettime(clockid_t, struct timespec *) - __attribute__((weak, alias("__vdso_clock_gettime"))); - -int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) -{ - long ret; - - asm("syscall" : "=a" (ret) : - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); - - return ret; -} -int gettimeofday(struct timeval *, struct timezone *) - __attribute__((weak, alias("__vdso_gettimeofday"))); - -time_t __vdso_time(time_t *t) -{ - long secs; - - asm volatile("syscall" - : "=a" (secs) - : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); - - return secs; -} -int time(time_t *t) __attribute__((weak, alias("__vdso_time"))); - -long -__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) -{ - /* - * UML does not support SMP, we can cheat here. :) - */ - - if (cpu) - *cpu = 0; - if (node) - *node = 0; - - return 0; -} - -long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) - __attribute__((weak, alias("__vdso_getcpu"))); diff --git a/arch/um/sys-x86/vdso/vdso-layout.lds.S b/arch/um/sys-x86/vdso/vdso-layout.lds.S deleted file mode 100644 index 634a2cf..0000000 --- a/arch/um/sys-x86/vdso/vdso-layout.lds.S +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Linker script for vDSO. This is an ELF shared object prelinked to - * its virtual address, and with only one read-only segment. - * This script controls its layout. - */ - -SECTIONS -{ - . = VDSO_PRELINK + SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - - .dynamic : { *(.dynamic) } :text :dynamic - - .rodata : { *(.rodata*) } :text - .data : { - *(.data*) - *(.sdata*) - *(.got.plt) *(.got) - *(.gnu.linkonce.d.*) - *(.bss*) - *(.dynbss*) - *(.gnu.linkonce.b.*) - } - - .altinstructions : { *(.altinstructions) } - .altinstr_replacement : { *(.altinstr_replacement) } - - /* - * Align the actual code well away from the non-instruction data. - * This is the best thing for the I-cache. - */ - . = ALIGN(0x100); - - .text : { *(.text*) } :text =0x90909090 -} - -/* - * Very old versions of ld do not recognize this name token; use the constant. - */ -#define PT_GNU_EH_FRAME 0x6474e550 - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; -} diff --git a/arch/um/sys-x86/vdso/vdso-note.S b/arch/um/sys-x86/vdso/vdso-note.S deleted file mode 100644 index 79a071e..0000000 --- a/arch/um/sys-x86/vdso/vdso-note.S +++ /dev/null @@ -1,12 +0,0 @@ -/* - * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. - * Here we can supply some information useful to userland. - */ - -#include -#include -#include - -ELFNOTE_START(Linux, 0, "a") - .long LINUX_VERSION_CODE -ELFNOTE_END diff --git a/arch/um/sys-x86/vdso/vdso.S b/arch/um/sys-x86/vdso/vdso.S deleted file mode 100644 index 03b0532..0000000 --- a/arch/um/sys-x86/vdso/vdso.S +++ /dev/null @@ -1,10 +0,0 @@ -#include - -__INITDATA - - .globl vdso_start, vdso_end -vdso_start: - .incbin "arch/um/sys-x86/vdso/vdso.so" -vdso_end: - -__FINIT diff --git a/arch/um/sys-x86/vdso/vdso.lds.S b/arch/um/sys-x86/vdso/vdso.lds.S deleted file mode 100644 index b96b267..0000000 --- a/arch/um/sys-x86/vdso/vdso.lds.S +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Linker script for 64-bit vDSO. - * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. - * - * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. - */ - -#define VDSO_PRELINK 0xffffffffff700000 -#include "vdso-layout.lds.S" - -/* - * This controls what userland symbols we export from the vDSO. - */ -VERSION { - LINUX_2.6 { - global: - clock_gettime; - __vdso_clock_gettime; - gettimeofday; - __vdso_gettimeofday; - getcpu; - __vdso_getcpu; - time; - __vdso_time; - local: *; - }; -} - -VDSO64_PRELINK = VDSO_PRELINK; diff --git a/arch/um/sys-x86/vdso/vma.c b/arch/um/sys-x86/vdso/vma.c deleted file mode 100644 index 9495c8d..0000000 --- a/arch/um/sys-x86/vdso/vma.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -unsigned int __read_mostly vdso_enabled = 1; -unsigned long um_vdso_addr; - -extern unsigned long task_size; -extern char vdso_start[], vdso_end[]; - -static struct page **vdsop; - -static int __init init_vdso(void) -{ - struct page *um_vdso; - - BUG_ON(vdso_end - vdso_start > PAGE_SIZE); - - um_vdso_addr = task_size - PAGE_SIZE; - - vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *)); - if (!vdsop) - goto oom; - - um_vdso = alloc_page(GFP_KERNEL); - if (!um_vdso) { - kfree(vdsop); - - goto oom; - } - - copy_page(page_address(um_vdso), vdso_start); - *vdsop = um_vdso; - - return 0; - -oom: - printk(KERN_ERR "Cannot allocate vdso\n"); - vdso_enabled = 0; - - return -ENOMEM; -} -subsys_initcall(init_vdso); - -int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) -{ - int err; - struct mm_struct *mm = current->mm; - - if (!vdso_enabled) - return 0; - - down_write(&mm->mmap_sem); - - err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - vdsop); - - up_write(&mm->mmap_sem); - - return err; -} -- cgit v1.1 From 0acdbbeb6dd435f5f3f1648fc3a2ab5fd07b5545 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:49 +0100 Subject: um: bury unused macros around ptrace.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/ptrace-generic.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index c3b8a04..f605d3c 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -23,14 +23,10 @@ struct pt_regs { #define PT_REGS_IP(r) UPT_IP(&(r)->regs) #define PT_REGS_SP(r) UPT_SP(&(r)->regs) -#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ - UPT_SET_SYSCALL_RETURN(&(r)->regs, res) #define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) #define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) -#define PT_REGS_SC(r) UPT_SC(&(r)->regs) - #define instruction_pointer(regs) PT_REGS_IP(regs) struct task_struct; -- cgit v1.1 From 549e78db9438374cb6a58201cc5f2194b222688f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:06:59 +0100 Subject: um: make load_initrd() static, kill shared/initrd.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/initrd.h | 12 ------------ arch/um/kernel/initrd.c | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 arch/um/include/shared/initrd.h (limited to 'arch/um') diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h deleted file mode 100644 index 22673bc..0000000 --- a/arch/um/include/shared/initrd.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __INITRD_USER_H__ -#define __INITRD_USER_H__ - -extern int load_initrd(char *filename, void *buf, int size); - -#endif - diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index d386c75..10cc18f 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -7,12 +7,12 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" -#include "initrd.h" #include "init.h" #include "os.h" /* Changed by uml_initrd_setup, which is a setup */ static char *initrd __initdata = NULL; +static int load_initrd(char *filename, void *buf, int size); static int __init read_initrd(void) { @@ -62,7 +62,7 @@ __uml_setup("initrd=", uml_initrd_setup, " name of the file containing the image.\n\n" ); -int load_initrd(char *filename, void *buf, int size) +static int load_initrd(char *filename, void *buf, int size) { int fd, n; -- cgit v1.1 From 429172ccf058e67974dd1ab3d8b82075383efe84 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:09 +0100 Subject: um: trim kern.h most of the functions in there are not used in anything that ends up including that header... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/kern.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/kern.h b/arch/um/include/shared/kern.h index 4ce3fc6..6cd0124 100644 --- a/arch/um/include/shared/kern.h +++ b/arch/um/include/shared/kern.h @@ -13,28 +13,10 @@ * includes. */ -extern int errno; - -extern int clone(int (*proc)(void *), void *sp, int flags, void *data); -extern int sleep(int); extern int printf(const char *fmt, ...); -extern char *strerror(int errnum); -extern char *ptsname(int __fd); -extern int munmap(void *, int); extern void *sbrk(int increment); -extern void *malloc(int size); -extern void perror(char *err); -extern int kill(int pid, int sig); -extern int getuid(void); -extern int getgid(void); extern int pause(void); -extern int write(int, const void *, int); extern void exit(int); -extern int close(int); -extern int read(unsigned int, char *, int); -extern int pipe(int *); -extern int sched_yield(void); -extern int ptrace(int op, int pid, long addr, long data); #endif -- cgit v1.1 From dbddc51bc8557525bcc51ad8f4e1626e5f586ebc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:19 +0100 Subject: um: don't include kern.h unless it's needed Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/ssl.c | 1 - arch/um/drivers/ubd_kern.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index f1786e6..678e205 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -15,7 +15,6 @@ #include "line.h" #include "ssl.h" #include "chan_kern.h" -#include "kern.h" #include "init.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 620f5b7..0136be1 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -46,7 +46,6 @@ #include "asm/tlbflush.h" #include "mem_user.h" #include "kern_util.h" -#include "kern.h" #include "mconsole_kern.h" #include "init.h" #include "irq_user.h" -- cgit v1.1 From 1cf5e62ab939022b43634d6608afd10a809b02b9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:29 +0100 Subject: um: shared/syscall.h is not even included ... and functions declared in it do not exist Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/syscall.h | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 arch/um/include/shared/syscall.h (limited to 'arch/um') diff --git a/arch/um/include/shared/syscall.h b/arch/um/include/shared/syscall.h deleted file mode 100644 index dda1df9..0000000 --- a/arch/um/include/shared/syscall.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSCALL_USER_H -#define __SYSCALL_USER_H - -extern int record_syscall_start(int syscall); -extern void record_syscall_end(int index, long result); - -#endif -- cgit v1.1 From 5ade8878e03a9a298a71efbf2895aa482e45448a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:39 +0100 Subject: um: kill shared/task.h and HOST_TASK_REGS Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/common-offsets.h | 1 - arch/um/include/shared/task.h | 9 --------- 2 files changed, 10 deletions(-) delete mode 100644 arch/um/include/shared/task.h (limited to 'arch/um') diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 72009c7..d7fe563 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -2,7 +2,6 @@ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); -OFFSET(HOST_TASK_REGS, task_struct, thread.regs); OFFSET(HOST_TASK_PID, task_struct, pid); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); diff --git a/arch/um/include/shared/task.h b/arch/um/include/shared/task.h deleted file mode 100644 index 3db6b58..0000000 --- a/arch/um/include/shared/task.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __TASK_H -#define __TASK_H - -#include - -#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) -#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) - -#endif -- cgit v1.1 From c75d053b701cc098d44b729c8266a2df5ca5206e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:49 +0100 Subject: um: make flush_tlb_kernel_range_common() static Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/tlb.h | 2 -- arch/um/kernel/tlb.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/tlb.h b/arch/um/include/shared/tlb.h index ecd2265..8a50ce1 100644 --- a/arch/um/include/shared/tlb.h +++ b/arch/um/include/shared/tlb.h @@ -9,7 +9,5 @@ #include "um_mmu.h" extern void force_flush_all(void); -extern int flush_tlb_kernel_range_common(unsigned long start, - unsigned long end); #endif diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index d175d05..d1da8ac 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -287,7 +287,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, } } -int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) +static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) { struct mm_struct *mm; pgd_t *pgd; -- cgit v1.1 From 445c5786c9ce02b6816bb11fd3394a134fa6d244 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:07:59 +0100 Subject: um: kill shared/tlb.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/tlb.h | 13 ------------- arch/um/kernel/process.c | 2 +- arch/um/kernel/tlb.c | 1 - 3 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 arch/um/include/shared/tlb.h (limited to 'arch/um') diff --git a/arch/um/include/shared/tlb.h b/arch/um/include/shared/tlb.h deleted file mode 100644 index 8a50ce1..0000000 --- a/arch/um/include/shared/tlb.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TLB_H__ -#define __TLB_H__ - -#include "um_mmu.h" - -extern void force_flush_all(void); - -#endif diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 21c1ae7..db44142 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -20,12 +20,12 @@ #include #include #include +#include #include #include "as-layout.h" #include "kern_util.h" #include "os.h" #include "skas.h" -#include "tlb.h" /* * This is a per-cpu array. A processor only modifies its entry and it only diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index d1da8ac..11cadb2 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -11,7 +11,6 @@ #include "mem_user.h" #include "os.h" #include "skas.h" -#include "tlb.h" struct host_vm_change { struct host_vm_op { -- cgit v1.1 From 0a9e70b1cd0f7ee82a65d19edfcd31664ef65f69 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:08:09 +0100 Subject: um: kill shared/mem_kern.h ... nothing declared there exists Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/ubd_kern.c | 1 - arch/um/include/shared/mem_kern.h | 20 -------------------- 2 files changed, 21 deletions(-) delete mode 100644 arch/um/include/shared/mem_kern.h (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0136be1..b3c8545 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -53,7 +53,6 @@ #include "ubd_user.h" #include "os.h" #include "mem.h" -#include "mem_kern.h" #include "cow.h" enum ubd_req { UBD_READ, UBD_WRITE }; diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h deleted file mode 100644 index 69be0fd..0000000 --- a/arch/um/include/shared/mem_kern.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __MEM_KERN_H__ -#define __MEM_KERN_H__ - -#include "linux/list.h" -#include "linux/types.h" - -struct remapper { - struct list_head list; - int (*proc)(int, unsigned long, int, __u64); -}; - -extern void register_remapper(struct remapper *info); - -#endif - -- cgit v1.1 From 17e052093bcd21eaf9eb6e792cd76fdc4f0e3505 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:08:19 +0100 Subject: um: take register_winch_irq() into the caller of is_skas_winch() Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/chan_user.c | 7 ++++++- arch/um/os-Linux/skas/process.c | 6 +----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 7ed06a7..f180813 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -281,7 +281,12 @@ void register_winch(int fd, struct tty_struct *tty) return; pid = tcgetpgrp(fd); - if (!is_skas_winch(pid, fd, tty) && (pid == -1)) { + if (is_skas_winch(pid, fd, tty)) { + register_winch_irq(-1, fd, -1, tty, 0); + return; + } + + if (pid == -1) { thread = winch_tramp(fd, tty, &thread_fd, &stack); if (thread < 0) return; diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 30f1bb4..29e4ab7 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -26,11 +26,7 @@ int is_skas_winch(int pid, int fd, void *data) { - if (pid != getpgrp()) - return 0; - - register_winch_irq(-1, fd, -1, data, 0); - return 1; + return pid == getpgrp(); } static int ptrace_dump_regs(int pid) -- cgit v1.1 From 510c72a3cf51c9463db64eb6c21347f4940a202f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:08:29 +0100 Subject: um: take chan_*.h and line.h to arch/um/drivers Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/chan.h | 50 +++++++++++++++++ arch/um/drivers/chan_kern.c | 2 +- arch/um/drivers/chan_user.h | 55 +++++++++++++++++++ arch/um/drivers/line.c | 2 +- arch/um/drivers/line.h | 106 +++++++++++++++++++++++++++++++++++++ arch/um/drivers/ssl.c | 3 +- arch/um/drivers/stdio_console.c | 3 +- arch/um/include/shared/chan_kern.h | 50 ----------------- arch/um/include/shared/chan_user.h | 55 ------------------- arch/um/include/shared/line.h | 106 ------------------------------------- arch/um/os-Linux/skas/process.c | 2 +- 11 files changed, 216 insertions(+), 218 deletions(-) create mode 100644 arch/um/drivers/chan.h create mode 100644 arch/um/drivers/chan_user.h create mode 100644 arch/um/drivers/line.h delete mode 100644 arch/um/include/shared/chan_kern.h delete mode 100644 arch/um/include/shared/chan_user.h delete mode 100644 arch/um/include/shared/line.h (limited to 'arch/um') diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h new file mode 100644 index 0000000..8df0fd90 --- /dev/null +++ b/arch/um/drivers/chan.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __CHAN_KERN_H__ +#define __CHAN_KERN_H__ + +#include +#include +#include +#include "chan_user.h" +#include "line.h" + +struct chan { + struct list_head list; + struct list_head free_list; + struct line *line; + char *dev; + unsigned int primary:1; + unsigned int input:1; + unsigned int output:1; + unsigned int opened:1; + unsigned int enabled:1; + int fd; + const struct chan_ops *ops; + void *data; +}; + +extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, + struct tty_struct *tty, int irq); +extern int parse_chan_pair(char *str, struct line *line, int device, + const struct chan_opts *opts, char **error_out); +extern int write_chan(struct list_head *chans, const char *buf, int len, + int write_irq); +extern int console_write_chan(struct list_head *chans, const char *buf, + int len); +extern int console_open_chan(struct line *line, struct console *co); +extern void deactivate_chan(struct list_head *chans, int irq); +extern void reactivate_chan(struct list_head *chans, int irq); +extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); +extern int enable_chan(struct line *line); +extern void close_chan(struct list_head *chans, int delay_free_irq); +extern int chan_window_size(struct list_head *chans, + unsigned short *rows_out, + unsigned short *cols_out); +extern int chan_config_string(struct list_head *chans, char *str, int size, + char **error_out); + +#endif diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index d4191fe..e040683 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -6,7 +6,7 @@ #include #include #include -#include "chan_kern.h" +#include "chan.h" #include "os.h" #ifdef CONFIG_NOCONFIG_CHAN diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h new file mode 100644 index 0000000..9b9ced8 --- /dev/null +++ b/arch/um/drivers/chan_user.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __CHAN_USER_H__ +#define __CHAN_USER_H__ + +#include "init.h" + +struct chan_opts { + void (*const announce)(char *dev_name, int dev); + char *xterm_title; + const int raw; +}; + +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; + +struct chan_ops { + char *type; + void *(*init)(char *, int, const struct chan_opts *); + int (*open)(int, int, int, void *, char **); + void (*close)(int, void *); + int (*read)(int, char *, void *); + int (*write)(int, const char *, int, void *); + int (*console_write)(int, const char *, int); + int (*window_size)(int, void *, unsigned short *, unsigned short *); + void (*free)(void *); + int winch; +}; + +extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, + tty_ops, xterm_ops; + +extern void generic_close(int fd, void *unused); +extern int generic_read(int fd, char *c_out, void *unused); +extern int generic_write(int fd, const char *buf, int n, void *unused); +extern int generic_console_write(int fd, const char *buf, int n); +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, + unsigned short *cols_out); +extern void generic_free(void *data); + +struct tty_struct; +extern void register_winch(int fd, struct tty_struct *tty); +extern void register_winch_irq(int fd, int tty_fd, int pid, + struct tty_struct *tty, unsigned long stack); + +#define __channel_help(fn, prefix) \ +__uml_help(fn, prefix "[0-9]*=\n" \ +" Attach a console or serial line to a host channel. See\n" \ +" http://user-mode-linux.sourceforge.net/old/input.html for a complete\n" \ +" description of this switch.\n\n" \ +); + +#endif diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 364c8a1..c1cf220 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -7,7 +7,7 @@ #include "linux/kd.h" #include "linux/sched.h" #include "linux/slab.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_kern.h" #include "irq_user.h" #include "kern_util.h" diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h new file mode 100644 index 0000000..63df3ca --- /dev/null +++ b/arch/um/drivers/line.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __LINE_H__ +#define __LINE_H__ + +#include "linux/list.h" +#include "linux/workqueue.h" +#include "linux/tty.h" +#include "linux/interrupt.h" +#include "linux/spinlock.h" +#include "linux/mutex.h" +#include "chan_user.h" +#include "mconsole_kern.h" + +/* There's only one modifiable field in this - .mc.list */ +struct line_driver { + const char *name; + const char *device_name; + const short major; + const short minor_start; + const short type; + const short subtype; + const int read_irq; + const char *read_irq_name; + const int write_irq; + const char *write_irq_name; + struct mc_device mc; +}; + +struct line { + struct tty_struct *tty; + spinlock_t count_lock; + unsigned long count; + int valid; + + char *init_str; + int init_pri; + struct list_head chan_list; + + /*This lock is actually, mostly, local to*/ + spinlock_t lock; + int throttled; + /* Yes, this is a real circular buffer. + * XXX: And this should become a struct kfifo! + * + * buffer points to a buffer allocated on demand, of length + * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/ + char *buffer; + char *head; + char *tail; + + int sigio; + struct delayed_work task; + const struct line_driver *driver; + int have_irq; +}; + +#define LINE_INIT(str, d) \ + { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \ + .init_str = str, \ + .init_pri = INIT_STATIC, \ + .valid = 1, \ + .lock = __SPIN_LOCK_UNLOCKED((str).lock), \ + .driver = d } + +extern void line_close(struct tty_struct *tty, struct file * filp); +extern int line_open(struct line *lines, struct tty_struct *tty); +extern int line_setup(struct line *lines, unsigned int sizeof_lines, + char *init, char **error_out); +extern int line_write(struct tty_struct *tty, const unsigned char *buf, + int len); +extern int line_put_char(struct tty_struct *tty, unsigned char ch); +extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); +extern int line_chars_in_buffer(struct tty_struct *tty); +extern void line_flush_buffer(struct tty_struct *tty); +extern void line_flush_chars(struct tty_struct *tty); +extern int line_write_room(struct tty_struct *tty); +extern int line_ioctl(struct tty_struct *tty, unsigned int cmd, + unsigned long arg); +extern void line_throttle(struct tty_struct *tty); +extern void line_unthrottle(struct tty_struct *tty); + +extern char *add_xterm_umid(char *base); +extern int line_setup_irq(int fd, int input, int output, struct line *line, + void *data); +extern void line_close_chan(struct line *line); +extern struct tty_driver *register_lines(struct line_driver *line_driver, + const struct tty_operations *driver, + struct line *lines, int nlines); +extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); +extern void close_lines(struct line *lines, int nlines); + +extern int line_config(struct line *lines, unsigned int sizeof_lines, + char *str, const struct chan_opts *opts, + char **error_out); +extern int line_id(char **str, int *start_out, int *end_out); +extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n, + char **error_out); +extern int line_get_config(char *dev, struct line *lines, + unsigned int sizeof_lines, char *str, + int size, char **error_out); + +#endif diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 678e205..9d8c20a 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -12,9 +12,8 @@ #include "linux/console.h" #include "asm/termbits.h" #include "asm/irq.h" -#include "line.h" #include "ssl.h" -#include "chan_kern.h" +#include "chan.h" #include "init.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 49266f6..088776f 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -20,8 +20,7 @@ #include "asm/current.h" #include "asm/irq.h" #include "stdio_console.h" -#include "line.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_user.h" #include "mconsole_kern.h" #include "init.h" diff --git a/arch/um/include/shared/chan_kern.h b/arch/um/include/shared/chan_kern.h deleted file mode 100644 index 1e65145..0000000 --- a/arch/um/include/shared/chan_kern.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __CHAN_KERN_H__ -#define __CHAN_KERN_H__ - -#include "linux/tty.h" -#include "linux/list.h" -#include "linux/console.h" -#include "chan_user.h" -#include "line.h" - -struct chan { - struct list_head list; - struct list_head free_list; - struct line *line; - char *dev; - unsigned int primary:1; - unsigned int input:1; - unsigned int output:1; - unsigned int opened:1; - unsigned int enabled:1; - int fd; - const struct chan_ops *ops; - void *data; -}; - -extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, - struct tty_struct *tty, int irq); -extern int parse_chan_pair(char *str, struct line *line, int device, - const struct chan_opts *opts, char **error_out); -extern int write_chan(struct list_head *chans, const char *buf, int len, - int write_irq); -extern int console_write_chan(struct list_head *chans, const char *buf, - int len); -extern int console_open_chan(struct line *line, struct console *co); -extern void deactivate_chan(struct list_head *chans, int irq); -extern void reactivate_chan(struct list_head *chans, int irq); -extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); -extern int enable_chan(struct line *line); -extern void close_chan(struct list_head *chans, int delay_free_irq); -extern int chan_window_size(struct list_head *chans, - unsigned short *rows_out, - unsigned short *cols_out); -extern int chan_config_string(struct list_head *chans, char *str, int size, - char **error_out); - -#endif diff --git a/arch/um/include/shared/chan_user.h b/arch/um/include/shared/chan_user.h deleted file mode 100644 index 9b9ced8..0000000 --- a/arch/um/include/shared/chan_user.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __CHAN_USER_H__ -#define __CHAN_USER_H__ - -#include "init.h" - -struct chan_opts { - void (*const announce)(char *dev_name, int dev); - char *xterm_title; - const int raw; -}; - -enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; - -struct chan_ops { - char *type; - void *(*init)(char *, int, const struct chan_opts *); - int (*open)(int, int, int, void *, char **); - void (*close)(int, void *); - int (*read)(int, char *, void *); - int (*write)(int, const char *, int, void *); - int (*console_write)(int, const char *, int); - int (*window_size)(int, void *, unsigned short *, unsigned short *); - void (*free)(void *); - int winch; -}; - -extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, - tty_ops, xterm_ops; - -extern void generic_close(int fd, void *unused); -extern int generic_read(int fd, char *c_out, void *unused); -extern int generic_write(int fd, const char *buf, int n, void *unused); -extern int generic_console_write(int fd, const char *buf, int n); -extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, - unsigned short *cols_out); -extern void generic_free(void *data); - -struct tty_struct; -extern void register_winch(int fd, struct tty_struct *tty); -extern void register_winch_irq(int fd, int tty_fd, int pid, - struct tty_struct *tty, unsigned long stack); - -#define __channel_help(fn, prefix) \ -__uml_help(fn, prefix "[0-9]*=\n" \ -" Attach a console or serial line to a host channel. See\n" \ -" http://user-mode-linux.sourceforge.net/old/input.html for a complete\n" \ -" description of this switch.\n\n" \ -); - -#endif diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h deleted file mode 100644 index 63df3ca..0000000 --- a/arch/um/include/shared/line.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __LINE_H__ -#define __LINE_H__ - -#include "linux/list.h" -#include "linux/workqueue.h" -#include "linux/tty.h" -#include "linux/interrupt.h" -#include "linux/spinlock.h" -#include "linux/mutex.h" -#include "chan_user.h" -#include "mconsole_kern.h" - -/* There's only one modifiable field in this - .mc.list */ -struct line_driver { - const char *name; - const char *device_name; - const short major; - const short minor_start; - const short type; - const short subtype; - const int read_irq; - const char *read_irq_name; - const int write_irq; - const char *write_irq_name; - struct mc_device mc; -}; - -struct line { - struct tty_struct *tty; - spinlock_t count_lock; - unsigned long count; - int valid; - - char *init_str; - int init_pri; - struct list_head chan_list; - - /*This lock is actually, mostly, local to*/ - spinlock_t lock; - int throttled; - /* Yes, this is a real circular buffer. - * XXX: And this should become a struct kfifo! - * - * buffer points to a buffer allocated on demand, of length - * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/ - char *buffer; - char *head; - char *tail; - - int sigio; - struct delayed_work task; - const struct line_driver *driver; - int have_irq; -}; - -#define LINE_INIT(str, d) \ - { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \ - .init_str = str, \ - .init_pri = INIT_STATIC, \ - .valid = 1, \ - .lock = __SPIN_LOCK_UNLOCKED((str).lock), \ - .driver = d } - -extern void line_close(struct tty_struct *tty, struct file * filp); -extern int line_open(struct line *lines, struct tty_struct *tty); -extern int line_setup(struct line *lines, unsigned int sizeof_lines, - char *init, char **error_out); -extern int line_write(struct tty_struct *tty, const unsigned char *buf, - int len); -extern int line_put_char(struct tty_struct *tty, unsigned char ch); -extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); -extern int line_chars_in_buffer(struct tty_struct *tty); -extern void line_flush_buffer(struct tty_struct *tty); -extern void line_flush_chars(struct tty_struct *tty); -extern int line_write_room(struct tty_struct *tty); -extern int line_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg); -extern void line_throttle(struct tty_struct *tty); -extern void line_unthrottle(struct tty_struct *tty); - -extern char *add_xterm_umid(char *base); -extern int line_setup_irq(int fd, int input, int output, struct line *line, - void *data); -extern void line_close_chan(struct line *line); -extern struct tty_driver *register_lines(struct line_driver *line_driver, - const struct tty_operations *driver, - struct line *lines, int nlines); -extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); -extern void close_lines(struct line *lines, int nlines); - -extern int line_config(struct line *lines, unsigned int sizeof_lines, - char *str, const struct chan_opts *opts, - char **error_out); -extern int line_id(char **str, int *start_out, int *end_out); -extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n, - char **error_out); -extern int line_get_config(char *dev, struct line *lines, - unsigned int sizeof_lines, char *str, - int size, char **error_out); - -#endif diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 29e4ab7..6c34f14 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -13,7 +13,7 @@ #include #include #include "as-layout.h" -#include "chan_user.h" +#include "init.h" #include "kern_util.h" #include "mem.h" #include "os.h" -- cgit v1.1 From ece67c8697f32699f6977d3d1ae2ae9f7892a913 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:08:39 +0100 Subject: um: take mconsole*.h to arch/um/drivers Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/mconsole.h | 98 ++++++++++++++++++++++++++++++++++ arch/um/drivers/mconsole_kern.h | 52 ++++++++++++++++++ arch/um/include/shared/mconsole.h | 98 ---------------------------------- arch/um/include/shared/mconsole_kern.h | 52 ------------------ 4 files changed, 150 insertions(+), 150 deletions(-) create mode 100644 arch/um/drivers/mconsole.h create mode 100644 arch/um/drivers/mconsole_kern.h delete mode 100644 arch/um/include/shared/mconsole.h delete mode 100644 arch/um/include/shared/mconsole_kern.h (limited to 'arch/um') diff --git a/arch/um/drivers/mconsole.h b/arch/um/drivers/mconsole.h new file mode 100644 index 0000000..c139ae1 --- /dev/null +++ b/arch/um/drivers/mconsole.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) + * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __MCONSOLE_H__ +#define __MCONSOLE_H__ + +#ifndef __KERNEL__ +#include +#define u32 uint32_t +#endif + +#include "sysdep/ptrace.h" + +#define MCONSOLE_MAGIC (0xcafebabe) +#define MCONSOLE_MAX_DATA (512) +#define MCONSOLE_VERSION 2 + +struct mconsole_request { + u32 magic; + u32 version; + u32 len; + char data[MCONSOLE_MAX_DATA]; +}; + +struct mconsole_reply { + u32 err; + u32 more; + u32 len; + char data[MCONSOLE_MAX_DATA]; +}; + +struct mconsole_notify { + u32 magic; + u32 version; + enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, + MCONSOLE_USER_NOTIFY } type; + u32 len; + char data[MCONSOLE_MAX_DATA]; +}; + +struct mc_request; + +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC }; + +struct mconsole_command +{ + char *command; + void (*handler)(struct mc_request *req); + enum mc_context context; +}; + +struct mc_request +{ + int len; + int as_interrupt; + + int originating_fd; + unsigned int originlen; + unsigned char origin[128]; /* sockaddr_un */ + + struct mconsole_request request; + struct mconsole_command *cmd; + struct uml_pt_regs regs; +}; + +extern char mconsole_socket_name[]; + +extern int mconsole_unlink_socket(void); +extern int mconsole_reply_len(struct mc_request *req, const char *reply, + int len, int err, int more); +extern int mconsole_reply(struct mc_request *req, const char *str, int err, + int more); + +extern void mconsole_version(struct mc_request *req); +extern void mconsole_help(struct mc_request *req); +extern void mconsole_halt(struct mc_request *req); +extern void mconsole_reboot(struct mc_request *req); +extern void mconsole_config(struct mc_request *req); +extern void mconsole_remove(struct mc_request *req); +extern void mconsole_sysrq(struct mc_request *req); +extern void mconsole_cad(struct mc_request *req); +extern void mconsole_stop(struct mc_request *req); +extern void mconsole_go(struct mc_request *req); +extern void mconsole_log(struct mc_request *req); +extern void mconsole_proc(struct mc_request *req); +extern void mconsole_stack(struct mc_request *req); + +extern int mconsole_get_request(int fd, struct mc_request *req); +extern int mconsole_notify(char *sock_name, int type, const void *data, + int len); +extern char *mconsole_notify_socket(void); +extern void lock_notify(void); +extern void unlock_notify(void); + +#endif diff --git a/arch/um/drivers/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h new file mode 100644 index 0000000..d2fe07e --- /dev/null +++ b/arch/um/drivers/mconsole_kern.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __MCONSOLE_KERN_H__ +#define __MCONSOLE_KERN_H__ + +#include "linux/list.h" +#include "mconsole.h" + +struct mconsole_entry { + struct list_head list; + struct mc_request request; +}; + +/* All these methods are called in process context. */ +struct mc_device { + struct list_head list; + char *name; + int (*config)(char *, char **); + int (*get_config)(char *, char *, int, char **); + int (*id)(char **, int *, int *); + int (*remove)(int, char **); +}; + +#define CONFIG_CHUNK(str, size, current, chunk, end) \ +do { \ + current += strlen(chunk); \ + if(current >= size) \ + str = NULL; \ + if(str != NULL){ \ + strcpy(str, chunk); \ + str += strlen(chunk); \ + } \ + if(end) \ + current++; \ +} while(0) + +#ifdef CONFIG_MCONSOLE + +extern void mconsole_register_dev(struct mc_device *new); + +#else + +static inline void mconsole_register_dev(struct mc_device *new) +{ +} + +#endif + +#endif diff --git a/arch/um/include/shared/mconsole.h b/arch/um/include/shared/mconsole.h deleted file mode 100644 index c139ae1..0000000 --- a/arch/um/include/shared/mconsole.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __MCONSOLE_H__ -#define __MCONSOLE_H__ - -#ifndef __KERNEL__ -#include -#define u32 uint32_t -#endif - -#include "sysdep/ptrace.h" - -#define MCONSOLE_MAGIC (0xcafebabe) -#define MCONSOLE_MAX_DATA (512) -#define MCONSOLE_VERSION 2 - -struct mconsole_request { - u32 magic; - u32 version; - u32 len; - char data[MCONSOLE_MAX_DATA]; -}; - -struct mconsole_reply { - u32 err; - u32 more; - u32 len; - char data[MCONSOLE_MAX_DATA]; -}; - -struct mconsole_notify { - u32 magic; - u32 version; - enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, - MCONSOLE_USER_NOTIFY } type; - u32 len; - char data[MCONSOLE_MAX_DATA]; -}; - -struct mc_request; - -enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC }; - -struct mconsole_command -{ - char *command; - void (*handler)(struct mc_request *req); - enum mc_context context; -}; - -struct mc_request -{ - int len; - int as_interrupt; - - int originating_fd; - unsigned int originlen; - unsigned char origin[128]; /* sockaddr_un */ - - struct mconsole_request request; - struct mconsole_command *cmd; - struct uml_pt_regs regs; -}; - -extern char mconsole_socket_name[]; - -extern int mconsole_unlink_socket(void); -extern int mconsole_reply_len(struct mc_request *req, const char *reply, - int len, int err, int more); -extern int mconsole_reply(struct mc_request *req, const char *str, int err, - int more); - -extern void mconsole_version(struct mc_request *req); -extern void mconsole_help(struct mc_request *req); -extern void mconsole_halt(struct mc_request *req); -extern void mconsole_reboot(struct mc_request *req); -extern void mconsole_config(struct mc_request *req); -extern void mconsole_remove(struct mc_request *req); -extern void mconsole_sysrq(struct mc_request *req); -extern void mconsole_cad(struct mc_request *req); -extern void mconsole_stop(struct mc_request *req); -extern void mconsole_go(struct mc_request *req); -extern void mconsole_log(struct mc_request *req); -extern void mconsole_proc(struct mc_request *req); -extern void mconsole_stack(struct mc_request *req); - -extern int mconsole_get_request(int fd, struct mc_request *req); -extern int mconsole_notify(char *sock_name, int type, const void *data, - int len); -extern char *mconsole_notify_socket(void); -extern void lock_notify(void); -extern void unlock_notify(void); - -#endif diff --git a/arch/um/include/shared/mconsole_kern.h b/arch/um/include/shared/mconsole_kern.h deleted file mode 100644 index d2fe07e..0000000 --- a/arch/um/include/shared/mconsole_kern.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __MCONSOLE_KERN_H__ -#define __MCONSOLE_KERN_H__ - -#include "linux/list.h" -#include "mconsole.h" - -struct mconsole_entry { - struct list_head list; - struct mc_request request; -}; - -/* All these methods are called in process context. */ -struct mc_device { - struct list_head list; - char *name; - int (*config)(char *, char **); - int (*get_config)(char *, char *, int, char **); - int (*id)(char **, int *, int *); - int (*remove)(int, char **); -}; - -#define CONFIG_CHUNK(str, size, current, chunk, end) \ -do { \ - current += strlen(chunk); \ - if(current >= size) \ - str = NULL; \ - if(str != NULL){ \ - strcpy(str, chunk); \ - str += strlen(chunk); \ - } \ - if(end) \ - current++; \ -} while(0) - -#ifdef CONFIG_MCONSOLE - -extern void mconsole_register_dev(struct mc_device *new); - -#else - -static inline void mconsole_register_dev(struct mc_device *new) -{ -} - -#endif - -#endif -- cgit v1.1 From fced95cacfc21b441ab33f5e7bbc750327e80325 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:08:49 +0100 Subject: um: kill um_uaccess.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/uaccess.h | 89 +++++++++++++++++++++++++++++++++-- arch/um/include/shared/um_uaccess.h | 94 ------------------------------------- 2 files changed, 84 insertions(+), 99 deletions(-) delete mode 100644 arch/um/include/shared/um_uaccess.h (limited to 'arch/um') diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index b9a895d..3f22fbf 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -6,15 +6,15 @@ #ifndef __UM_UACCESS_H #define __UM_UACCESS_H -#include -#include - /* thread_info has a mm_segment_t in it, so put the definition up here */ typedef struct { unsigned long seg; } mm_segment_t; -#include "linux/thread_info.h" +#include +#include +#include +#include #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -38,7 +38,86 @@ typedef struct { #define segment_eq(a, b) ((a).seg == (b).seg) -#include "um_uaccess.h" +#define __under_task_size(addr, size) \ + (((unsigned long) (addr) < TASK_SIZE) && \ + (((unsigned long) (addr) + (size)) < TASK_SIZE)) + +#define __access_ok_vsyscall(type, addr, size) \ + ((type == VERIFY_READ) && \ + ((unsigned long) (addr) >= FIXADDR_USER_START) && \ + ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ + ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) + +#define __addr_range_nowrap(addr, size) \ + ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) + +#define access_ok(type, addr, size) \ + (__addr_range_nowrap(addr, size) && \ + (__under_task_size(addr, size) || \ + __access_ok_vsyscall(type, addr, size) || \ + segment_eq(get_fs(), KERNEL_DS))) + +extern int copy_from_user(void *to, const void __user *from, int n); +extern int copy_to_user(void __user *to, const void *from, int n); + +/* + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ + +extern int strncpy_from_user(char *dst, const char __user *src, int count); + +/* + * __clear_user: - Zero a block of memory in user space, with less checking. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int __clear_user(void __user *mem, int len); + +/* + * clear_user: - Zero a block of memory in user space. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int clear_user(void __user *mem, int len); + +/* + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * @n: The maximum valid length + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. + */ +extern int strnlen_user(const void __user *str, int len); #define __copy_from_user(to, from, n) copy_from_user(to, from, n) diff --git a/arch/um/include/shared/um_uaccess.h b/arch/um/include/shared/um_uaccess.h deleted file mode 100644 index 51e1cce..0000000 --- a/arch/um/include/shared/um_uaccess.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_UACCESS_H -#define __ARCH_UM_UACCESS_H - -#include -#include -#include "sysdep/archsetjmp.h" - -#define __under_task_size(addr, size) \ - (((unsigned long) (addr) < TASK_SIZE) && \ - (((unsigned long) (addr) + (size)) < TASK_SIZE)) - -#define __access_ok_vsyscall(type, addr, size) \ - ((type == VERIFY_READ) && \ - ((unsigned long) (addr) >= FIXADDR_USER_START) && \ - ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ - ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) - -#define __addr_range_nowrap(addr, size) \ - ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) - -#define access_ok(type, addr, size) \ - (__addr_range_nowrap(addr, size) && \ - (__under_task_size(addr, size) || \ - __access_ok_vsyscall(type, addr, size) || \ - segment_eq(get_fs(), KERNEL_DS))) - -extern int copy_from_user(void *to, const void __user *from, int n); -extern int copy_to_user(void __user *to, const void *from, int n); - -/* - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ - -extern int strncpy_from_user(char *dst, const char __user *src, int count); - -/* - * __clear_user: - Zero a block of memory in user space, with less checking. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int __clear_user(void __user *mem, int len); - -/* - * clear_user: - Zero a block of memory in user space. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int clear_user(void __user *mem, int len); - -/* - * strlen_user: - Get the size of a string in user space. - * @str: The string to measure. - * @n: The maximum valid length - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * If the string is too long, returns a value greater than @n. - */ -extern int strnlen_user(const void __user *str, int len); - -#endif -- cgit v1.1 From 4dc706c2f292b2c28016a27f400af84a62ec4a63 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:09:09 +0100 Subject: um: take um_mmu.h to asm/mmu.h, clean asm/mmu_context.h a bit Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/mmu.h | 22 +++++++++++++++++----- arch/um/include/asm/mmu_context.h | 7 ++----- arch/um/include/shared/um_mmu.h | 24 ------------------------ 3 files changed, 19 insertions(+), 34 deletions(-) delete mode 100644 arch/um/include/shared/um_mmu.h (limited to 'arch/um') diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index cf259de..b1a7e47 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -1,12 +1,24 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ARCH_UM_MMU_H +#define __ARCH_UM_MMU_H -#include "um_mmu.h" +#include "mm_id.h" +#include "ldt.h" -#endif +typedef struct mm_context { + struct mm_id id; + struct uml_ldt ldt; + struct page **stub_pages; +} mm_context_t; + +extern void __switch_mm(struct mm_id * mm_idp); +/* Avoid tangled inclusion with asm/ldt.h */ +extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); +extern void free_ldt(struct mm_context *mm); + +#endif diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 34d8130..591b3d8 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -6,15 +6,12 @@ #ifndef __UM_MMU_CONTEXT_H #define __UM_MMU_CONTEXT_H -#include "linux/sched.h" -#include "um_mmu.h" +#include +#include extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm); extern void arch_exit_mmap(struct mm_struct *mm); -#define get_mmu_context(task) do ; while(0) -#define activate_context(tsk) do ; while(0) - #define deactivate_mm(tsk,mm) do { } while (0) extern void force_flush_all(void); diff --git a/arch/um/include/shared/um_mmu.h b/arch/um/include/shared/um_mmu.h deleted file mode 100644 index b1a7e47..0000000 --- a/arch/um/include/shared/um_mmu.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_MMU_H -#define __ARCH_UM_MMU_H - -#include "mm_id.h" -#include "ldt.h" - -typedef struct mm_context { - struct mm_id id; - struct uml_ldt ldt; - struct page **stub_pages; -} mm_context_t; - -extern void __switch_mm(struct mm_id * mm_idp); - -/* Avoid tangled inclusion with asm/ldt.h */ -extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); -extern void free_ldt(struct mm_context *mm); - -#endif -- cgit v1.1 From c5cc32fe14ccbc19484202d20cf7d6bad45e3567 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:09:39 +0100 Subject: um: move asm/desc.h into arch/x86/um/asm its only purpose is to shadow the x86 asm/desc.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/desc.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 arch/um/include/asm/desc.h (limited to 'arch/um') diff --git a/arch/um/include/asm/desc.h b/arch/um/include/asm/desc.h deleted file mode 100644 index 4ec34a5..0000000 --- a/arch/um/include/asm/desc.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __UM_DESC_H -#define __UM_DESC_H - -/* Taken from asm-i386/desc.h, it's the only thing we need. The rest wouldn't - * compile, and has never been used. */ -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif -- cgit v1.1 From 1bbd5f21f426d99660ea8120b79595a282e5ff8a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:09:49 +0100 Subject: um: merge os-Linux/tls.c into arch/x86/um/os-Linux/tls.c it's i386-specific; moreover, analogs on other targets have incompatible interface - PTRACE_GET_THREAD_AREA does exist elsewhere, but struct user_desc does *not* Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 5 ----- arch/um/os-Linux/Makefile | 4 ++-- arch/um/os-Linux/tls.c | 35 ----------------------------------- 3 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 arch/um/os-Linux/tls.c (limited to 'arch/um') diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index caa6661..89b686c1 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -10,7 +10,6 @@ #include "irq_user.h" #include "longjmp.h" #include "mm_id.h" -#include "sysdep/tls.h" #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) @@ -212,10 +211,6 @@ extern int run_helper_thread(int (*proc)(void *), void *arg, extern int helper_wait(int pid); -/* tls.c */ -extern int os_set_thread_area(user_desc_t *info, int pid); -extern int os_get_thread_area(user_desc_t *info, int pid); - /* umid.c */ extern int umid_file_name(char *name, char *buf, int len); extern int set_umid(char *name); diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 015d000..dd76410 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -5,13 +5,13 @@ obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ - umid.o tls.o user_syms.o util.o drivers/ skas/ + umid.o user_syms.o util.o drivers/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o tls.o umid.o util.o + tty.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c deleted file mode 100644 index 73277801..0000000 --- a/arch/um/os-Linux/tls.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include "sysdep/tls.h" - -/* TLS support - we basically rely on the host's one.*/ - -#ifndef PTRACE_GET_THREAD_AREA -#define PTRACE_GET_THREAD_AREA 25 -#endif - -#ifndef PTRACE_SET_THREAD_AREA -#define PTRACE_SET_THREAD_AREA 26 -#endif - -int os_set_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} - -int os_get_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} -- cgit v1.1 From b3ee571e58120de30c3d15657022bf2c72477e02 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:10:49 +0100 Subject: um: take ldt.h to arch/x86/um/asm/mm_context.h it's x86-only and we have no business playing with it in asm/mmu.h; make the latter have struct uml_arch_mm_context arch; instead of struct uml_ldt ldt; and let arch//um/asm/mm_context.h decide what'll be in there. While we are at it, kill host_ldt.h - it's not needed in part of places that include it (we want asm/ldt.h in those) and it can be trivially expanded into the single remaining one. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/mmu.h | 4 ++-- arch/um/include/shared/ldt.h | 37 ------------------------------------- 2 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 arch/um/include/shared/ldt.h (limited to 'arch/um') diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index b1a7e47..30509b9 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -7,11 +7,11 @@ #define __ARCH_UM_MMU_H #include "mm_id.h" -#include "ldt.h" +#include typedef struct mm_context { struct mm_id id; - struct uml_ldt ldt; + struct uml_arch_mm_context arch; struct page **stub_pages; } mm_context_t; diff --git a/arch/um/include/shared/ldt.h b/arch/um/include/shared/ldt.h deleted file mode 100644 index a7f999a..0000000 --- a/arch/um/include/shared/ldt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Licensed under the GPL - * - * Author: Bodo Stroesser - */ - -#ifndef __ASM_LDT_H -#define __ASM_LDT_H - -#include -#include - -extern void ldt_host_info(void); - -#define LDT_PAGES_MAX \ - ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE) -#define LDT_ENTRIES_PER_PAGE \ - (PAGE_SIZE/LDT_ENTRY_SIZE) -#define LDT_DIRECT_ENTRIES \ - ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE) - -struct ldt_entry { - __u32 a; - __u32 b; -}; - -typedef struct uml_ldt { - int entry_count; - struct mutex lock; - union { - struct ldt_entry * pages[LDT_PAGES_MAX]; - struct ldt_entry entries[LDT_DIRECT_ENTRIES]; - } u; -} uml_ldt_t; - -#endif -- cgit v1.1 From c506c0e4a730b436b082fa398ec1d8ae9433b2eb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:10:59 +0100 Subject: um: take ubd_user.h to its users... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/ubd_user.h | 16 ++++++++++++++++ arch/um/include/shared/ubd_user.h | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 arch/um/drivers/ubd_user.h delete mode 100644 arch/um/include/shared/ubd_user.h (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_user.h b/arch/um/drivers/ubd_user.h new file mode 100644 index 0000000..3845051 --- /dev/null +++ b/arch/um/drivers/ubd_user.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com) + * Licensed under the GPL + */ + +#ifndef __UM_UBD_USER_H +#define __UM_UBD_USER_H + +extern void ignore_sigwinch_sig(void); +extern int start_io_thread(unsigned long sp, int *fds_out); +extern int io_thread(void *arg); +extern int kernel_fd; + +#endif + diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/include/shared/ubd_user.h deleted file mode 100644 index 3845051..0000000 --- a/arch/um/include/shared/ubd_user.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com) - * Licensed under the GPL - */ - -#ifndef __UM_UBD_USER_H -#define __UM_UBD_USER_H - -extern void ignore_sigwinch_sig(void); -extern int start_io_thread(unsigned long sp, int *fds_out); -extern int io_thread(void *arg); -extern int kernel_fd; - -#endif - -- cgit v1.1 From 8807c1d56121269a27ad973c6adda18cc4c6a099 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:09 +0100 Subject: um: asm/apic.h is there only to shadow the x86 one... ... so take it to arch/um/x86/asm. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/apic.h | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 arch/um/include/asm/apic.h (limited to 'arch/um') diff --git a/arch/um/include/asm/apic.h b/arch/um/include/asm/apic.h deleted file mode 100644 index 876dee8..0000000 --- a/arch/um/include/asm/apic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __UM_APIC_H -#define __UM_APIC_H - -#endif -- cgit v1.1 From ff9586e98feaf6c2df0c936075e3cbb31045b99e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:19 +0100 Subject: um: required-features.h is there only to shadow x86 one... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/required-features.h | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 arch/um/include/asm/required-features.h (limited to 'arch/um') diff --git a/arch/um/include/asm/required-features.h b/arch/um/include/asm/required-features.h deleted file mode 100644 index dfb967b..0000000 --- a/arch/um/include/asm/required-features.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __UM_REQUIRED_FEATURES_H -#define __UM_REQUIRED_FEATURES_H - -/* - * Nothing to see, just need something for the i386 and x86_64 asm - * headers to include. - */ - -#endif -- cgit v1.1 From 3fb77d7256f442e8e15d51f111bb6cf096d4a9f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:29 +0100 Subject: um: irq_vectors.h just shadows x86 one Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/irq_vectors.h | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 arch/um/include/asm/irq_vectors.h (limited to 'arch/um') diff --git a/arch/um/include/asm/irq_vectors.h b/arch/um/include/asm/irq_vectors.h deleted file mode 100644 index 272a81e..0000000 --- a/arch/um/include/asm/irq_vectors.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_IRQ_VECTORS_H -#define __UM_IRQ_VECTORS_H - -#endif - -- cgit v1.1 From c32324e31270514638d6d2df38436590862e0d8f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:39 +0100 Subject: um: page_offset.h is never used ... and neither is the only define in it Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/page_offset.h | 1 - 1 file changed, 1 deletion(-) delete mode 100644 arch/um/include/asm/page_offset.h (limited to 'arch/um') diff --git a/arch/um/include/asm/page_offset.h b/arch/um/include/asm/page_offset.h deleted file mode 100644 index 1c168df..0000000 --- a/arch/um/include/asm/page_offset.h +++ /dev/null @@ -1 +0,0 @@ -#define PAGE_OFFSET_RAW (uml_physmem) -- cgit v1.1 From 4d211093e838ddd049b5cf4f0773aa5ac67f9976 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:49 +0100 Subject: um: fix gcov build breakage a) exports in gmon_syms.c duplicate kernel/gcov/* ones b) excluding -pg in vdso compile is not enough - -fprofile-arcs and -ftest-coverage also needs to be excluded Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/kernel/gmon_syms.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 72eccd2..e9bcf247 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c @@ -7,18 +7,3 @@ extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); - -/* - * This is defined (and referred to in profiling stub code) only by some GCC - * versions in libgcov. - * - * Since SuSE backported the fix, we cannot handle it depending on GCC version. - * So, unconditionally export it. But also give it a weak declaration, which - * will be overridden by any other one. - */ - -extern void __gcov_init(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_init); - -extern void __gcov_merge_add(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_merge_add); -- cgit v1.1 From 966e803ab12538faf2b236dbe83f7fb796a031d6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:12:19 +0100 Subject: um: unify ptrace_user.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/ptrace_user.h | 3 ++- arch/um/os-Linux/skas/process.c | 3 +-- arch/um/os-Linux/start_up.c | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'arch/um') diff --git a/arch/um/include/shared/ptrace_user.h b/arch/um/include/shared/ptrace_user.h index 7fd8539..56b2f28 100644 --- a/arch/um/include/shared/ptrace_user.h +++ b/arch/um/include/shared/ptrace_user.h @@ -6,7 +6,8 @@ #ifndef __PTRACE_USER_H__ #define __PTRACE_USER_H__ -#include "sysdep/ptrace_user.h" +#include +#include extern int ptrace_getregs(long pid, unsigned long *regs_out); extern int ptrace_setregs(long pid, unsigned long *regs_in); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 6c34f14..cd65727 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include "as-layout.h" @@ -162,7 +161,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, if (!local_using_sysemu) { - err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); if (err < 0) { printk(UM_KERN_ERR "handle_trap - nullifying syscall " diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index b698680..425162e 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -224,7 +223,7 @@ static void __init check_sysemu(void) goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); @@ -260,7 +259,7 @@ static void __init check_sysemu(void) "doesn't singlestep"); goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) fatal_perror("check_sysemu : failed to modify " @@ -316,10 +315,10 @@ static void __init check_ptrace(void) fatal("check_ptrace : expected (SIGTRAP|0x80), " "got status = %d", status); - syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0); if (syscall == __NR_getpid) { - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getppid); if (n < 0) fatal_perror("check_ptrace : failed to modify " -- cgit v1.1 From 772bd0a5a5ebfd37186df086c0f51f676495c4d9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:12:39 +0100 Subject: um: kill useless argument of free_chan() and free_one_chan() delay_free_irq is always 0 for those... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/drivers/chan_kern.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index e040683..420e2c8 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -358,11 +358,11 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out, return 0; } -static void free_one_chan(struct chan *chan, int delay_free_irq) +static void free_one_chan(struct chan *chan) { list_del(&chan->list); - close_one_chan(chan, delay_free_irq); + close_one_chan(chan, 0); if (chan->ops->free != NULL) (*chan->ops->free)(chan->data); @@ -372,14 +372,14 @@ static void free_one_chan(struct chan *chan, int delay_free_irq) kfree(chan); } -static void free_chan(struct list_head *chans, int delay_free_irq) +static void free_chan(struct list_head *chans) { struct list_head *ele, *next; struct chan *chan; list_for_each_safe(ele, next, chans) { chan = list_entry(ele, struct chan, list); - free_one_chan(chan, delay_free_irq); + free_one_chan(chan); } } @@ -547,7 +547,7 @@ int parse_chan_pair(char *str, struct line *line, int device, char *in, *out; if (!list_empty(chans)) { - free_chan(chans, 0); + free_chan(chans); INIT_LIST_HEAD(chans); } -- cgit v1.1 From d805a78603bb489d71a12466e8f29c5e9837e50a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:00 +0100 Subject: um: clean Kconfig up a bit * kill duplicates with drivers/char/Kconfig * take watchdog one into drivers/watchdog/Kconfig * take mmapper to arch/um/Kconfig.um * rename Kconfig.char menu to "UML Character Devices" Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Kconfig.char | 114 +-------------------------------------------------- arch/um/Kconfig.um | 6 +++ 2 files changed, 7 insertions(+), 113 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 70dabd1..b9d7c42 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -1,5 +1,4 @@ - -menu "Character Devices" +menu "UML Character Devices" config STDERR_CONSOLE bool "stderr console" @@ -105,92 +104,6 @@ config SSL_CHAN this if you expect the UML that you build to be run in environments which don't have a set of /dev/pty* devices. -config UNIX98_PTYS - bool "Unix98 PTY support" - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx for - masters and /dev/ttyxx for slaves of pseudo terminals. This scheme - has a number of problems. The GNU C library glibc 2.1 and later, - however, supports the Unix98 naming standard: in order to acquire a - pseudo terminal, a process opens /dev/ptmx; the number of the pseudo - terminal is then made available to the process and the pseudo - terminal slave can be accessed as /dev/pts/. What was - traditionally /dev/ttyp2 will then be /dev/pts/2, for example. - - All modern Linux systems use the Unix98 ptys. Say Y unless - you're on an embedded system and want to conserve memory. - -config LEGACY_PTYS - bool "Legacy (BSD) PTY support" - default y - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx - for masters and /dev/ttyxx for slaves of pseudo - terminals. This scheme has a number of problems, including - security. This option enables these legacy devices; on most - systems, it is safe to say N. - -config RAW_DRIVER - tristate "RAW driver (/dev/raw/rawN)" - depends on BLOCK - help - The raw driver permits block devices to be bound to /dev/raw/rawN. - Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. - See the raw(8) manpage for more details. - - Applications should preferably open the device (eg /dev/hda1) - with the O_DIRECT flag. - -config MAX_RAW_DEVS - int "Maximum number of RAW devices to support (1-8192)" - depends on RAW_DRIVER - default "256" - help - The maximum number of RAW devices that are supported. - Default is 256. Increase this number in case you need lots of - raw devices. - -config LEGACY_PTY_COUNT - int "Maximum number of legacy PTY in use" - depends on LEGACY_PTYS - default "256" - help - The maximum number of legacy PTYs that can be used at any one time. - The default is 256, and should be more than enough. Embedded - systems may want to reduce this to save memory. - - When not in use, each legacy PTY occupies 12 bytes on 32-bit - architectures and 24 bytes on 64-bit architectures. - -config WATCHDOG - bool "Watchdog Timer Support" - -config WATCHDOG_NOWAYOUT - bool "Disable watchdog shutdown on close" - depends on WATCHDOG - -config SOFT_WATCHDOG - tristate "Software Watchdog" - depends on WATCHDOG - -config UML_WATCHDOG - tristate "UML watchdog" - depends on WATCHDOG - config UML_SOUND tristate "Sound support" help @@ -211,29 +124,4 @@ config HOSTAUDIO tristate default UML_SOUND -#It is selected elsewhere, so kconfig would warn without this. -config HW_RANDOM - tristate - default n - -config UML_RANDOM - tristate "Hardware random number generator" - help - This option enables UML's "hardware" random number generator. It - attaches itself to the host's /dev/random, supplying as much entropy - as the host has, rather than the small amount the UML gets from its - own drivers. It registers itself as a standard hardware random number - generator, major 10, minor 183, and the canonical device name is - /dev/hwrng. - The way to make use of this is to install the rng-tools package - (check your distro, or download from - http://sourceforge.net/projects/gkernel/). rngd periodically reads - /dev/hwrng and injects the entropy into /dev/random. - -config MMAPPER - tristate "iomem emulation driver" - help - This driver allows a host file to be used as emulated IO memory inside - UML. - endmenu diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index b5e675e..70fd690 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -148,5 +148,11 @@ config KERNEL_STACK_ORDER be 1 << order pages. The default is OK unless you're running Valgrind on UML, in which case, set this to 3. +config MMAPPER + tristate "iomem emulation driver" + help + This driver allows a host file to be used as emulated IO memory inside + UML. + config NO_DMA def_bool y -- cgit v1.1 From f5e900770f387d7a4c633b7cef105039f32a85c1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:10 +0100 Subject: um: switch to generic-y kill wrapper headers Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/Kbuild | 2 ++ arch/um/include/asm/bug.h | 6 ------ arch/um/include/asm/cputime.h | 6 ------ arch/um/include/asm/device.h | 7 ------- arch/um/include/asm/emergency-restart.h | 6 ------ arch/um/include/asm/futex.h | 6 ------ arch/um/include/asm/hardirq.h | 1 - arch/um/include/asm/irq_regs.h | 1 - arch/um/include/asm/kdebug.h | 1 - arch/um/include/asm/percpu.h | 6 ------ arch/um/include/asm/sections.h | 7 ------- arch/um/include/asm/topology.h | 6 ------ arch/um/include/asm/xor.h | 6 ------ 13 files changed, 2 insertions(+), 59 deletions(-) create mode 100644 arch/um/include/asm/Kbuild delete mode 100644 arch/um/include/asm/bug.h delete mode 100644 arch/um/include/asm/cputime.h delete mode 100644 arch/um/include/asm/device.h delete mode 100644 arch/um/include/asm/emergency-restart.h delete mode 100644 arch/um/include/asm/futex.h delete mode 100644 arch/um/include/asm/hardirq.h delete mode 100644 arch/um/include/asm/irq_regs.h delete mode 100644 arch/um/include/asm/kdebug.h delete mode 100644 arch/um/include/asm/percpu.h delete mode 100644 arch/um/include/asm/sections.h delete mode 100644 arch/um/include/asm/topology.h delete mode 100644 arch/um/include/asm/xor.h (limited to 'arch/um') diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild new file mode 100644 index 0000000..e16895d --- /dev/null +++ b/arch/um/include/asm/Kbuild @@ -0,0 +1,2 @@ +generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h +generic-y += irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h diff --git a/arch/um/include/asm/bug.h b/arch/um/include/asm/bug.h deleted file mode 100644 index 9e33b86..0000000 --- a/arch/um/include/asm/bug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_BUG_H -#define __UM_BUG_H - -#include - -#endif diff --git a/arch/um/include/asm/cputime.h b/arch/um/include/asm/cputime.h deleted file mode 100644 index c84acba..0000000 --- a/arch/um/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CPUTIME_H -#define __UM_CPUTIME_H - -#include - -#endif /* __UM_CPUTIME_H */ diff --git a/arch/um/include/asm/device.h b/arch/um/include/asm/device.h deleted file mode 100644 index d8f9872..0000000 --- a/arch/um/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/arch/um/include/asm/emergency-restart.h b/arch/um/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c4..0000000 --- a/arch/um/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h deleted file mode 100644 index 6a332a9..0000000 --- a/arch/um/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include - -#endif diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h deleted file mode 100644 index fb3c05a..0000000 --- a/arch/um/include/asm/hardirq.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/um/include/asm/irq_regs.h b/arch/um/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b..0000000 --- a/arch/um/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/um/include/asm/kdebug.h b/arch/um/include/asm/kdebug.h deleted file mode 100644 index 6ece1b0..0000000 --- a/arch/um/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/um/include/asm/percpu.h b/arch/um/include/asm/percpu.h deleted file mode 100644 index efe7508..0000000 --- a/arch/um/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_PERCPU_H -#define __UM_PERCPU_H - -#include - -#endif /* __UM_PERCPU_H */ diff --git a/arch/um/include/asm/sections.h b/arch/um/include/asm/sections.h deleted file mode 100644 index 6b0231e..0000000 --- a/arch/um/include/asm/sections.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _UM_SECTIONS_H -#define _UM_SECTIONS_H - -/* nothing to see, move along */ -#include - -#endif diff --git a/arch/um/include/asm/topology.h b/arch/um/include/asm/topology.h deleted file mode 100644 index 0905e4f..0000000 --- a/arch/um/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_TOPOLOGY_H -#define _ASM_UM_TOPOLOGY_H - -#include - -#endif diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h deleted file mode 100644 index a19db3e..0000000 --- a/arch/um/include/asm/xor.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_XOR_H -#define __UM_XOR_H - -#include "asm-generic/xor.h" - -#endif -- cgit v1.1 From 8e66cda4af84321b308825f1c70aff6bffa30b35 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:20 +0100 Subject: um: hw_irq.h can go generic as well Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/Kbuild | 2 +- arch/um/include/asm/hw_irq.h | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 arch/um/include/asm/hw_irq.h (limited to 'arch/um') diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index e16895d..5962826 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -1,2 +1,2 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h -generic-y += irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h +generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h diff --git a/arch/um/include/asm/hw_irq.h b/arch/um/include/asm/hw_irq.h deleted file mode 100644 index 1cf84cf..0000000 --- a/arch/um/include/asm/hw_irq.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _ASM_UM_HW_IRQ_H -#define _ASM_UM_HW_IRQ_H - -#include "asm/irq.h" -#include "asm/archparam.h" - -#endif -- cgit v1.1 From c2ad3ad009cbef8eb2f550809d2c2c3ed8e04a8d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:30 +0100 Subject: um: asm/pda.h is not needed anymore Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/pda.h | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 arch/um/include/asm/pda.h (limited to 'arch/um') diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h deleted file mode 100644 index ddcd774..0000000 --- a/arch/um/include/asm/pda.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PDA_X86_64_H -#define __UM_PDA_X86_64_H - -/* XXX */ -struct foo { - unsigned int __softirq_pending; - unsigned int __nmi_count; -}; - -extern struct foo me; - -#define read_pda(me) (&me) - -#endif - -- cgit v1.1 From 46ecca8ae1540abe73000d0fb4878de6956a208f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:40 +0100 Subject: um: segment.h is x86-only and needed only there Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/segment.h | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 arch/um/include/asm/segment.h (limited to 'arch/um') diff --git a/arch/um/include/asm/segment.h b/arch/um/include/asm/segment.h deleted file mode 100644 index 45183fc..0000000 --- a/arch/um/include/asm/segment.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __UM_SEGMENT_H -#define __UM_SEGMENT_H - -extern int host_gdt_entry_tls_min; - -#define GDT_ENTRY_TLS_ENTRIES 3 -#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min -#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) - -#endif -- cgit v1.1 From b8c655d727ebfe78769b62a0349227d5a656e967 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:13:50 +0100 Subject: um: generic ftrace.h will do... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/Kbuild | 1 + arch/um/include/asm/ftrace.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 arch/um/include/asm/ftrace.h (limited to 'arch/um') diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 5962826..451f451 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -1,2 +1,3 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h +generic-y += ftrace.h diff --git a/arch/um/include/asm/ftrace.h b/arch/um/include/asm/ftrace.h deleted file mode 100644 index 40a8c17..0000000 --- a/arch/um/include/asm/ftrace.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ -- cgit v1.1 From a34978cbd977ab62c744f63daacd9dc1474482be Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:14:00 +0100 Subject: um: kill system-um.h most of it belonged in irqflags.h, actually Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++++++- arch/um/include/asm/system-um.h | 45 ----------------------------------------- 2 files changed, 37 insertions(+), 46 deletions(-) delete mode 100644 arch/um/include/asm/system-um.h (limited to 'arch/um') diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 659b9ab..c780d8a 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -1,6 +1,42 @@ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H -/* Empty for now */ +extern int get_signals(void); +extern int set_signals(int enable); +extern void block_signals(void); +extern void unblock_signals(void); + +static inline unsigned long arch_local_save_flags(void) +{ + return get_signals(); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + set_signals(flags); +} + +static inline void arch_local_irq_enable(void) +{ + unblock_signals(); +} + +static inline void arch_local_irq_disable(void) +{ + block_signals(); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_local_save_flags() == 0; +} #endif diff --git a/arch/um/include/asm/system-um.h b/arch/um/include/asm/system-um.h deleted file mode 100644 index 0eec245..0000000 --- a/arch/um/include/asm/system-um.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __UM_SYSTEM_GENERIC_H -#define __UM_SYSTEM_GENERIC_H - -extern int get_signals(void); -extern int set_signals(int enable); -extern void block_signals(void); -extern void unblock_signals(void); - -static inline unsigned long arch_local_save_flags(void) -{ - return get_signals(); -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - set_signals(flags); -} - -static inline void arch_local_irq_enable(void) -{ - unblock_signals(); -} - -static inline void arch_local_irq_disable(void) -{ - block_signals(); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_local_save_flags() == 0; -} - -extern void *_switch_to(void *prev, void *next, void *last); -#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) - -#endif -- cgit v1.1 From 73395a0002aa9573ffc8d989587b79663847f705 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:14:10 +0100 Subject: um: distribute exports to where exported stuff is defined ksyms.c is down to the stuff defined in various USER_OBJS Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/kernel/exec.c | 18 ++++++++++-------- arch/um/kernel/irq.c | 1 + arch/um/kernel/ksyms.c | 38 +------------------------------------- arch/um/kernel/mem.c | 2 ++ arch/um/kernel/physmem.c | 21 ++++++++++++--------- arch/um/kernel/process.c | 2 ++ arch/um/kernel/skas/uaccess.c | 6 ++++++ arch/um/kernel/tlb.c | 2 ++ arch/um/kernel/trap.c | 2 ++ arch/um/kernel/um_arch.c | 2 ++ 10 files changed, 40 insertions(+), 54 deletions(-) (limited to 'arch/um') diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 939a4a6..6cade93 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -3,14 +3,15 @@ * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/fs.h" -#include "linux/ptrace.h" -#include "linux/sched.h" -#include "linux/slab.h" -#include "asm/current.h" -#include "asm/processor.h" -#include "asm/uaccess.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "as-layout.h" #include "mem_user.h" #include "skas.h" @@ -41,6 +42,7 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; } +EXPORT_SYMBOL(start_thread); static long execve1(const char *file, const char __user *const __user *argv, diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 9e485c7..71b8c94 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -258,6 +258,7 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } +EXPORT_SYMBOL(deactivate_fd); /* * Called just before shutdown in order to provide a clean exec diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0ae0dfc..e17bea0 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -3,33 +3,11 @@ * Licensed under the GPL */ -#include "linux/module.h" -#include "linux/syscalls.h" -#include "asm/tlbflush.h" -#include "asm/uaccess.h" -#include "as-layout.h" -#include "kern_util.h" -#include "mem_user.h" +#include #include "os.h" -EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(sys_waitpid); -EXPORT_SYMBOL(flush_tlb_range); - -EXPORT_SYMBOL(high_physmem); -EXPORT_SYMBOL(empty_zero_page); -EXPORT_SYMBOL(handle_page_fault); -EXPORT_SYMBOL(find_iomem); - -EXPORT_SYMBOL(strnlen_user); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(uml_strdup); EXPORT_SYMBOL(os_stat_fd); EXPORT_SYMBOL(os_stat_file); @@ -57,24 +35,10 @@ EXPORT_SYMBOL(os_connect_socket); EXPORT_SYMBOL(os_accept_connection); EXPORT_SYMBOL(os_rcv_fd); EXPORT_SYMBOL(run_helper); -EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(os_major); EXPORT_SYMBOL(os_minor); EXPORT_SYMBOL(os_makedev); EXPORT_SYMBOL(add_sigio_fd); EXPORT_SYMBOL(ignore_sigio_fd); -EXPORT_SYMBOL(deactivate_fd); EXPORT_SYMBOL(sigio_broken); - -#ifdef CONFIG_SMP - -/* required for SMP */ - -extern void __write_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__write_lock_failed); - -extern void __read_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__read_lock_failed); - -#endif diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 8137ccc..ebb86b2 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -20,6 +21,7 @@ /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ unsigned long *empty_zero_page = NULL; +EXPORT_SYMBOL(empty_zero_page); /* allocated in paging_init and unchanged thereafter */ static unsigned long *empty_bad_page = NULL; diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index a1a9090..f116db1 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -3,20 +3,22 @@ * Licensed under the GPL */ -#include "linux/bootmem.h" -#include "linux/mm.h" -#include "linux/pfn.h" -#include "asm/page.h" -#include "as-layout.h" -#include "init.h" -#include "kern.h" -#include "mem_user.h" -#include "os.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static int physmem_fd = -1; /* Changed during early boot */ unsigned long high_physmem; +EXPORT_SYMBOL(high_physmem); extern unsigned long long physmem_size; @@ -184,6 +186,7 @@ unsigned long find_iomem(char *driver, unsigned long *len_out) return 0; } +EXPORT_SYMBOL(find_iomem); static int setup_iomem(void) { diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index db44142..c533835 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -78,6 +78,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ¤t->thread.regs, 0, NULL, NULL); return pid; } +EXPORT_SYMBOL(kernel_thread); static inline void set_current(struct task_struct *task) { @@ -286,6 +287,7 @@ char *uml_strdup(const char *string) { return kstrdup(string, GFP_KERNEL); } +EXPORT_SYMBOL(uml_strdup); int copy_to_user_proc(void __user *to, void *from, int size) { diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 6966342..9fefd92 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -149,6 +150,7 @@ int copy_from_user(void *to, const void __user *from, int n) buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): n; } +EXPORT_SYMBOL(copy_from_user); static int copy_chunk_to_user(unsigned long to, int len, void *arg) { @@ -170,6 +172,7 @@ int copy_to_user(void __user *to, const void *from, int n) buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : n; } +EXPORT_SYMBOL(copy_to_user); static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) { @@ -204,6 +207,7 @@ int strncpy_from_user(char *dst, const char __user *src, int count) return -EFAULT; return strnlen(dst, count); } +EXPORT_SYMBOL(strncpy_from_user); static int clear_chunk(unsigned long addr, int len, void *unused) { @@ -226,6 +230,7 @@ int clear_user(void __user *mem, int len) return access_ok(VERIFY_WRITE, mem, len) ? buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; } +EXPORT_SYMBOL(clear_user); static int strnlen_chunk(unsigned long str, int len, void *arg) { @@ -251,3 +256,4 @@ int strnlen_user(const void __user *str, int len) return count + 1; return -EFAULT; } +EXPORT_SYMBOL(strnlen_user); diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 11cadb2..7f3d4d86 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -498,6 +499,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, flush_tlb_kernel_range_common(start, end); else fix_range(vma->vm_mm, start, end, 0); } +EXPORT_SYMBOL(flush_tlb_range); void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index f2a2036..dafc947 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,7 @@ out_of_memory: pagefault_out_of_memory(); return 0; } +EXPORT_SYMBOL(handle_page_fault); static void show_segv_info(struct uml_pt_regs *regs) { diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8d84250..ba00eae 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -102,6 +102,8 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long uml_physmem; +EXPORT_SYMBOL(uml_physmem); + unsigned long uml_reserved; /* Also modified in mem_init */ unsigned long start_vm; unsigned long end_vm; -- cgit v1.1 From 3369465ed1a6a9aa9b885a6d7d8e074ecbd782da Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Aug 2011 20:11:59 +0100 Subject: um: switch to use of drivers/Kconfig Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/Kconfig.rest | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'arch/um') diff --git a/arch/um/Kconfig.rest b/arch/um/Kconfig.rest index 0ccad0f..567eb5f 100644 --- a/arch/um/Kconfig.rest +++ b/arch/um/Kconfig.rest @@ -2,20 +2,14 @@ source "init/Kconfig" source "kernel/Kconfig.freezer" -source "drivers/block/Kconfig" - source "arch/um/Kconfig.char" -source "drivers/base/Kconfig" +source "drivers/Kconfig" source "net/Kconfig" source "arch/um/Kconfig.net" -source "drivers/net/Kconfig" - -source "drivers/connector/Kconfig" - source "fs/Kconfig" source "security/Kconfig" @@ -24,19 +18,4 @@ source "crypto/Kconfig" source "lib/Kconfig" -source "drivers/scsi/Kconfig" - -source "drivers/md/Kconfig" - -if BROKEN - source "drivers/mtd/Kconfig" -endif - -source "drivers/leds/Kconfig" - -#This is just to shut up some Kconfig warnings, so no prompt. -config INPUT - tristate - default n - source "arch/um/Kconfig.debug" -- cgit v1.1 From 8535639810e578960233ad39def3ac2157b0c3ec Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 2 Nov 2011 13:17:27 +0100 Subject: um: fix ubd cow size ubd_file_size() cannot use ubd_dev->cow.file because at this time ubd_dev->cow.file is not initialized. Therefore, ubd_file_size() will always report a wrong disk size when COW files are used. Reading from /dev/ubd* would crash the kernel. We have to read the correct disk size from the COW file's backing file. Signed-off-by: Richard Weinberger CC: stable@kernel.org --- arch/um/drivers/ubd_kern.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'arch/um') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index b3c8545..944453a 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -511,8 +511,37 @@ __uml_exitcall(kill_io_thread); static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; + int fd; + int err; + + __u32 version; + __u32 align; + char *backing_file; + time_t mtime; + unsigned long long size; + int sector_size; + int bitmap_offset; + + if (ubd_dev->file && ubd_dev->cow.file) { + file = ubd_dev->cow.file; + + goto out; + } - file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; + fd = os_open_file(ubd_dev->file, global_openflags, 0); + if (fd < 0) + return fd; + + err = read_cow_header(file_reader, &fd, &version, &backing_file, \ + &mtime, &size, §or_size, &align, &bitmap_offset); + os_close_file(fd); + + if(err == -EINVAL) + file = ubd_dev->file; + else + file = backing_file; + +out: return os_file_size(file, size_out); } -- cgit v1.1