]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.arch/ppc32-fix-ptrace-compat-wrapper-for-fpu-register-access
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / ppc32-fix-ptrace-compat-wrapper-for-fpu-register-access
CommitLineData
00e5a55c
BS
1From: Michael Neuling <mikey@neuling.org>
2Subject: powerpc: Fix ptrace compat wrapper for FPU register access
3Patch-mainline: 2.6.30-rc4
4Git-commit: bc826666e4252f78d2b144af3b7d699ff5efce0a
5References: bnc#496027
6
7powerpc: Fix ptrace compat wrapper for FPU register access
8
9The ptrace compat wrapper mishandles access to the fpu registers. The
10PTRACE_PEEKUSR and PTRACE_POKEUSR requests miscalculate the index into
11the fpr array due to the broken FPINDEX macro. The
12PPC_PTRACE_PEEKUSR_3264 request needs to use the same formula that the
13native ptrace interface uses when operating on the register number (as
14opposed to the 4-byte offset). The PPC_PTRACE_POKEUSR_3264 request
15didn't take TS_FPRWIDTH into account.
16
17Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
18Signed-off-by: Michael Neuling <mikey@neuling.org>
19Signed-off-by: Paul Mackerras <paulus@samba.org>
20Acked-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;