diff options
-rw-r--r-- | arch/um/include/registers.h | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/mem.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 21 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-i386/registers.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-x86_64/registers.c | 5 | ||||
-rw-r--r-- | arch/um/sys-x86_64/ptrace_user.c | 7 | ||||
-rw-r--r-- | arch/um/sys-x86_64/user-offsets.c | 2 |
7 files changed, 32 insertions, 12 deletions
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index 4892e5fcef07..83b688ca198f 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h | |||
@@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); | |||
14 | extern void save_registers(int pid, union uml_pt_regs *regs); | 14 | extern void save_registers(int pid, union uml_pt_regs *regs); |
15 | extern void restore_registers(int pid, union uml_pt_regs *regs); | 15 | extern void restore_registers(int pid, union uml_pt_regs *regs); |
16 | extern void init_registers(int pid); | 16 | extern void init_registers(int pid); |
17 | extern void get_safe_registers(unsigned long * regs); | 17 | extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); |
18 | extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); | 18 | extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); |
19 | 19 | ||
20 | #endif | 20 | #endif |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9890e9090f58..fbb080c2fc26 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
@@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | |||
60 | 60 | ||
61 | multi_count++; | 61 | multi_count++; |
62 | 62 | ||
63 | get_safe_registers(regs); | 63 | get_safe_registers(regs, NULL); |
64 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + | 64 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + |
65 | ((unsigned long) &batch_syscall_stub - | 65 | ((unsigned long) &batch_syscall_stub - |
66 | (unsigned long) &__syscall_stub_start); | 66 | (unsigned long) &__syscall_stub_start); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 120a21c5883f..bbf34cb91ce1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs) | |||
310 | } | 310 | } |
311 | } | 311 | } |
312 | } | 312 | } |
313 | #define INIT_JMP_NEW_THREAD 0 | ||
314 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
315 | #define INIT_JMP_CALLBACK 2 | ||
316 | #define INIT_JMP_HALT 3 | ||
317 | #define INIT_JMP_REBOOT 4 | ||
318 | 313 | ||
319 | int copy_context_skas0(unsigned long new_stack, int pid) | 314 | int copy_context_skas0(unsigned long new_stack, int pid) |
320 | { | 315 | { |
321 | int err; | 316 | int err; |
322 | unsigned long regs[MAX_REG_NR]; | 317 | unsigned long regs[HOST_FRAME_SIZE]; |
318 | unsigned long fp_regs[HOST_FP_SIZE]; | ||
323 | unsigned long current_stack = current_stub_stack(); | 319 | unsigned long current_stack = current_stub_stack(); |
324 | struct stub_data *data = (struct stub_data *) current_stack; | 320 | struct stub_data *data = (struct stub_data *) current_stack; |
325 | struct stub_data *child_data = (struct stub_data *) new_stack; | 321 | struct stub_data *child_data = (struct stub_data *) new_stack; |
@@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
334 | .timer = ((struct itimerval) | 330 | .timer = ((struct itimerval) |
335 | { { 0, 1000000 / hz() }, | 331 | { { 0, 1000000 / hz() }, |
336 | { 0, 1000000 / hz() }})}); | 332 | { 0, 1000000 / hz() }})}); |
337 | get_safe_registers(regs); | 333 | get_safe_registers(regs, fp_regs); |
338 | 334 | ||
339 | /* Set parent's instruction pointer to start of clone-stub */ | 335 | /* Set parent's instruction pointer to start of clone-stub */ |
340 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + | 336 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + |
@@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
350 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | 346 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " |
351 | "pid = %d, errno = %d\n", pid, errno); | 347 | "pid = %d, errno = %d\n", pid, errno); |
352 | 348 | ||
349 | err = ptrace_setfpregs(pid, fp_regs); | ||
350 | if(err < 0) | ||
351 | panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " | ||
352 | "pid = %d, errno = %d\n", pid, errno); | ||
353 | |||
353 | /* set a well known return code for detection of child write failure */ | 354 | /* set a well known return code for detection of child write failure */ |
354 | child_data->err = 12345678; | 355 | child_data->err = 12345678; |
355 | 356 | ||
@@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
457 | set_signals(flags); | 458 | set_signals(flags); |
458 | } | 459 | } |
459 | 460 | ||
461 | #define INIT_JMP_NEW_THREAD 0 | ||
462 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
463 | #define INIT_JMP_CALLBACK 2 | ||
464 | #define INIT_JMP_HALT 3 | ||
465 | #define INIT_JMP_REBOOT 4 | ||
466 | |||
460 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) |
461 | { | 468 | { |
462 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; |
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index aee4812333c6..7a6f6b99ceff 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c | |||
@@ -122,9 +122,12 @@ void init_registers(int pid) | |||
122 | err); | 122 | err); |
123 | } | 123 | } |
124 | 124 | ||
125 | void get_safe_registers(unsigned long *regs) | 125 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
126 | { | 126 | { |
127 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | 127 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); |
128 | if(fp_regs != NULL) | ||
129 | memcpy(fp_regs, exec_fp_regs, | ||
130 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
128 | } | 131 | } |
129 | 132 | ||
130 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) | 133 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) |
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 4b638dfb52b0..001941fa1a1e 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c | |||
@@ -70,9 +70,12 @@ void init_registers(int pid) | |||
70 | err); | 70 | err); |
71 | } | 71 | } |
72 | 72 | ||
73 | void get_safe_registers(unsigned long *regs) | 73 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
74 | { | 74 | { |
75 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | 75 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); |
76 | if(fp_regs != NULL) | ||
77 | memcpy(fp_regs, exec_fp_regs, | ||
78 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
76 | } | 79 | } |
77 | 80 | ||
78 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) | 81 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) |
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c index 12e404c6fa46..b5f9c33e311e 100644 --- a/arch/um/sys-x86_64/ptrace_user.c +++ b/arch/um/sys-x86_64/ptrace_user.c | |||
@@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs) | |||
24 | return(0); | 24 | return(0); |
25 | } | 25 | } |
26 | 26 | ||
27 | int ptrace_setfpregs(long pid, unsigned long *regs) | ||
28 | { | ||
29 | if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) | ||
30 | return -errno; | ||
31 | return 0; | ||
32 | } | ||
33 | |||
27 | void ptrace_pokeuser(unsigned long addr, unsigned long data) | 34 | void ptrace_pokeuser(unsigned long addr, unsigned long data) |
28 | { | 35 | { |
29 | panic("ptrace_pokeuser"); | 36 | panic("ptrace_pokeuser"); |
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 5a585bfbb8c2..7bd54a921cf7 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c | |||
@@ -57,7 +57,7 @@ void foo(void) | |||
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); | 59 | DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); |
60 | DEFINE(HOST_FP_SIZE, 0); | 60 | DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); |
61 | DEFINE(HOST_XFP_SIZE, 0); | 61 | DEFINE(HOST_XFP_SIZE, 0); |
62 | DEFINE_LONGS(HOST_RBX, RBX); | 62 | DEFINE_LONGS(HOST_RBX, RBX); |
63 | DEFINE_LONGS(HOST_RCX, RCX); | 63 | DEFINE_LONGS(HOST_RCX, RCX); |