aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/include/registers.h2
-rw-r--r--arch/um/include/sysdep-i386/ptrace_user.h3
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace_user.h3
-rw-r--r--arch/um/os-Linux/skas/process.c15
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c16
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c10
6 files changed, 49 insertions, 0 deletions
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 9ea1ae3c8f46..b0b4589e0ebc 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -18,5 +18,7 @@ extern int restore_registers(int pid, struct uml_pt_regs *regs);
18extern int init_registers(int pid); 18extern int init_registers(int pid);
19extern void get_safe_registers(unsigned long *regs); 19extern void get_safe_registers(unsigned long *regs);
20extern unsigned long get_thread_reg(int reg, jmp_buf *buf); 20extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
21extern int get_fp_registers(int pid, unsigned long *regs);
22extern int put_fp_registers(int pid, unsigned long *regs);
21 23
22#endif 24#endif
diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
index 899aa4b2a78d..75650723c38f 100644
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -9,6 +9,7 @@
9#include <sys/ptrace.h> 9#include <sys/ptrace.h>
10#include <linux/ptrace.h> 10#include <linux/ptrace.h>
11#include <asm/ptrace.h> 11#include <asm/ptrace.h>
12#include "user_constants.h"
12 13
13#define PT_OFFSET(r) ((r) * sizeof(long)) 14#define PT_OFFSET(r) ((r) * sizeof(long))
14 15
@@ -40,6 +41,8 @@
40#define PT_SP_OFFSET PT_OFFSET(UESP) 41#define PT_SP_OFFSET PT_OFFSET(UESP)
41#define PT_SP(regs) ((regs)[UESP]) 42#define PT_SP(regs) ((regs)[UESP])
42 43
44#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
45
43#ifndef FRAME_SIZE 46#ifndef FRAME_SIZE
44#define FRAME_SIZE (17) 47#define FRAME_SIZE (17)
45#endif 48#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 4cd61a852fab..45c0bd881cb3 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -12,6 +12,7 @@
12#include <linux/ptrace.h> 12#include <linux/ptrace.h>
13#include <asm/ptrace.h> 13#include <asm/ptrace.h>
14#undef __FRAME_OFFSETS 14#undef __FRAME_OFFSETS
15#include "user_constants.h"
15 16
16#define PT_INDEX(off) ((off) / sizeof(unsigned long)) 17#define PT_INDEX(off) ((off) / sizeof(unsigned long))
17 18
@@ -69,6 +70,8 @@
69#define REGS_IP_INDEX PT_INDEX(RIP) 70#define REGS_IP_INDEX PT_INDEX(RIP)
70#define REGS_SP_INDEX PT_INDEX(RSP) 71#define REGS_SP_INDEX PT_INDEX(RSP)
71 72
73#define FP_SIZE (HOST_FP_SIZE)
74
72#endif 75#endif
73 76
74/* 77/*
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b14829469fae..1e8cba6550a9 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -115,6 +115,14 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
115 sizeof(struct ptrace_faultinfo)); 115 sizeof(struct ptrace_faultinfo));
116 } 116 }
117 else { 117 else {
118 unsigned long fpregs[FP_SIZE];
119
120 err = get_fp_registers(pid, fpregs);
121 if (err < 0) {
122 printk(UM_KERN_ERR "save_fp_registers returned %d\n",
123 err);
124 fatal_sigsegv();
125 }
118 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 126 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
119 if (err) { 127 if (err) {
120 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, " 128 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
@@ -128,6 +136,13 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
128 * the stub stack page. We just have to copy it. 136 * the stub stack page. We just have to copy it.
129 */ 137 */
130 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 138 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
139
140 err = put_fp_registers(pid, fpregs);
141 if (err < 0) {
142 printk(UM_KERN_ERR "put_fp_registers returned %d\n",
143 err);
144 fatal_sigsegv();
145 }
131 } 146 }
132} 147}
133 148
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index f74d853a0ee0..b613473b3ec1 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -56,6 +56,22 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
56 56
57int have_fpx_regs = 1; 57int have_fpx_regs = 1;
58 58
59int get_fp_registers(int pid, unsigned long *regs)
60{
61 if (have_fpx_regs)
62 return save_fpx_registers(pid, regs);
63 else
64 return save_fp_registers(pid, regs);
65}
66
67int put_fp_registers(int pid, unsigned long *regs)
68{
69 if (have_fpx_regs)
70 return restore_fpx_registers(pid, regs);
71 else
72 return restore_fp_registers(pid, regs);
73}
74
59void arch_init_registers(int pid) 75void arch_init_registers(int pid)
60{ 76{
61 unsigned long fpx_regs[HOST_XFP_SIZE]; 77 unsigned long fpx_regs[HOST_XFP_SIZE];
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a375853337a7..594d97ad02b3 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -40,3 +40,13 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
40 return 0; 40 return 0;
41 } 41 }
42} 42}
43
44int get_fp_registers(int pid, unsigned long *regs)
45{
46 return save_fp_registers(pid, regs);
47}
48
49int put_fp_registers(int pid, unsigned long *regs)
50{
51 return restore_fp_registers(pid, regs);
52}