aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64
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-x86_64
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-x86_64')
-rw-r--r--arch/um/sys-x86_64/ptrace.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 1970d78aa52..b9032992a99 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -156,28 +156,53 @@ int is_syscall(unsigned long addr)
156 return(instr == 0x050f); 156 return(instr == 0x050f);
157} 157}
158 158
159int get_fpregs(unsigned long buf, struct task_struct *child) 159int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
160{ 160{
161 panic("get_fpregs"); 161 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
162 return(0); 162 long fpregs[HOST_FP_SIZE];
163}
164 163
165int set_fpregs(unsigned long buf, struct task_struct *child) 164 BUG_ON(sizeof(*buf) != sizeof(fpregs));
166{ 165 err = save_fp_registers(userspace_pid[cpu], fpregs);
167 panic("set_fpregs"); 166 if (err)
168 return(0); 167 return err;
168
169 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
170 if(n > 0)
171 return -EFAULT;
172
173 return n;
169} 174}
170 175
171int get_fpxregs(unsigned long buf, struct task_struct *tsk) 176int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
172{ 177{
173 panic("get_fpxregs"); 178 int n, cpu = ((struct thread_info *) child->stack)->cpu;
174 return(0); 179 long fpregs[HOST_FP_SIZE];
180
181 BUG_ON(sizeof(*buf) != sizeof(fpregs));
182 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
183 if (n > 0)
184 return -EFAULT;
185
186 return restore_fp_registers(userspace_pid[cpu], fpregs);
175} 187}
176 188
177int set_fpxregs(unsigned long buf, struct task_struct *tsk) 189long subarch_ptrace(struct task_struct *child, long request, long addr,
190 long data)
178{ 191{
179 panic("set_fxpregs"); 192 int ret = -EIO;
180 return(0); 193
194 switch (request) {
195 case PTRACE_GETFPXREGS: /* Get the child FPU state. */
196 ret = get_fpregs((struct user_i387_struct __user *) data,
197 child);
198 break;
199 case PTRACE_SETFPXREGS: /* Set the child FPU state. */
200 ret = set_fpregs((struct user_i387_struct __user *) data,
201 child);
202 break;
203 }
204
205 return ret;
181} 206}
182 207
183/* 208/*