aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-i386
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-10-16 04:27:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:07 -0400
commite8012b584fac3a1bb70cd896612c12086d28e9ff (patch)
tree0ec406be2ad1878b601c6e97ad6216764ddae942 /arch/um/sys-i386
parenta5f6096c805e6d2fa03ee932f8c70af34cee41a0 (diff)
uml: ptrace floating point fixes
Handle floating point state better in ptrace. The code now correctly distinguishes between PTRACE_[GS]ETFPREGS and PTRACE_[GS]ETFPXREGS. The FPX requests get handed off to arch-specific code because that's not generic. get_fpregs, set_fpregs, set_fpregs, and set_fpxregs needed real implementations. Something here exposed a missing include in asm/page.h, which needed linux/types.h in order to get gfp_t, so that's fixed here. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r--arch/um/sys-i386/ptrace.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index cb899dd1c6b5..659011df1e9a 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -6,6 +6,7 @@
6#include "linux/mm.h" 6#include "linux/mm.h"
7#include "linux/sched.h" 7#include "linux/sched.h"
8#include "asm/uaccess.h" 8#include "asm/uaccess.h"
9#include "skas.h"
9 10
10extern int arch_switch_tls(struct task_struct *from, struct task_struct *to); 11extern int arch_switch_tls(struct task_struct *from, struct task_struct *to);
11 12
@@ -144,48 +145,64 @@ int peek_user(struct task_struct *child, long addr, long data)
144 return put_user(tmp, (unsigned long __user *) data); 145 return put_user(tmp, (unsigned long __user *) data);
145} 146}
146 147
147static inline int convert_fxsr_to_user(struct _fpstate __user *buf, 148int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
148 struct pt_regs *regs)
149{ 149{
150 return 0; 150 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
151} 151 long fpregs[HOST_FP_SIZE];
152 152
153static inline int convert_fxsr_from_user(struct pt_regs *regs, 153 BUG_ON(sizeof(*buf) != sizeof(fpregs));
154 struct _fpstate __user *buf) 154 err = save_fp_registers(userspace_pid[cpu], fpregs);
155{ 155 if (err)
156 return 0; 156 return err;
157
158 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
159 if(n > 0)
160 return -EFAULT;
161
162 return n;
157} 163}
158 164
159int get_fpregs(unsigned long buf, struct task_struct *child) 165int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
160{ 166{
161 int err; 167 int n, cpu = ((struct thread_info *) child->stack)->cpu;
168 long fpregs[HOST_FP_SIZE];
162 169
163 err = convert_fxsr_to_user((struct _fpstate __user *) buf, 170 BUG_ON(sizeof(*buf) != sizeof(fpregs));
164 &child->thread.regs); 171 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
165 if (err) 172 if (n > 0)
166 return -EFAULT; 173 return -EFAULT;
167 return 0; 174
175 return restore_fp_registers(userspace_pid[cpu], fpregs);
168} 176}
169 177
170int set_fpregs(unsigned long buf, struct task_struct *child) 178int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
171{ 179{
172 int err; 180 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
181 long fpregs[HOST_XFP_SIZE];
173 182
174 err = convert_fxsr_from_user(&child->thread.regs, 183 BUG_ON(sizeof(*buf) != sizeof(fpregs));
175 (struct _fpstate __user *) buf); 184 err = save_fpx_registers(userspace_pid[cpu], fpregs);
176 if (err) 185 if (err)
186 return err;
187
188 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
189 if(n > 0)
177 return -EFAULT; 190 return -EFAULT;
178 return 0;
179}
180 191
181int get_fpxregs(unsigned long buf, struct task_struct *tsk) 192 return n;
182{
183 return 0;
184} 193}
185 194
186int set_fpxregs(unsigned long buf, struct task_struct *tsk) 195int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
187{ 196{
188 return 0; 197 int n, cpu = ((struct thread_info *) child->stack)->cpu;
198 long fpregs[HOST_XFP_SIZE];
199
200 BUG_ON(sizeof(*buf) != sizeof(fpregs));
201 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
202 if (n > 0)
203 return -EFAULT;
204
205 return restore_fpx_registers(userspace_pid[cpu], fpregs);
189} 206}
190 207
191#ifdef notdef 208#ifdef notdef
@@ -209,3 +226,9 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
209{ 226{
210 return 1; 227 return 1;
211} 228}
229
230long subarch_ptrace(struct task_struct *child, long request, long addr,
231 long data)
232{
233 return -EIO;
234}