mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-18 10:34:24 +08:00
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>
This commit is contained in:
parent
3cc33d50f5
commit
ee4a391661
@ -92,7 +92,8 @@ static inline long regs_return_value(struct pt_regs *regs)
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
extern unsigned long ptrace_get_reg(struct task_struct *task, int regno);
|
extern int ptrace_get_reg(struct task_struct *task, int regno,
|
||||||
|
unsigned long *data);
|
||||||
extern int ptrace_put_reg(struct task_struct *task, int regno,
|
extern int ptrace_put_reg(struct task_struct *task, int regno,
|
||||||
unsigned long data);
|
unsigned long data);
|
||||||
|
|
||||||
|
@ -180,9 +180,10 @@ static int set_user_msr(struct task_struct *task, unsigned long msr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
static unsigned long get_user_dscr(struct task_struct *task)
|
static int get_user_dscr(struct task_struct *task, unsigned long *data)
|
||||||
{
|
{
|
||||||
return task->thread.dscr;
|
*data = task->thread.dscr;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_user_dscr(struct task_struct *task, unsigned long dscr)
|
static 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)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static unsigned long get_user_dscr(struct task_struct *task)
|
static int get_user_dscr(struct task_struct *task, unsigned long *data)
|
||||||
{
|
{
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -216,19 +217,23 @@ static int set_user_trap(struct task_struct *task, unsigned long trap)
|
|||||||
/*
|
/*
|
||||||
* Get contents of register REGNO in task TASK.
|
* Get contents of register REGNO in task TASK.
|
||||||
*/
|
*/
|
||||||
unsigned long ptrace_get_reg(struct task_struct *task, int regno)
|
int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
|
||||||
{
|
{
|
||||||
if (task->thread.regs == NULL)
|
if ((task->thread.regs == NULL) || !data)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (regno == PT_MSR)
|
if (regno == PT_MSR) {
|
||||||
return get_user_msr(task);
|
*data = get_user_msr(task);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (regno == PT_DSCR)
|
if (regno == PT_DSCR)
|
||||||
return get_user_dscr(task);
|
return get_user_dscr(task, data);
|
||||||
|
|
||||||
if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
|
if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
|
||||||
return ((unsigned long *)task->thread.regs)[regno];
|
*data = ((unsigned long *)task->thread.regs)[regno];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -1560,7 +1565,9 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
|
|
||||||
CHECK_FULL_REGS(child->thread.regs);
|
CHECK_FULL_REGS(child->thread.regs);
|
||||||
if (index < PT_FPR0) {
|
if (index < PT_FPR0) {
|
||||||
tmp = ptrace_get_reg(child, (int) index);
|
ret = ptrace_get_reg(child, (int) index, &tmp);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
unsigned int fpidx = index - PT_FPR0;
|
unsigned int fpidx = index - PT_FPR0;
|
||||||
|
|
||||||
|
@ -95,7 +95,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||||||
|
|
||||||
CHECK_FULL_REGS(child->thread.regs);
|
CHECK_FULL_REGS(child->thread.regs);
|
||||||
if (index < PT_FPR0) {
|
if (index < PT_FPR0) {
|
||||||
tmp = ptrace_get_reg(child, index);
|
ret = ptrace_get_reg(child, index, &tmp);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
flush_fp_to_thread(child);
|
flush_fp_to_thread(child);
|
||||||
/*
|
/*
|
||||||
@ -148,7 +150,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||||||
tmp = ((u64 *)child->thread.fpr)
|
tmp = ((u64 *)child->thread.fpr)
|
||||||
[FPRINDEX_3264(numReg)];
|
[FPRINDEX_3264(numReg)];
|
||||||
} else { /* register within PT_REGS struct */
|
} else { /* register within PT_REGS struct */
|
||||||
tmp = ptrace_get_reg(child, numReg);
|
unsigned long tmp2;
|
||||||
|
ret = ptrace_get_reg(child, numReg, &tmp2);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
tmp = tmp2;
|
||||||
}
|
}
|
||||||
reg32bits = ((u32*)&tmp)[part];
|
reg32bits = ((u32*)&tmp)[part];
|
||||||
ret = put_user(reg32bits, (u32 __user *)data);
|
ret = put_user(reg32bits, (u32 __user *)data);
|
||||||
@ -232,7 +238,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||||||
break;
|
break;
|
||||||
CHECK_FULL_REGS(child->thread.regs);
|
CHECK_FULL_REGS(child->thread.regs);
|
||||||
if (numReg < PT_FPR0) {
|
if (numReg < PT_FPR0) {
|
||||||
unsigned long freg = ptrace_get_reg(child, numReg);
|
unsigned long freg;
|
||||||
|
ret = ptrace_get_reg(child, numReg, &freg);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
if (index % 2)
|
if (index % 2)
|
||||||
freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);
|
freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user