aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8b056d2295cc..f1ce64649256 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -21,6 +21,7 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/regset.h>
24#include <linux/user.h> 25#include <linux/user.h>
25#include <linux/security.h> 26#include <linux/security.h>
26#include <linux/signal.h> 27#include <linux/signal.h>
@@ -103,24 +104,48 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
103} 104}
104 105
105 106
107static int fpr_get(struct task_struct *target, const struct user_regset *regset,
108 unsigned int pos, unsigned int count,
109 void *kbuf, void __user *ubuf)
110{
111 flush_fp_to_thread(target);
112
113 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
114 offsetof(struct thread_struct, fpr[32]));
115
116 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
117 &target->thread.fpr, 0, -1);
118}
119
120static int fpr_set(struct task_struct *target, const struct user_regset *regset,
121 unsigned int pos, unsigned int count,
122 const void *kbuf, const void __user *ubuf)
123{
124 flush_fp_to_thread(target);
125
126 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
127 offsetof(struct thread_struct, fpr[32]));
128
129 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
130 &target->thread.fpr, 0, -1);
131}
132
106static int get_fpregs(void __user *data, struct task_struct *task, 133static int get_fpregs(void __user *data, struct task_struct *task,
107 int has_fpscr) 134 int has_fpscr)
108{ 135{
109 unsigned int count = has_fpscr ? 33 : 32; 136 unsigned int count = has_fpscr ? 33 : 32;
110 137 if (!access_ok(VERIFY_WRITE, data, count * sizeof(double)))
111 if (copy_to_user(data, task->thread.fpr, count * sizeof(double)))
112 return -EFAULT; 138 return -EFAULT;
113 return 0; 139 return fpr_get(task, NULL, 0, count * sizeof(double), NULL, data);
114} 140}
115 141
116static int set_fpregs(void __user *data, struct task_struct *task, 142static int set_fpregs(void __user *data, struct task_struct *task,
117 int has_fpscr) 143 int has_fpscr)
118{ 144{
119 unsigned int count = has_fpscr ? 33 : 32; 145 unsigned int count = has_fpscr ? 33 : 32;
120 146 if (!access_ok(VERIFY_READ, data, count * sizeof(double)))
121 if (copy_from_user(task->thread.fpr, data, count * sizeof(double)))
122 return -EFAULT; 147 return -EFAULT;
123 return 0; 148 return fpr_set(task, NULL, 0, count * sizeof(double), NULL, data);
124} 149}
125 150
126 151