diff options
| -rw-r--r-- | arch/um/include/sysdep-i386/stub.h | 29 | ||||
| -rw-r--r-- | arch/um/include/sysdep-x86_64/stub.h | 30 | ||||
| -rw-r--r-- | arch/um/kernel/skas/clone.c | 23 |
3 files changed, 46 insertions, 36 deletions
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index 6ba8cbbe0d36..b492b12b4a10 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h | |||
| @@ -6,8 +6,12 @@ | |||
| 6 | #ifndef __SYSDEP_STUB_H | 6 | #ifndef __SYSDEP_STUB_H |
| 7 | #define __SYSDEP_STUB_H | 7 | #define __SYSDEP_STUB_H |
| 8 | 8 | ||
| 9 | #include <sys/mman.h> | ||
| 9 | #include <asm/ptrace.h> | 10 | #include <asm/ptrace.h> |
| 10 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
| 12 | #include "stub-data.h" | ||
| 13 | #include "kern_constants.h" | ||
| 14 | #include "uml-config.h" | ||
| 11 | 15 | ||
| 12 | extern void stub_segv_handler(int sig); | 16 | extern void stub_segv_handler(int sig); |
| 13 | extern void stub_clone_handler(void); | 17 | extern void stub_clone_handler(void); |
| @@ -76,23 +80,22 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, | |||
| 76 | return ret; | 80 | return ret; |
| 77 | } | 81 | } |
| 78 | 82 | ||
| 79 | static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, | 83 | static inline void trap_myself(void) |
| 80 | long arg4, long arg5, long arg6) | ||
| 81 | { | 84 | { |
| 82 | long ret; | 85 | __asm("int3"); |
| 83 | |||
| 84 | __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; " | ||
| 85 | "int $0x80 ; pop %%ebp" | ||
| 86 | : "=a" (ret) | ||
| 87 | : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3), | ||
| 88 | "S" (arg4), "D" (arg5), "0" (arg6)); | ||
| 89 | |||
| 90 | return ret; | ||
| 91 | } | 86 | } |
| 92 | 87 | ||
| 93 | static inline void trap_myself(void) | 88 | static inline void remap_stack(int fd, unsigned long offset) |
| 94 | { | 89 | { |
| 95 | __asm("int3"); | 90 | __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" |
| 91 | "movl %7, %%ebx ; movl %%eax, (%%ebx)" | ||
| 92 | : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), | ||
| 93 | "c" (UM_KERN_PAGE_SIZE), | ||
| 94 | "d" (PROT_READ | PROT_WRITE), | ||
| 95 | "S" (MAP_FIXED | MAP_SHARED), "D" (fd), | ||
| 96 | "a" (offset), | ||
| 97 | "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) | ||
| 98 | : "memory"); | ||
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | #endif | 101 | #endif |
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index c41689c13dc9..92e989f81761 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h | |||
| @@ -6,8 +6,12 @@ | |||
| 6 | #ifndef __SYSDEP_STUB_H | 6 | #ifndef __SYSDEP_STUB_H |
| 7 | #define __SYSDEP_STUB_H | 7 | #define __SYSDEP_STUB_H |
| 8 | 8 | ||
| 9 | #include <sys/mman.h> | ||
| 9 | #include <asm/unistd.h> | 10 | #include <asm/unistd.h> |
| 10 | #include <sysdep/ptrace_user.h> | 11 | #include <sysdep/ptrace_user.h> |
| 12 | #include "stub-data.h" | ||
| 13 | #include "kern_constants.h" | ||
| 14 | #include "uml-config.h" | ||
| 11 | 15 | ||
| 12 | extern void stub_segv_handler(int sig); | 16 | extern void stub_segv_handler(int sig); |
| 13 | extern void stub_clone_handler(void); | 17 | extern void stub_clone_handler(void); |
| @@ -81,23 +85,23 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, | |||
| 81 | return ret; | 85 | return ret; |
| 82 | } | 86 | } |
| 83 | 87 | ||
| 84 | static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, | 88 | static inline void trap_myself(void) |
| 85 | long arg4, long arg5, long arg6) | ||
| 86 | { | 89 | { |
| 87 | long ret; | 90 | __asm("int3"); |
| 88 | |||
| 89 | __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " | ||
| 90 | "movq %7, %%r9; " __syscall : "=a" (ret) | ||
| 91 | : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), | ||
| 92 | "g" (arg4), "g" (arg5), "g" (arg6) | ||
| 93 | : __syscall_clobber, "r10", "r8", "r9" ); | ||
| 94 | |||
| 95 | return ret; | ||
| 96 | } | 91 | } |
| 97 | 92 | ||
| 98 | static inline void trap_myself(void) | 93 | static inline void remap_stack(long fd, unsigned long offset) |
| 99 | { | 94 | { |
| 100 | __asm("int3"); | 95 | __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " |
| 96 | "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " | ||
| 97 | "movq %%rax, (%%rbx)": | ||
| 98 | : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), | ||
| 99 | "S" (UM_KERN_PAGE_SIZE), | ||
| 100 | "d" (PROT_READ | PROT_WRITE), | ||
| 101 | "g" (MAP_FIXED | MAP_SHARED), "g" (fd), | ||
| 102 | "g" (offset), | ||
| 103 | "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) | ||
| 104 | : __syscall_clobber, "r10", "r8", "r9" ); | ||
| 101 | } | 105 | } |
| 102 | 106 | ||
| 103 | #endif | 107 | #endif |
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index cb37ce9124a6..47b812b3bca8 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c | |||
| @@ -18,11 +18,10 @@ | |||
| 18 | * on some systems. | 18 | * on some systems. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field) | ||
| 22 | |||
| 23 | void __attribute__ ((__section__ (".__syscall_stub"))) | 21 | void __attribute__ ((__section__ (".__syscall_stub"))) |
| 24 | stub_clone_handler(void) | 22 | stub_clone_handler(void) |
| 25 | { | 23 | { |
| 24 | struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; | ||
| 26 | long err; | 25 | long err; |
| 27 | 26 | ||
| 28 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, | 27 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, |
| @@ -35,17 +34,21 @@ stub_clone_handler(void) | |||
| 35 | if(err) | 34 | if(err) |
| 36 | goto out; | 35 | goto out; |
| 37 | 36 | ||
| 38 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, | 37 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, |
| 39 | (long) &STUB_DATA(timer), 0); | 38 | (long) &data->timer, 0); |
| 40 | if(err) | 39 | if(err) |
| 41 | goto out; | 40 | goto out; |
| 42 | 41 | ||
| 43 | err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, | 42 | remap_stack(data->fd, data->offset); |
| 44 | UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 43 | goto done; |
| 45 | MAP_FIXED | MAP_SHARED, STUB_DATA(fd), | 44 | |
| 46 | STUB_DATA(offset)); | ||
| 47 | out: | 45 | out: |
| 48 | /* save current result. Parent: pid; child: retcode of mmap */ | 46 | /* save current result. |
| 49 | STUB_DATA(err) = err; | 47 | * Parent: pid; |
| 48 | * child: retcode of mmap already saved and it jumps around this | ||
| 49 | * assignment | ||
| 50 | */ | ||
| 51 | data->err = err; | ||
| 52 | done: | ||
| 50 | trap_myself(); | 53 | trap_myself(); |
| 51 | } | 54 | } |
