aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-26 15:37:57 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-29 03:02:04 -0400
commite69b742a6793dc5bf16f6eedca534d4bc10d68b2 (patch)
tree63765003b6dcffd410d82e3ea2ecd10153596570 /arch/powerpc
parent66857b3a9e88ac6f6e279eaa06b84367e662c0dd (diff)
powerpc/ptrace: Fix build with gcc 4.6
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>
Diffstat (limited to 'arch/powerpc')
-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 05b7dd217f60..18447c4fbad3 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,
1497 if (index < PT_FPR0) { 1497 if (index < PT_FPR0) {
1498 tmp = ptrace_get_reg(child, (int) index); 1498 tmp = ptrace_get_reg(child, (int) index);
1499 } else { 1499 } else {
1500 unsigned int fpidx = index - PT_FPR0;
1501
1500 flush_fp_to_thread(child); 1502 flush_fp_to_thread(child);
1501 tmp = ((unsigned long *)child->thread.fpr) 1503 if (fpidx < (PT_FPSCR - PT_FPR0))
1502 [TS_FPRWIDTH * (index - PT_FPR0)]; 1504 tmp = ((unsigned long *)child->thread.fpr)
1505 [fpidx * TS_FPRWIDTH];
1506 else
1507 tmp = child->thread.fpscr.val;
1503 } 1508 }
1504 ret = put_user(tmp, datalp); 1509 ret = put_user(tmp, datalp);
1505 break; 1510 break;
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request,
1525 if (index < PT_FPR0) { 1530 if (index < PT_FPR0) {
1526 ret = ptrace_put_reg(child, index, data); 1531 ret = ptrace_put_reg(child, index, data);
1527 } else { 1532 } else {
1533 unsigned int fpidx = index - PT_FPR0;
1534
1528 flush_fp_to_thread(child); 1535 flush_fp_to_thread(child);
1529 ((unsigned long *)child->thread.fpr) 1536 if (fpidx < (PT_FPSCR - PT_FPR0))
1530 [TS_FPRWIDTH * (index - PT_FPR0)] = data; 1537 ((unsigned long *)child->thread.fpr)
1538 [fpidx * TS_FPRWIDTH] = data;
1539 else
1540 child->thread.fpscr.val = data;
1531 ret = 0; 1541 ret = 0;
1532 } 1542 }
1533 break; 1543 break;