diff options
| -rw-r--r-- | arch/powerpc/kernel/align.c | 29 | 
1 files changed, 13 insertions, 16 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index ada06924a423..73cb6a3229ae 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -367,27 +367,24 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,  static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,  			   unsigned int flags)  { -	char *ptr = (char *) ¤t->thread.TS_FPR(reg); -	int i, ret; +	char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); +	char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); +	int i, ret, sw = 0;  	if (!(flags & F))  		return 0;  	if (reg & 1)  		return 0;	/* invalid form: FRS/FRT must be even */ -	if (!(flags & SW)) { -		/* not byte-swapped - easy */ -		if (!(flags & ST)) -			ret = __copy_from_user(ptr, addr, 16); -		else -			ret = __copy_to_user(addr, ptr, 16); -	} else { -		/* each FPR value is byte-swapped separately */ -		ret = 0; -		for (i = 0; i < 16; ++i) { -			if (!(flags & ST)) -				ret |= __get_user(ptr[i^7], addr + i); -			else -				ret |= __put_user(ptr[i^7], addr + i); +	if (flags & SW) +		sw = 7; +	ret = 0; +	for (i = 0; i < 8; ++i) { +		if (!(flags & ST)) { +			ret |= __get_user(ptr0[i^sw], addr + i); +			ret |= __get_user(ptr1[i^sw], addr + i + 8); +		} else { +			ret |= __put_user(ptr0[i^sw], addr + i); +			ret |= __put_user(ptr1[i^sw], addr + i + 8);  		}  	}  	if (ret)  | 
