diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace32.c')
| -rw-r--r-- | arch/powerpc/kernel/ptrace32.c | 75 | 
1 files changed, 31 insertions, 44 deletions
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index 8a6daf4129f..f52b7db327c 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c @@ -32,42 +32,17 @@  #include <asm/uaccess.h>  #include <asm/page.h>  #include <asm/pgtable.h> -#include <asm/system.h> +#include <asm/switch_to.h>  /*   * does not yet catch signals sent when the child dies.   * in exit.c or in signal.c.   */ -/* - * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, - * we mark them as obsolete now, they will be removed in a future version - */ -static long compat_ptrace_old(struct task_struct *child, long request, -			      long addr, long data) -{ -	switch (request) { -	case PPC_PTRACE_GETREGS:	/* Get GPRs 0 - 31. */ -		return copy_regset_to_user(child, -					   task_user_regset_view(current), 0, -					   0, 32 * sizeof(compat_long_t), -					   compat_ptr(data)); - -	case PPC_PTRACE_SETREGS:	/* Set GPRs 0 - 31. */ -		return copy_regset_from_user(child, -					     task_user_regset_view(current), 0, -					     0, 32 * sizeof(compat_long_t), -					     compat_ptr(data)); -	} - -	return -EPERM; -} -  /* Macros to workout the correct index for the FPR in the thread struct */  #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)  #define FPRHALF(i) (((i) - PT_FPR0) & 1)  #define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i) -#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))  long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  			compat_ulong_t caddr, compat_ulong_t cdata) @@ -119,7 +94,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  		CHECK_FULL_REGS(child->thread.regs);  		if (index < PT_FPR0) { -			tmp = ptrace_get_reg(child, index); +			ret = ptrace_get_reg(child, index, &tmp); +			if (ret) +				break;  		} else {  			flush_fp_to_thread(child);  			/* @@ -127,7 +104,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  			 * to be an array of unsigned int (32 bits) - the  			 * index passed in is based on this assumption.  			 */ -			tmp = ((unsigned int *)child->thread.fpr) +			tmp = ((unsigned int *)child->thread.fp_state.fpr)  				[FPRINDEX(index)];  		}  		ret = put_user((unsigned int)tmp, (u32 __user *)data); @@ -169,10 +146,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  		if (numReg >= PT_FPR0) {  			flush_fp_to_thread(child);  			/* get 64 bit FPR */ -			tmp = ((u64 *)child->thread.fpr) -				[FPRINDEX_3264(numReg)]; +			tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0];  		} 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];  		ret = put_user(reg32bits, (u32 __user *)data); @@ -225,7 +205,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  			 * to be an array of unsigned int (32 bits) - the  			 * index passed in is based on this assumption.  			 */ -			((unsigned int *)child->thread.fpr) +			((unsigned int *)child->thread.fp_state.fpr)  				[FPRINDEX(index)] = data;  			ret = 0;  		} @@ -256,7 +236,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  			break;  		CHECK_FULL_REGS(child->thread.regs);  		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)  				freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);  			else @@ -266,8 +249,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  			u64 *tmp;  			flush_fp_to_thread(child);  			/* get 64 bit FPR ... */ -			tmp = &(((u64 *)child->thread.fpr) -				[FPRINDEX_3264(numReg)]); +			tmp = &child->thread.fp_state.fpr[numReg - PT_FPR0][0];  			/* ... write the 32 bit part we want */  			((u32 *)tmp)[index % 2] = data;  			ret = 0; @@ -276,11 +258,21 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  	}  	case PTRACE_GET_DEBUGREG: { +#ifndef CONFIG_PPC_ADV_DEBUG_REGS +		unsigned long dabr_fake; +#endif  		ret = -EINVAL;  		/* We only support one DABR and no IABRS at the moment */  		if (addr > 0)  			break; -		ret = put_user(child->thread.dabr, (u32 __user *)data); +#ifdef CONFIG_PPC_ADV_DEBUG_REGS +		ret = put_user(child->thread.debug.dac1, (u32 __user *)data); +#else +		dabr_fake = ( +			(child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) | +			(child->thread.hw_brk.type & HW_BRK_TYPE_DABR)); +		ret = put_user(dabr_fake, (u32 __user *)data); +#endif  		break;  	} @@ -304,23 +296,18 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,  	case PTRACE_SETVSRREGS:  	case PTRACE_GETREGS64:  	case PTRACE_SETREGS64: -	case PPC_PTRACE_GETFPREGS: -	case PPC_PTRACE_SETFPREGS:  	case PTRACE_KILL:  	case PTRACE_SINGLESTEP:  	case PTRACE_DETACH:  	case PTRACE_SET_DEBUGREG:  	case PTRACE_SYSCALL:  	case PTRACE_CONT: +	case PPC_PTRACE_GETHWDBGINFO: +	case PPC_PTRACE_SETHWDEBUG: +	case PPC_PTRACE_DELHWDEBUG:  		ret = arch_ptrace(child, request, addr, data);  		break; -	/* Old reverse args ptrace callss */ -	case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ -	case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ -		ret = compat_ptrace_old(child, request, addr, data); -		break; -  	default:  		ret = compat_ptrace_request(child, request, addr, data);  		break;  | 
