diff options
Diffstat (limited to 'arch/um')
| -rw-r--r-- | arch/um/drivers/cow_user.c | 2 | ||||
| -rw-r--r-- | arch/um/include/longjmp.h | 4 | ||||
| -rw-r--r-- | arch/um/include/sysdep-i386/kernel-offsets.h | 2 | ||||
| -rw-r--r-- | arch/um/include/sysdep-x86_64/kernel-offsets.h | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/mem.c | 118 | ||||
| -rw-r--r-- | arch/um/os-Linux/process.c | 8 | ||||
| -rw-r--r-- | arch/um/os-Linux/skas/process.c | 36 | ||||
| -rw-r--r-- | arch/um/os-Linux/start_up.c | 24 | ||||
| -rw-r--r-- | arch/um/os-Linux/trap.c | 4 | ||||
| -rw-r--r-- | arch/um/os-Linux/uaccess.c | 4 | ||||
| -rw-r--r-- | arch/um/os-Linux/util.c | 2 | ||||
| -rw-r--r-- | arch/um/sys-i386/signal.c | 6 | ||||
| -rw-r--r-- | arch/um/sys-i386/stub_segv.c | 4 | ||||
| -rw-r--r-- | arch/um/sys-x86_64/stub_segv.c | 10 | 
14 files changed, 162 insertions, 64 deletions
| diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 0ec4052db9c5..6ab852bfcd3a 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
| @@ -100,7 +100,7 @@ struct cow_header_v3_broken { | |||
| 100 | __u32 alignment; | 100 | __u32 alignment; | 
| 101 | __u32 cow_format; | 101 | __u32 cow_format; | 
| 102 | char backing_file[PATH_LEN_V3]; | 102 | char backing_file[PATH_LEN_V3]; | 
| 103 | }; | 103 | } __attribute__((packed)); | 
| 104 | 104 | ||
| 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 
| 106 | #define COW_BITMAP 0 | 106 | #define COW_BITMAP 0 | 
| diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h index 018b3819ab0b..8e7053013f7b 100644 --- a/arch/um/include/longjmp.h +++ b/arch/um/include/longjmp.h | |||
| @@ -4,11 +4,11 @@ | |||
| 4 | #include <setjmp.h> | 4 | #include <setjmp.h> | 
| 5 | #include "os.h" | 5 | #include "os.h" | 
| 6 | 6 | ||
| 7 | #define UML_SIGLONGJMP(buf, val) do { \ | 7 | #define UML_LONGJMP(buf, val) do { \ | 
| 8 | longjmp(*buf, val); \ | 8 | longjmp(*buf, val); \ | 
| 9 | } while(0) | 9 | } while(0) | 
| 10 | 10 | ||
| 11 | #define UML_SIGSETJMP(buf, enable) ({ \ | 11 | #define UML_SETJMP(buf, enable) ({ \ | 
| 12 | int n; \ | 12 | int n; \ | 
| 13 | enable = get_signals(); \ | 13 | enable = get_signals(); \ | 
| 14 | n = setjmp(*buf); \ | 14 | n = setjmp(*buf); \ | 
| diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h index 82f96c574144..2c13de321f2f 100644 --- a/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/arch/um/include/sysdep-i386/kernel-offsets.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include <linux/stddef.h> | 1 | #include <linux/stddef.h> | 
| 2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> | 
| 3 | #include <linux/elf.h> | 3 | #include <linux/elf.h> | 
| 4 | #include <asm/mman.h> | ||
| 4 | 5 | ||
| 5 | #define DEFINE(sym, val) \ | 6 | #define DEFINE(sym, val) \ | 
| 6 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 7 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 
| @@ -16,6 +17,7 @@ | |||
| 16 | void foo(void) | 17 | void foo(void) | 
| 17 | { | 18 | { | 
| 18 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | 19 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | 
| 20 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
| 19 | #ifdef CONFIG_MODE_TT | 21 | #ifdef CONFIG_MODE_TT | 
| 20 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 
| 21 | #endif | 23 | #endif | 
| diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 5ce93abd0b54..939cc475757a 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/time.h> | 4 | #include <linux/time.h> | 
| 5 | #include <linux/elf.h> | 5 | #include <linux/elf.h> | 
| 6 | #include <asm/page.h> | 6 | #include <asm/page.h> | 
| 7 | #include <asm/mman.h> | ||
| 7 | 8 | ||
| 8 | #define DEFINE(sym, val) \ | 9 | #define DEFINE(sym, val) \ | 
| 9 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 10 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 
| @@ -18,6 +19,7 @@ | |||
| 18 | 19 | ||
| 19 | void foo(void) | 20 | void foo(void) | 
| 20 | { | 21 | { | 
| 22 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
| 21 | #ifdef CONFIG_MODE_TT | 23 | #ifdef CONFIG_MODE_TT | 
| 22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 24 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 
| 23 | #endif | 25 | #endif | 
| diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 71bb90a7606d..c6432e729241 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <fcntl.h> | 8 | #include <fcntl.h> | 
| 9 | #include <sys/types.h> | 9 | #include <sys/types.h> | 
| 10 | #include <sys/mman.h> | 10 | #include <sys/mman.h> | 
| 11 | #include <sys/statfs.h> | ||
| 11 | #include "kern_util.h" | 12 | #include "kern_util.h" | 
| 12 | #include "user.h" | 13 | #include "user.h" | 
| 13 | #include "user_util.h" | 14 | #include "user_util.h" | 
| @@ -19,6 +20,7 @@ | |||
| 19 | 20 | ||
| 20 | #include <sys/param.h> | 21 | #include <sys/param.h> | 
| 21 | 22 | ||
| 23 | static char *default_tmpdir = "/tmp"; | ||
| 22 | static char *tempdir = NULL; | 24 | static char *tempdir = NULL; | 
| 23 | 25 | ||
| 24 | static void __init find_tempdir(void) | 26 | static void __init find_tempdir(void) | 
| @@ -34,7 +36,7 @@ static void __init find_tempdir(void) | |||
| 34 | break; | 36 | break; | 
| 35 | } | 37 | } | 
| 36 | if((dir == NULL) || (*dir == '\0')) | 38 | if((dir == NULL) || (*dir == '\0')) | 
| 37 | dir = "/tmp"; | 39 | dir = default_tmpdir; | 
| 38 | 40 | ||
| 39 | tempdir = malloc(strlen(dir) + 2); | 41 | tempdir = malloc(strlen(dir) + 2); | 
| 40 | if(tempdir == NULL){ | 42 | if(tempdir == NULL){ | 
| @@ -46,6 +48,96 @@ static void __init find_tempdir(void) | |||
| 46 | strcat(tempdir, "/"); | 48 | strcat(tempdir, "/"); | 
| 47 | } | 49 | } | 
| 48 | 50 | ||
| 51 | /* This will return 1, with the first character in buf being the | ||
| 52 | * character following the next instance of c in the file. This will | ||
| 53 | * read the file as needed. If there's an error, -errno is returned; | ||
| 54 | * if the end of the file is reached, 0 is returned. | ||
| 55 | */ | ||
| 56 | static int next(int fd, char *buf, int size, char c) | ||
| 57 | { | ||
| 58 | int n; | ||
| 59 | char *ptr; | ||
| 60 | |||
| 61 | while((ptr = strchr(buf, c)) == NULL){ | ||
| 62 | n = read(fd, buf, size - 1); | ||
| 63 | if(n == 0) | ||
| 64 | return 0; | ||
| 65 | else if(n < 0) | ||
| 66 | return -errno; | ||
| 67 | |||
| 68 | buf[n] = '\0'; | ||
| 69 | } | ||
| 70 | |||
| 71 | ptr++; | ||
| 72 | memmove(buf, ptr, strlen(ptr) + 1); | ||
| 73 | return 1; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int checked_tmpdir = 0; | ||
| 77 | |||
| 78 | /* Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner | ||
| 79 | * way to do this than to parse /proc/mounts. statfs will return the | ||
| 80 | * same filesystem magic number and fs id for both /dev and /dev/shm | ||
| 81 | * when they are both tmpfs, so you can't tell if they are different | ||
| 82 | * filesystems. Also, there seems to be no other way of finding the | ||
| 83 | * mount point of a filesystem from within it. | ||
| 84 | * | ||
| 85 | * If a /dev/shm tmpfs entry is found, then we switch to using it. | ||
| 86 | * Otherwise, we stay with the default /tmp. | ||
| 87 | */ | ||
| 88 | static void which_tmpdir(void) | ||
| 89 | { | ||
| 90 | int fd, found; | ||
| 91 | char buf[128] = { '\0' }; | ||
| 92 | |||
| 93 | if(checked_tmpdir) | ||
| 94 | return; | ||
| 95 | |||
| 96 | checked_tmpdir = 1; | ||
| 97 | |||
| 98 | printf("Checking for tmpfs mount on /dev/shm..."); | ||
| 99 | |||
| 100 | fd = open("/proc/mounts", O_RDONLY); | ||
| 101 | if(fd < 0){ | ||
| 102 | printf("failed to open /proc/mounts, errno = %d\n", errno); | ||
| 103 | return; | ||
| 104 | } | ||
| 105 | |||
| 106 | while(1){ | ||
| 107 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
| 108 | if(found != 1) | ||
| 109 | break; | ||
| 110 | |||
| 111 | if(!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) | ||
| 112 | goto found; | ||
| 113 | |||
| 114 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n'); | ||
| 115 | if(found != 1) | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | |||
| 119 | err: | ||
| 120 | if(found == 0) | ||
| 121 | printf("nothing mounted on /dev/shm\n"); | ||
| 122 | else if(found < 0) | ||
| 123 | printf("read returned errno %d\n", -found); | ||
| 124 | |||
| 125 | return; | ||
| 126 | |||
| 127 | found: | ||
| 128 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
| 129 | if(found != 1) | ||
| 130 | goto err; | ||
| 131 | |||
| 132 | if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ | ||
| 133 | printf("not tmpfs\n"); | ||
| 134 | return; | ||
| 135 | } | ||
| 136 | |||
| 137 | printf("OK\n"); | ||
| 138 | default_tmpdir = "/dev/shm"; | ||
| 139 | } | ||
| 140 | |||
| 49 | /* | 141 | /* | 
| 50 | * This proc still used in tt-mode | 142 | * This proc still used in tt-mode | 
| 51 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | 143 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | 
| @@ -56,6 +148,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink) | |||
| 56 | char *tempname; | 148 | char *tempname; | 
| 57 | int fd; | 149 | int fd; | 
| 58 | 150 | ||
| 151 | which_tmpdir(); | ||
| 59 | tempname = malloc(MAXPATHLEN); | 152 | tempname = malloc(MAXPATHLEN); | 
| 60 | 153 | ||
| 61 | find_tempdir(); | 154 | find_tempdir(); | 
| @@ -137,3 +230,26 @@ int create_mem_file(unsigned long long len) | |||
| 137 | } | 230 | } | 
| 138 | return(fd); | 231 | return(fd); | 
| 139 | } | 232 | } | 
| 233 | |||
| 234 | |||
| 235 | void check_tmpexec(void) | ||
| 236 | { | ||
| 237 | void *addr; | ||
| 238 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
| 239 | |||
| 240 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
| 241 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
| 242 | printf("Checking PROT_EXEC mmap in %s...",tempdir); | ||
| 243 | fflush(stdout); | ||
| 244 | if(addr == MAP_FAILED){ | ||
| 245 | err = errno; | ||
| 246 | perror("failed"); | ||
| 247 | if(err == EPERM) | ||
| 248 | printf("%s must be not mounted noexec\n",tempdir); | ||
| 249 | exit(1); | ||
| 250 | } | ||
| 251 | printf("OK\n"); | ||
| 252 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
| 253 | |||
| 254 | close(fd); | ||
| 255 | } | ||
| diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 8176b0b52047..3505f44f8a25 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
| @@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len) | |||
| 190 | } | 190 | } | 
| 191 | 191 | ||
| 192 | #ifndef MADV_REMOVE | 192 | #ifndef MADV_REMOVE | 
| 193 | #define MADV_REMOVE 0x5 /* remove these pages & resources */ | 193 | #define MADV_REMOVE KERNEL_MADV_REMOVE | 
| 194 | #endif | 194 | #endif | 
| 195 | 195 | ||
| 196 | int os_drop_memory(void *addr, int length) | 196 | int os_drop_memory(void *addr, int length) | 
| @@ -216,7 +216,7 @@ int can_drop_memory(void) | |||
| 216 | } | 216 | } | 
| 217 | 217 | ||
| 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 
| 219 | MAP_PRIVATE, fd, 0); | 219 | MAP_SHARED, fd, 0); | 
| 220 | if(addr == MAP_FAILED){ | 220 | if(addr == MAP_FAILED){ | 
| 221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 
| 222 | return 0; | 222 | return 0; | 
| @@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack) | |||
| 266 | 266 | ||
| 267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 
| 268 | { | 268 | { | 
| 269 | sigjmp_buf buf; | 269 | jmp_buf buf; | 
| 270 | int n, enable; | 270 | int n, enable; | 
| 271 | 271 | ||
| 272 | *jmp_ptr = &buf; | 272 | *jmp_ptr = &buf; | 
| 273 | n = UML_SIGSETJMP(&buf, enable); | 273 | n = UML_SETJMP(&buf, enable); | 
| 274 | if(n != 0) | 274 | if(n != 0) | 
| 275 | return(n); | 275 | return(n); | 
| 276 | (*fn)(arg); | 276 | (*fn)(arg); | 
| diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 045ae0037456..0776bc18ca85 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
| 434 | void (*handler)(int)) | 434 | void (*handler)(int)) | 
| 435 | { | 435 | { | 
| 436 | unsigned long flags; | 436 | unsigned long flags; | 
| 437 | sigjmp_buf switch_buf, fork_buf; | 437 | jmp_buf switch_buf, fork_buf; | 
| 438 | int enable; | 438 | int enable; | 
| 439 | 439 | ||
| 440 | *switch_buf_ptr = &switch_buf; | 440 | *switch_buf_ptr = &switch_buf; | 
| @@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
| 450 | */ | 450 | */ | 
| 451 | flags = get_signals(); | 451 | flags = get_signals(); | 
| 452 | block_signals(); | 452 | block_signals(); | 
| 453 | if(UML_SIGSETJMP(&fork_buf, enable) == 0) | 453 | if(UML_SETJMP(&fork_buf, enable) == 0) | 
| 454 | new_thread_proc(stack, handler); | 454 | new_thread_proc(stack, handler); | 
| 455 | 455 | ||
| 456 | remove_sigstack(); | 456 | remove_sigstack(); | 
| @@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
| 466 | 466 | ||
| 467 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) | 
| 468 | { | 468 | { | 
| 469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | jmp_buf buf, **switch_buf = sw, *fork_buf; | 
| 470 | int enable; | 470 | int enable; | 
| 471 | 471 | ||
| 472 | *switch_buf = &buf; | 472 | *switch_buf = &buf; | 
| 473 | fork_buf = fb; | 473 | fork_buf = fb; | 
| 474 | if(UML_SIGSETJMP(&buf, enable) == 0) | 474 | if(UML_SETJMP(&buf, enable) == 0) | 
| 475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 
| 476 | } | 476 | } | 
| 477 | 477 | ||
| 478 | void switch_threads(void *me, void *next) | 478 | void switch_threads(void *me, void *next) | 
| 479 | { | 479 | { | 
| 480 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | 480 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; | 
| 481 | int enable; | 481 | int enable; | 
| 482 | 482 | ||
| 483 | *me_ptr = &my_buf; | 483 | *me_ptr = &my_buf; | 
| 484 | if(UML_SIGSETJMP(&my_buf, enable) == 0) | 484 | if(UML_SETJMP(&my_buf, enable) == 0) | 
| 485 | UML_SIGLONGJMP(next_buf, 1); | 485 | UML_LONGJMP(next_buf, 1); | 
| 486 | } | 486 | } | 
| 487 | 487 | ||
| 488 | static sigjmp_buf initial_jmpbuf; | 488 | static jmp_buf initial_jmpbuf; | 
| 489 | 489 | ||
| 490 | /* XXX Make these percpu */ | 490 | /* XXX Make these percpu */ | 
| 491 | static void (*cb_proc)(void *arg); | 491 | static void (*cb_proc)(void *arg); | 
| 492 | static void *cb_arg; | 492 | static void *cb_arg; | 
| 493 | static sigjmp_buf *cb_back; | 493 | static jmp_buf *cb_back; | 
| 494 | 494 | ||
| 495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 
| 496 | { | 496 | { | 
| 497 | sigjmp_buf **switch_buf = switch_buf_ptr; | 497 | jmp_buf **switch_buf = switch_buf_ptr; | 
| 498 | int n, enable; | 498 | int n, enable; | 
| 499 | 499 | ||
| 500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 
| @@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
| 502 | SIGVTALRM, -1); | 502 | SIGVTALRM, -1); | 
| 503 | 503 | ||
| 504 | *fork_buf_ptr = &initial_jmpbuf; | 504 | *fork_buf_ptr = &initial_jmpbuf; | 
| 505 | n = UML_SIGSETJMP(&initial_jmpbuf, enable); | 505 | n = UML_SETJMP(&initial_jmpbuf, enable); | 
| 506 | switch(n){ | 506 | switch(n){ | 
| 507 | case INIT_JMP_NEW_THREAD: | 507 | case INIT_JMP_NEW_THREAD: | 
| 508 | new_thread_proc((void *) stack, new_thread_handler); | 508 | new_thread_proc((void *) stack, new_thread_handler); | 
| @@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
| 512 | break; | 512 | break; | 
| 513 | case INIT_JMP_CALLBACK: | 513 | case INIT_JMP_CALLBACK: | 
| 514 | (*cb_proc)(cb_arg); | 514 | (*cb_proc)(cb_arg); | 
| 515 | UML_SIGLONGJMP(cb_back, 1); | 515 | UML_LONGJMP(cb_back, 1); | 
| 516 | break; | 516 | break; | 
| 517 | case INIT_JMP_HALT: | 517 | case INIT_JMP_HALT: | 
| 518 | kmalloc_ok = 0; | 518 | kmalloc_ok = 0; | 
| @@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
| 523 | default: | 523 | default: | 
| 524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 
| 525 | } | 525 | } | 
| 526 | UML_SIGLONGJMP(*switch_buf, 1); | 526 | UML_LONGJMP(*switch_buf, 1); | 
| 527 | } | 527 | } | 
| 528 | 528 | ||
| 529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 
| 530 | { | 530 | { | 
| 531 | sigjmp_buf here; | 531 | jmp_buf here; | 
| 532 | int enable; | 532 | int enable; | 
| 533 | 533 | ||
| 534 | cb_proc = proc; | 534 | cb_proc = proc; | 
| @@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
| 536 | cb_back = &here; | 536 | cb_back = &here; | 
| 537 | 537 | ||
| 538 | block_signals(); | 538 | block_signals(); | 
| 539 | if(UML_SIGSETJMP(&here, enable) == 0) | 539 | if(UML_SETJMP(&here, enable) == 0) | 
| 540 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 540 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 
| 541 | unblock_signals(); | 541 | unblock_signals(); | 
| 542 | 542 | ||
| 543 | cb_proc = NULL; | 543 | cb_proc = NULL; | 
| @@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
| 548 | void halt_skas(void) | 548 | void halt_skas(void) | 
| 549 | { | 549 | { | 
| 550 | block_signals(); | 550 | block_signals(); | 
| 551 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | 551 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | 
| 552 | } | 552 | } | 
| 553 | 553 | ||
| 554 | void reboot_skas(void) | 554 | void reboot_skas(void) | 
| 555 | { | 555 | { | 
| 556 | block_signals(); | 556 | block_signals(); | 
| 557 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | 557 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | 
| 558 | } | 558 | } | 
| 559 | 559 | ||
| 560 | void switch_mm_skas(struct mm_id *mm_idp) | 560 | void switch_mm_skas(struct mm_id *mm_idp) | 
| diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 387e26af301a..503148504009 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
| @@ -296,29 +296,7 @@ static void __init check_ptrace(void) | |||
| 296 | check_sysemu(); | 296 | check_sysemu(); | 
| 297 | } | 297 | } | 
| 298 | 298 | ||
| 299 | extern int create_tmp_file(unsigned long long len); | 299 | extern void check_tmpexec(void); | 
| 300 | |||
| 301 | static void check_tmpexec(void) | ||
| 302 | { | ||
| 303 | void *addr; | ||
| 304 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
| 305 | |||
| 306 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
| 307 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
| 308 | printf("Checking PROT_EXEC mmap in /tmp..."); | ||
| 309 | fflush(stdout); | ||
| 310 | if(addr == MAP_FAILED){ | ||
| 311 | err = errno; | ||
| 312 | perror("failed"); | ||
| 313 | if(err == EPERM) | ||
| 314 | printf("/tmp must be not mounted noexec\n"); | ||
| 315 | exit(1); | ||
| 316 | } | ||
| 317 | printf("OK\n"); | ||
| 318 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
| 319 | |||
| 320 | close(fd); | ||
| 321 | } | ||
| 322 | 300 | ||
| 323 | void os_early_checks(void) | 301 | void os_early_checks(void) | 
| 324 | { | 302 | { | 
| diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index a9f6b26f9828..90b29ae9af46 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c | |||
| @@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h) | |||
| 35 | 35 | ||
| 36 | void do_longjmp(void *b, int val) | 36 | void do_longjmp(void *b, int val) | 
| 37 | { | 37 | { | 
| 38 | sigjmp_buf *buf = b; | 38 | jmp_buf *buf = b; | 
| 39 | 39 | ||
| 40 | UML_SIGLONGJMP(buf, val); | 40 | UML_LONGJMP(buf, val); | 
| 41 | } | 41 | } | 
| diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index 166fb66995df..e523719330b2 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
| @@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
| 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 
| 17 | int enable; | 17 | int enable; | 
| 18 | 18 | ||
| 19 | sigjmp_buf jbuf; | 19 | jmp_buf jbuf; | 
| 20 | *fault_catcher = &jbuf; | 20 | *fault_catcher = &jbuf; | 
| 21 | if(UML_SIGSETJMP(&jbuf, enable) == 0){ | 21 | if(UML_SETJMP(&jbuf, enable) == 0){ | 
| 22 | (*op)(to, from, n); | 22 | (*op)(to, from, n); | 
| 23 | ret = 0; | 23 | ret = 0; | 
| 24 | *faulted_out = 0; | 24 | *faulted_out = 0; | 
| diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index e32065e2fdc8..c47a2a7ce70e 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
| @@ -104,7 +104,7 @@ void setup_hostinfo(void) | |||
| 104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 
| 105 | { | 105 | { | 
| 106 | va_list args; | 106 | va_list args; | 
| 107 | sigjmp_buf buf; | 107 | jmp_buf buf; | 
| 108 | int n; | 108 | int n; | 
| 109 | 109 | ||
| 110 | n = sigsetjmp(buf, 1); | 110 | n = sigsetjmp(buf, 1); | 
| diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 618fd8594643..0709fc6670c2 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
| @@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
| 57 | return(0); | 57 | return(0); | 
| 58 | } | 58 | } | 
| 59 | 59 | ||
| 60 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, | 60 | int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, | 
| 61 | struct pt_regs *regs, unsigned long sp) | 61 | struct pt_regs *regs, unsigned long sp) | 
| 62 | { | 62 | { | 
| 63 | struct sigcontext sc; | 63 | struct sigcontext sc; | 
| @@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, | |||
| 132 | return(err); | 132 | return(err); | 
| 133 | } | 133 | } | 
| 134 | 134 | ||
| 135 | int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, | 135 | int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, | 
| 136 | struct sigcontext *from, int fpsize, unsigned long sp) | 136 | struct sigcontext *from, int fpsize, unsigned long sp) | 
| 137 | { | 137 | { | 
| 138 | struct _fpstate __user *to_fp; | 138 | struct _fpstate __user *to_fp; | 
| @@ -167,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) | |||
| 167 | return(ret); | 167 | return(ret); | 
| 168 | } | 168 | } | 
| 169 | 169 | ||
| 170 | static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, | 170 | static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, | 
| 171 | struct pt_regs *from, unsigned long sp) | 171 | struct pt_regs *from, unsigned long sp) | 
| 172 | { | 172 | { | 
| 173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 
| diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index a37f672ec964..2355dc19c46c 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
| @@ -27,6 +27,6 @@ stub_segv_handler(int sig) | |||
| 27 | * the stack in its original form when we do the sigreturn here, by | 27 | * the stack in its original form when we do the sigreturn here, by | 
| 28 | * hand. | 28 | * hand. | 
| 29 | */ | 29 | */ | 
| 30 | __asm__("mov %0,%%esp ; movl %1, %%eax ; " | 30 | __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; " | 
| 31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); | 31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); | 
| 32 | } | 32 | } | 
| diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index a27099533198..1c967026c957 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c | |||
| @@ -33,7 +33,7 @@ stub_segv_handler(int sig) | |||
| 33 | struct ucontext *uc; | 33 | struct ucontext *uc; | 
| 34 | int pid; | 34 | int pid; | 
| 35 | 35 | ||
| 36 | __asm__("movq %%rdx, %0" : "=g" (uc) :); | 36 | __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); | 
| 37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 
| 38 | &uc->uc_mcontext); | 38 | &uc->uc_mcontext); | 
| 39 | 39 | ||
| @@ -44,8 +44,8 @@ stub_segv_handler(int sig) | |||
| 44 | * the signal frame. So, we use the ucontext pointer, which we know | 44 | * the signal frame. So, we use the ucontext pointer, which we know | 
| 45 | * already, to get the signal frame pointer, and add 8 to that. | 45 | * already, to get the signal frame pointer, and add 8 to that. | 
| 46 | */ | 46 | */ | 
| 47 | __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": : | 47 | __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": : | 
| 48 | "g" ((unsigned long) container_of(uc, struct rt_sigframe, | 48 | "g" ((unsigned long) | 
| 49 | uc) + 8), | 49 | container_of(uc, struct rt_sigframe, uc) + 8), | 
| 50 | "g" (__NR_rt_sigreturn)); | 50 | "g" (__NR_rt_sigreturn)); | 
| 51 | } | 51 | } | 
