summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/um/include/registers.h2
-rw-r--r--arch/um/os-Linux/skas/mem.c2
-rw-r--r--arch/um/os-Linux/skas/process.c21
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c5
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c5
-rw-r--r--arch/um/sys-x86_64/ptrace_user.c7
-rw-r--r--arch/um/sys-x86_64/user-offsets.c2
7 files changed, 32 insertions, 12 deletions
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 4892e5fcef0..83b688ca198 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);
extern void save_registers(int pid, union uml_pt_regs *regs);
extern void restore_registers(int pid, union uml_pt_regs *regs);
extern void 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 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
#endif
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9890e9090f5..fbb080c2fc2 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)
multi_count++;
- get_safe_registers(regs);
+ get_safe_registers(regs, NULL);
regs[REGS_IP_INDEX] = UML_CONFIG_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 120a21c5883..bbf34cb91ce 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)
}
}
}
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[MAX_REG_NR];
+ unsigned long regs[HOST_FRAME_SIZE];
+ unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
.timer = ((struct itimerval)
{ { 0, 1000000 / hz() },
{ 0, 1000000 / hz() }})});
- get_safe_registers(regs);
+ get_safe_registers(regs, fp_regs);
/* Set parent's instruction pointer to start of clone-stub */
regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
@@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, errno);
+ err = ptrace_setfpregs(pid, fp_regs);
+ if(err < 0)
+ panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
+ "pid = %d, errno = %d\n", pid, errno);
+
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
@@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
set_signals(flags);
}
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
+
void thread_wait(void *sw, void *fb)
{
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 aee4812333c..7a6f6b99cef 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)
err);
}
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ if(fp_regs != NULL)
+ memcpy(fp_regs, exec_fp_regs,
+ HOST_FP_SIZE * sizeof(unsigned long));
}
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 4b638dfb52b..001941fa1a1 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)
err);
}
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ if(fp_regs != NULL)
+ memcpy(fp_regs, exec_fp_regs,
+ HOST_FP_SIZE * sizeof(unsigned long));
}
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 12e404c6fa4..b5f9c33e311 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)
return(0);
}
+int ptrace_setfpregs(long pid, unsigned long *regs)
+{
+ if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
+ return -errno;
+ return 0;
+}
+
void ptrace_pokeuser(unsigned long addr, unsigned long data)
{
panic("ptrace_pokeuser");
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 5a585bfbb8c..7bd54a921cf 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)
#endif
DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
- DEFINE(HOST_FP_SIZE, 0);
+ DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
DEFINE(HOST_XFP_SIZE, 0);
DEFINE_LONGS(HOST_RBX, RBX);
DEFINE_LONGS(HOST_RCX, RCX);