]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.arch/ppc32-fix-ptrace-compat-wrapper-for-fpu-register-access
Revert "Disable build of xen kernel."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / ppc32-fix-ptrace-compat-wrapper-for-fpu-register-access
1 From: Michael Neuling <mikey@neuling.org>
2 Subject: powerpc: Fix ptrace compat wrapper for FPU register access
3 Patch-mainline: 2.6.30-rc4
4 Git-commit: bc826666e4252f78d2b144af3b7d699ff5efce0a
5 References: bnc#496027
6
7 powerpc: Fix ptrace compat wrapper for FPU register access
8
9 The ptrace compat wrapper mishandles access to the fpu registers. The
10 PTRACE_PEEKUSR and PTRACE_POKEUSR requests miscalculate the index into
11 the fpr array due to the broken FPINDEX macro. The
12 PPC_PTRACE_PEEKUSR_3264 request needs to use the same formula that the
13 native ptrace interface uses when operating on the register number (as
14 opposed to the 4-byte offset). The PPC_PTRACE_POKEUSR_3264 request
15 didn't take TS_FPRWIDTH into account.
16
17 Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
18 Signed-off-by: Michael Neuling <mikey@neuling.org>
19 Signed-off-by: Paul Mackerras <paulus@samba.org>
20 Acked-by: Jeff Mahoney <jeffm@suse.com>
21 ---
22 arch/powerpc/kernel/ptrace32.c | 15 +++++++++++----
23 1 file changed, 11 insertions(+), 4 deletions(-)
24
25 --- a/arch/powerpc/kernel/ptrace32.c
26 +++ b/arch/powerpc/kernel/ptrace32.c
27 @@ -70,7 +70,8 @@ static long compat_ptrace_old(struct tas
28 /* Macros to workout the correct index for the FPR in the thread struct */
29 #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
30 #define FPRHALF(i) (((i) - PT_FPR0) & 1)
31 -#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) + FPRHALF(i)
32 +#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
33 +#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
34
35 static int compat_ptrace_getsiginfo(struct task_struct *child, compat_siginfo_t __user *data)
36 {
37 @@ -192,8 +193,9 @@ long compat_arch_ptrace(struct task_stru
38 CHECK_FULL_REGS(child->thread.regs);
39 if (numReg >= PT_FPR0) {
40 flush_fp_to_thread(child);
41 - tmp = ((unsigned long int *)child->thread.fpr)
42 - [FPRINDEX(numReg)];
43 + /* get 64 bit FPR */
44 + tmp = ((u64 *)child->thread.fpr)
45 + [FPRINDEX_3264(numReg)];
46 } else { /* register within PT_REGS struct */
47 tmp = ptrace_get_reg(child, numReg);
48 }
49 @@ -286,8 +288,13 @@ long compat_arch_ptrace(struct task_stru
50 freg = (freg & 0xfffffffful) | (data << 32);
51 ret = ptrace_put_reg(child, numReg, freg);
52 } else {
53 + u64 *tmp;
54 flush_fp_to_thread(child);
55 - ((unsigned int *)child->thread.regs)[index] = data;
56 + /* get 64 bit FPR ... */
57 + tmp = &(((u64 *)child->thread.fpr)
58 + [FPRINDEX_3264(numReg)]);
59 + /* ... write the 32 bit part we want */
60 + ((u32 *)tmp)[index % 2] = data;
61 ret = 0;
62 }
63 break;