aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2013-02-14 12:44:23 -0500
committerMichael Ellerman <michael@ellerman.id.au>2013-04-17 23:03:57 -0400
commitee4a3916614829914830bc4371358f4d4a63c4d9 (patch)
treeba1c65ba0a58933b8d9d43fe0374bdbc775338ad /arch/powerpc
parent3cc33d50f52521760da29ebd9db239741da7f21a (diff)
powerpc: fixing ptrace_get_reg to return an error
Currently ptrace_get_reg returns error as a value what make impossible to tell whether it is a correct value or error code. The patch adds a parameter which points to the real return data and returns an error code. As get_user_msr() never fails and it is used in multiple places so it has not been changed by this patch. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Acked-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/ptrace.h3
-rw-r--r--arch/powerpc/kernel/ptrace.c29
-rw-r--r--arch/powerpc/kernel/ptrace32.c15
3 files changed, 32 insertions, 15 deletions
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 5f995681bc1d..becc08e6a65c 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -92,7 +92,8 @@ static inline long regs_return_value(struct pt_regs *regs)
92 } while(0) 92 } while(0)
93 93
94struct task_struct; 94struct task_struct;
95extern unsigned long ptrace_get_reg(struct task_struct *task, int regno); 95extern int ptrace_get_reg(struct task_struct *task, int regno,
96 unsigned long *data);
96extern int ptrace_put_reg(struct task_struct *task, int regno, 97extern int ptrace_put_reg(struct task_struct *task, int regno,
97 unsigned long data); 98 unsigned long data);
98 99
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index f9b30c68ba47..10ade3c0c88a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -180,9 +180,10 @@ static int set_user_msr(struct task_struct *task, unsigned long msr)
180} 180}
181 181
182#ifdef CONFIG_PPC64 182#ifdef CONFIG_PPC64
183static unsigned long get_user_dscr(struct task_struct *task) 183static int get_user_dscr(struct task_struct *task, unsigned long *data)
184{ 184{
185 return task->thread.dscr; 185 *data = task->thread.dscr;
186 return 0;
186} 187}
187 188
188static int set_user_dscr(struct task_struct *task, unsigned long dscr) 189static int set_user_dscr(struct task_struct *task, unsigned long dscr)
@@ -192,7 +193,7 @@ static int set_user_dscr(struct task_struct *task, unsigned long dscr)
192 return 0; 193 return 0;
193} 194}
194#else 195#else
195static unsigned long get_user_dscr(struct task_struct *task) 196static int get_user_dscr(struct task_struct *task, unsigned long *data)
196{ 197{
197 return -EIO; 198 return -EIO;
198} 199}
@@ -216,19 +217,23 @@ static int set_user_trap(struct task_struct *task, unsigned long trap)
216/* 217/*
217 * Get contents of register REGNO in task TASK. 218 * Get contents of register REGNO in task TASK.
218 */ 219 */
219unsigned long ptrace_get_reg(struct task_struct *task, int regno) 220int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
220{ 221{
221 if (task->thread.regs == NULL) 222 if ((task->thread.regs == NULL) || !data)
222 return -EIO; 223 return -EIO;
223 224
224 if (regno == PT_MSR) 225 if (regno == PT_MSR) {
225 return get_user_msr(task); 226 *data = get_user_msr(task);
227 return 0;
228 }
226 229
227 if (regno == PT_DSCR) 230 if (regno == PT_DSCR)
228 return get_user_dscr(task); 231 return get_user_dscr(task, data);
229 232
230 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) 233 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
231 return ((unsigned long *)task->thread.regs)[regno]; 234 *data = ((unsigned long *)task->thread.regs)[regno];
235 return 0;
236 }
232 237
233 return -EIO; 238 return -EIO;
234} 239}
@@ -1560,7 +1565,9 @@ long arch_ptrace(struct task_struct *child, long request,
1560 1565
1561 CHECK_FULL_REGS(child->thread.regs); 1566 CHECK_FULL_REGS(child->thread.regs);
1562 if (index < PT_FPR0) { 1567 if (index < PT_FPR0) {
1563 tmp = ptrace_get_reg(child, (int) index); 1568 ret = ptrace_get_reg(child, (int) index, &tmp);
1569 if (ret)
1570 break;
1564 } else { 1571 } else {
1565 unsigned int fpidx = index - PT_FPR0; 1572 unsigned int fpidx = index - PT_FPR0;
1566 1573
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index c0244e766834..f51599e941c7 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -95,7 +95,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
95 95
96 CHECK_FULL_REGS(child->thread.regs); 96 CHECK_FULL_REGS(child->thread.regs);
97 if (index < PT_FPR0) { 97 if (index < PT_FPR0) {
98 tmp = ptrace_get_reg(child, index); 98 ret = ptrace_get_reg(child, index, &tmp);
99 if (ret)
100 break;
99 } else { 101 } else {
100 flush_fp_to_thread(child); 102 flush_fp_to_thread(child);
101 /* 103 /*
@@ -148,7 +150,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
148 tmp = ((u64 *)child->thread.fpr) 150 tmp = ((u64 *)child->thread.fpr)
149 [FPRINDEX_3264(numReg)]; 151 [FPRINDEX_3264(numReg)];
150 } else { /* register within PT_REGS struct */ 152 } else { /* register within PT_REGS struct */
151 tmp = ptrace_get_reg(child, numReg); 153 unsigned long tmp2;
154 ret = ptrace_get_reg(child, numReg, &tmp2);
155 if (ret)
156 break;
157 tmp = tmp2;
152 } 158 }
153 reg32bits = ((u32*)&tmp)[part]; 159 reg32bits = ((u32*)&tmp)[part];
154 ret = put_user(reg32bits, (u32 __user *)data); 160 ret = put_user(reg32bits, (u32 __user *)data);
@@ -232,7 +238,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
232 break; 238 break;
233 CHECK_FULL_REGS(child->thread.regs); 239 CHECK_FULL_REGS(child->thread.regs);
234 if (numReg < PT_FPR0) { 240 if (numReg < PT_FPR0) {
235 unsigned long freg = ptrace_get_reg(child, numReg); 241 unsigned long freg;
242 ret = ptrace_get_reg(child, numReg, &freg);
243 if (ret)
244 break;
236 if (index % 2) 245 if (index % 2)
237 freg = (freg & ~0xfffffffful) | (data & 0xfffffffful); 246 freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);
238 else 247 else