diff options
| -rw-r--r-- | arch/um/Kconfig.um | 1 | ||||
| -rw-r--r-- | arch/um/Makefile | 2 | ||||
| -rw-r--r-- | arch/um/configs/i386_defconfig | 1 | ||||
| -rw-r--r-- | arch/um/configs/x86_64_defconfig | 1 | ||||
| -rw-r--r-- | arch/um/include/asm/thread_info.h | 3 | ||||
| -rw-r--r-- | arch/um/include/shared/os.h | 2 | ||||
| -rw-r--r-- | arch/um/kernel/gmon_syms.c | 7 | ||||
| -rw-r--r-- | arch/um/kernel/process.c | 4 | ||||
| -rw-r--r-- | arch/um/os-Linux/drivers/tuntap_user.c | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/skas/process.c | 17 | ||||
| -rw-r--r-- | arch/um/os-Linux/start_up.c | 6 | ||||
| -rw-r--r-- | arch/x86/um/os-Linux/registers.c | 18 | ||||
| -rw-r--r-- | arch/x86/um/os-Linux/tls.c | 2 | ||||
| -rw-r--r-- | arch/x86/um/user-offsets.c | 2 |
14 files changed, 41 insertions, 27 deletions
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index 4b2ed5858b2e..e26376ab5452 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um | |||
| @@ -20,6 +20,7 @@ config LD_SCRIPT_DYN | |||
| 20 | bool | 20 | bool |
| 21 | default y | 21 | default y |
| 22 | depends on !LD_SCRIPT_STATIC | 22 | depends on !LD_SCRIPT_STATIC |
| 23 | select MODULE_REL_CRCS if MODVERSIONS | ||
| 23 | 24 | ||
| 24 | source "fs/Kconfig.binfmt" | 25 | source "fs/Kconfig.binfmt" |
| 25 | 26 | ||
diff --git a/arch/um/Makefile b/arch/um/Makefile index 6ca4f66085c1..b76fcce397a1 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
| @@ -121,7 +121,7 @@ archheaders: | |||
| 121 | archprepare: include/generated/user_constants.h | 121 | archprepare: include/generated/user_constants.h |
| 122 | 122 | ||
| 123 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 123 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
| 124 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib | 124 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie) |
| 125 | 125 | ||
| 126 | CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ | 126 | CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ |
| 127 | $(call cc-option, -fno-stack-protector,) \ | 127 | $(call cc-option, -fno-stack-protector,) \ |
diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index 5636221b8785..8f114e3b0a7a 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig | |||
| @@ -53,7 +53,6 @@ CONFIG_NET=y | |||
| 53 | CONFIG_PACKET=y | 53 | CONFIG_PACKET=y |
| 54 | CONFIG_UNIX=y | 54 | CONFIG_UNIX=y |
| 55 | CONFIG_INET=y | 55 | CONFIG_INET=y |
| 56 | # CONFIG_INET_LRO is not set | ||
| 57 | # CONFIG_IPV6 is not set | 56 | # CONFIG_IPV6 is not set |
| 58 | CONFIG_UML_NET=y | 57 | CONFIG_UML_NET=y |
| 59 | CONFIG_UML_NET_ETHERTAP=y | 58 | CONFIG_UML_NET_ETHERTAP=y |
diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index 7a67b7ac1a7e..5d0875fc0db2 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig | |||
| @@ -51,7 +51,6 @@ CONFIG_NET=y | |||
| 51 | CONFIG_PACKET=y | 51 | CONFIG_PACKET=y |
| 52 | CONFIG_UNIX=y | 52 | CONFIG_UNIX=y |
| 53 | CONFIG_INET=y | 53 | CONFIG_INET=y |
| 54 | # CONFIG_INET_LRO is not set | ||
| 55 | # CONFIG_IPV6 is not set | 54 | # CONFIG_IPV6 is not set |
| 56 | CONFIG_UML_NET=y | 55 | CONFIG_UML_NET=y |
| 57 | CONFIG_UML_NET_ETHERTAP=y | 56 | CONFIG_UML_NET_ETHERTAP=y |
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 053baff03674..9300f7630d2a 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <asm/types.h> | 11 | #include <asm/types.h> |
| 12 | #include <asm/page.h> | 12 | #include <asm/page.h> |
| 13 | #include <asm/segment.h> | 13 | #include <asm/segment.h> |
| 14 | #include <sysdep/ptrace_user.h> | ||
| 14 | 15 | ||
| 15 | struct thread_info { | 16 | struct thread_info { |
| 16 | struct task_struct *task; /* main task structure */ | 17 | struct task_struct *task; /* main task structure */ |
| @@ -22,6 +23,8 @@ struct thread_info { | |||
| 22 | 0-0xBFFFFFFF for user | 23 | 0-0xBFFFFFFF for user |
| 23 | 0-0xFFFFFFFF for kernel */ | 24 | 0-0xFFFFFFFF for kernel */ |
| 24 | struct thread_info *real_thread; /* Points to non-IRQ stack */ | 25 | struct thread_info *real_thread; /* Points to non-IRQ stack */ |
| 26 | unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore | ||
| 27 | them out-of-band */ | ||
| 25 | }; | 28 | }; |
| 26 | 29 | ||
| 27 | #define INIT_THREAD_INFO(tsk) \ | 30 | #define INIT_THREAD_INFO(tsk) \ |
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 574e03fc7ba2..d8ddaf9790d2 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h | |||
| @@ -278,7 +278,7 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr, | |||
| 278 | extern int is_skas_winch(int pid, int fd, void *data); | 278 | extern int is_skas_winch(int pid, int fd, void *data); |
| 279 | extern int start_userspace(unsigned long stub_stack); | 279 | extern int start_userspace(unsigned long stub_stack); |
| 280 | extern int copy_context_skas0(unsigned long stack, int pid); | 280 | extern int copy_context_skas0(unsigned long stack, int pid); |
| 281 | extern void userspace(struct uml_pt_regs *regs); | 281 | extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); |
| 282 | extern int map_stub_pages(int fd, unsigned long code, unsigned long data, | 282 | extern int map_stub_pages(int fd, unsigned long code, unsigned long data, |
| 283 | unsigned long stack); | 283 | unsigned long stack); |
| 284 | extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); | 284 | extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); |
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 1bf61266da8e..f138a4a0db99 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c | |||
| @@ -7,3 +7,10 @@ | |||
| 7 | 7 | ||
| 8 | extern void __bb_init_func(void *) __attribute__((weak)); | 8 | extern void __bb_init_func(void *) __attribute__((weak)); |
| 9 | EXPORT_SYMBOL(__bb_init_func); | 9 | EXPORT_SYMBOL(__bb_init_func); |
| 10 | |||
| 11 | extern void __gcov_init(void *) __attribute__((weak)); | ||
| 12 | EXPORT_SYMBOL(__gcov_init); | ||
| 13 | extern void __gcov_merge_add(void *, unsigned int) __attribute__((weak)); | ||
| 14 | EXPORT_SYMBOL(__gcov_merge_add); | ||
| 15 | extern void __gcov_exit(void) __attribute__((weak)); | ||
| 16 | EXPORT_SYMBOL(__gcov_exit); | ||
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2c7f721eccbc..691b83b10649 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
| @@ -131,7 +131,7 @@ void new_thread_handler(void) | |||
| 131 | * callback returns only if the kernel thread execs a process | 131 | * callback returns only if the kernel thread execs a process |
| 132 | */ | 132 | */ |
| 133 | n = fn(arg); | 133 | n = fn(arg); |
| 134 | userspace(¤t->thread.regs.regs); | 134 | userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | /* Called magically, see new_thread_handler above */ | 137 | /* Called magically, see new_thread_handler above */ |
| @@ -150,7 +150,7 @@ void fork_handler(void) | |||
| 150 | 150 | ||
| 151 | current->thread.prev_sched = NULL; | 151 | current->thread.prev_sched = NULL; |
| 152 | 152 | ||
| 153 | userspace(¤t->thread.regs.regs); | 153 | userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | int copy_thread(unsigned long clone_flags, unsigned long sp, | 156 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index c2e6e1dad876..db24ce0d09a6 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c | |||
| @@ -80,7 +80,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, | |||
| 80 | pid = run_helper(tuntap_pre_exec, &data, argv); | 80 | pid = run_helper(tuntap_pre_exec, &data, argv); |
| 81 | 81 | ||
| 82 | if (pid < 0) | 82 | if (pid < 0) |
| 83 | return -pid; | 83 | return pid; |
| 84 | 84 | ||
| 85 | close(remote); | 85 | close(remote); |
| 86 | 86 | ||
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 819d68656673..c94c3bd70ccd 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -88,12 +88,11 @@ bad_wait: | |||
| 88 | 88 | ||
| 89 | extern unsigned long current_stub_stack(void); | 89 | extern unsigned long current_stub_stack(void); |
| 90 | 90 | ||
| 91 | static void get_skas_faultinfo(int pid, struct faultinfo *fi) | 91 | static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs) |
| 92 | { | 92 | { |
| 93 | int err; | 93 | int err; |
| 94 | unsigned long fpregs[FP_SIZE]; | ||
| 95 | 94 | ||
| 96 | err = get_fp_registers(pid, fpregs); | 95 | err = get_fp_registers(pid, aux_fp_regs); |
| 97 | if (err < 0) { | 96 | if (err < 0) { |
| 98 | printk(UM_KERN_ERR "save_fp_registers returned %d\n", | 97 | printk(UM_KERN_ERR "save_fp_registers returned %d\n", |
| 99 | err); | 98 | err); |
| @@ -113,7 +112,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) | |||
| 113 | */ | 112 | */ |
| 114 | memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); | 113 | memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); |
| 115 | 114 | ||
| 116 | err = put_fp_registers(pid, fpregs); | 115 | err = put_fp_registers(pid, aux_fp_regs); |
| 117 | if (err < 0) { | 116 | if (err < 0) { |
| 118 | printk(UM_KERN_ERR "put_fp_registers returned %d\n", | 117 | printk(UM_KERN_ERR "put_fp_registers returned %d\n", |
| 119 | err); | 118 | err); |
| @@ -121,9 +120,9 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) | |||
| 121 | } | 120 | } |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | static void handle_segv(int pid, struct uml_pt_regs * regs) | 123 | static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs) |
| 125 | { | 124 | { |
| 126 | get_skas_faultinfo(pid, ®s->faultinfo); | 125 | get_skas_faultinfo(pid, ®s->faultinfo, aux_fp_regs); |
| 127 | segv(regs->faultinfo, 0, 1, NULL); | 126 | segv(regs->faultinfo, 0, 1, NULL); |
| 128 | } | 127 | } |
| 129 | 128 | ||
| @@ -332,7 +331,7 @@ int start_userspace(unsigned long stub_stack) | |||
| 332 | return err; | 331 | return err; |
| 333 | } | 332 | } |
| 334 | 333 | ||
| 335 | void userspace(struct uml_pt_regs *regs) | 334 | void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) |
| 336 | { | 335 | { |
| 337 | int err, status, op, pid = userspace_pid[0]; | 336 | int err, status, op, pid = userspace_pid[0]; |
| 338 | /* To prevent races if using_sysemu changes under us.*/ | 337 | /* To prevent races if using_sysemu changes under us.*/ |
| @@ -407,11 +406,11 @@ void userspace(struct uml_pt_regs *regs) | |||
| 407 | case SIGSEGV: | 406 | case SIGSEGV: |
| 408 | if (PTRACE_FULL_FAULTINFO) { | 407 | if (PTRACE_FULL_FAULTINFO) { |
| 409 | get_skas_faultinfo(pid, | 408 | get_skas_faultinfo(pid, |
| 410 | ®s->faultinfo); | 409 | ®s->faultinfo, aux_fp_regs); |
| 411 | (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, | 410 | (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, |
| 412 | regs); | 411 | regs); |
| 413 | } | 412 | } |
| 414 | else handle_segv(pid, regs); | 413 | else handle_segv(pid, regs, aux_fp_regs); |
| 415 | break; | 414 | break; |
| 416 | case SIGTRAP + 0x80: | 415 | case SIGTRAP + 0x80: |
| 417 | handle_trap(pid, regs, local_using_sysemu); | 416 | handle_trap(pid, regs, local_using_sysemu); |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index b1b6b75c5b17..82bf5f8442ba 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
| @@ -154,10 +154,10 @@ static int __init nosysemu_cmd_param(char *str, int* add) | |||
| 154 | 154 | ||
| 155 | __uml_setup("nosysemu", nosysemu_cmd_param, | 155 | __uml_setup("nosysemu", nosysemu_cmd_param, |
| 156 | "nosysemu\n" | 156 | "nosysemu\n" |
| 157 | " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" | 157 | " Turns off syscall emulation patch for ptrace (SYSEMU).\n" |
| 158 | " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" | 158 | " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" |
| 159 | " behaviour of ptrace() and helps reducing host context switch rate.\n" | 159 | " behaviour of ptrace() and helps reduce host context switch rates.\n" |
| 160 | " To make it working, you need a kernel patch for your host, too.\n" | 160 | " To make it work, you need a kernel patch for your host, too.\n" |
| 161 | " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n" | 161 | " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n" |
| 162 | " information.\n\n"); | 162 | " information.\n\n"); |
| 163 | 163 | ||
diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c index 28775f55bde2..3c423dfcd78b 100644 --- a/arch/x86/um/os-Linux/registers.c +++ b/arch/x86/um/os-Linux/registers.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <errno.h> | 7 | #include <errno.h> |
| 8 | #include <stdlib.h> | ||
| 8 | #include <sys/ptrace.h> | 9 | #include <sys/ptrace.h> |
| 9 | #ifdef __i386__ | 10 | #ifdef __i386__ |
| 10 | #include <sys/user.h> | 11 | #include <sys/user.h> |
| @@ -31,7 +32,7 @@ int save_fp_registers(int pid, unsigned long *fp_regs) | |||
| 31 | 32 | ||
| 32 | if (have_xstate_support) { | 33 | if (have_xstate_support) { |
| 33 | iov.iov_base = fp_regs; | 34 | iov.iov_base = fp_regs; |
| 34 | iov.iov_len = sizeof(struct _xstate); | 35 | iov.iov_len = FP_SIZE * sizeof(unsigned long); |
| 35 | if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) | 36 | if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) |
| 36 | return -errno; | 37 | return -errno; |
| 37 | return 0; | 38 | return 0; |
| @@ -51,10 +52,9 @@ int restore_fp_registers(int pid, unsigned long *fp_regs) | |||
| 51 | { | 52 | { |
| 52 | #ifdef PTRACE_SETREGSET | 53 | #ifdef PTRACE_SETREGSET |
| 53 | struct iovec iov; | 54 | struct iovec iov; |
| 54 | |||
| 55 | if (have_xstate_support) { | 55 | if (have_xstate_support) { |
| 56 | iov.iov_base = fp_regs; | 56 | iov.iov_base = fp_regs; |
| 57 | iov.iov_len = sizeof(struct _xstate); | 57 | iov.iov_len = FP_SIZE * sizeof(unsigned long); |
| 58 | if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) | 58 | if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) |
| 59 | return -errno; | 59 | return -errno; |
| 60 | return 0; | 60 | return 0; |
| @@ -125,13 +125,19 @@ int put_fp_registers(int pid, unsigned long *regs) | |||
| 125 | void arch_init_registers(int pid) | 125 | void arch_init_registers(int pid) |
| 126 | { | 126 | { |
| 127 | #ifdef PTRACE_GETREGSET | 127 | #ifdef PTRACE_GETREGSET |
| 128 | struct _xstate fp_regs; | 128 | void * fp_regs; |
| 129 | struct iovec iov; | 129 | struct iovec iov; |
| 130 | 130 | ||
| 131 | iov.iov_base = &fp_regs; | 131 | fp_regs = malloc(FP_SIZE * sizeof(unsigned long)); |
| 132 | iov.iov_len = sizeof(struct _xstate); | 132 | if(fp_regs == NULL) |
| 133 | return; | ||
| 134 | |||
| 135 | iov.iov_base = fp_regs; | ||
| 136 | iov.iov_len = FP_SIZE * sizeof(unsigned long); | ||
| 133 | if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0) | 137 | if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0) |
| 134 | have_xstate_support = 1; | 138 | have_xstate_support = 1; |
| 139 | |||
| 140 | free(fp_regs); | ||
| 135 | #endif | 141 | #endif |
| 136 | } | 142 | } |
| 137 | #endif | 143 | #endif |
diff --git a/arch/x86/um/os-Linux/tls.c b/arch/x86/um/os-Linux/tls.c index 9d94b3b76c74..ed8ea90967dc 100644 --- a/arch/x86/um/os-Linux/tls.c +++ b/arch/x86/um/os-Linux/tls.c | |||
| @@ -37,7 +37,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) | |||
| 37 | continue; | 37 | continue; |
| 38 | else if (errno == ENOSYS) | 38 | else if (errno == ENOSYS) |
| 39 | *supports_tls = 0; | 39 | *supports_tls = 0; |
| 40 | return; | 40 | return; |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | 43 | ||
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index 02250b2633b8..3099c209546f 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c | |||
| @@ -51,7 +51,7 @@ void foo(void) | |||
| 51 | DEFINE(HOST_ORIG_AX, ORIG_EAX); | 51 | DEFINE(HOST_ORIG_AX, ORIG_EAX); |
| 52 | #else | 52 | #else |
| 53 | #ifdef FP_XSTATE_MAGIC1 | 53 | #ifdef FP_XSTATE_MAGIC1 |
| 54 | DEFINE(HOST_FP_SIZE, sizeof(struct _xstate) / sizeof(unsigned long)); | 54 | DEFINE_LONGS(HOST_FP_SIZE, 2696); |
| 55 | #else | 55 | #else |
| 56 | DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); | 56 | DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); |
| 57 | #endif | 57 | #endif |
