aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-26 19:37:57 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-17 10:49:02 -0800
commitf2a1abc8cfa0220a550c5a54440a5e97ef025899 (patch)
tree71325fb1c2331af0bc8ae2d7f930a7aca533f5ef
parent15a83cc22d40240f1f551b4c2092f7f246bdbfce (diff)
downloadkernel_samsung_smdk4412-f2a1abc8cfa0220a550c5a54440a5e97ef025899.tar.gz
kernel_samsung_smdk4412-f2a1abc8cfa0220a550c5a54440a5e97ef025899.tar.bz2
kernel_samsung_smdk4412-f2a1abc8cfa0220a550c5a54440a5e97ef025899.zip
powerpc/ptrace: Fix build with gcc 4.6
commit e69b742a6793dc5bf16f6eedca534d4bc10d68b2 upstream. gcc (rightfully) complains that we are accessing beyond the end of the fpr array (we do, to access the fpscr). The only sane thing to do (whether anything in that code can be called remotely sane is debatable) is to special case fpscr and handle it as a separate statement. I initially tried to do it it by making the array access conditional to index < PT_FPSCR and using a 3rd else leg but for some reason gcc was unable to understand it and still spewed the warning. So I ended up with something a tad more intricated but it seems to build on 32-bit and on 64-bit with and without VSX. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/powerpc/kernel/ptrace.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cb22024f2b4..9321d0f4b6a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request,
if (index < PT_FPR0) {
tmp = ptrace_get_reg(child, (int) index);
} else {
+ unsigned int fpidx = index - PT_FPR0;
+
flush_fp_to_thread(child);
- tmp = ((unsigned long *)child->thread.fpr)
- [TS_FPRWIDTH * (index - PT_FPR0)];
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ tmp = ((unsigned long *)child->thread.fpr)
+ [fpidx * TS_FPRWIDTH];
+ else
+ tmp = child->thread.fpscr.val;
}
ret = put_user(tmp, datalp);
break;
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request,
if (index < PT_FPR0) {
ret = ptrace_put_reg(child, index, data);
} else {
+ unsigned int fpidx = index - PT_FPR0;
+
flush_fp_to_thread(child);
- ((unsigned long *)child->thread.fpr)
- [TS_FPRWIDTH * (index - PT_FPR0)] = data;
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ ((unsigned long *)child->thread.fpr)
+ [fpidx * TS_FPRWIDTH] = data;
+ else
+ child->thread.fpscr.val = data;
ret = 0;
}
break;