aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/lib/sstep.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/lib/sstep.c')
-rw-r--r--arch/powerpc/lib/sstep.c70
1 files changed, 36 insertions, 34 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e0a9858d537e..9a52349874ee 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/kprobes.h> 12#include <linux/kprobes.h>
13#include <linux/ptrace.h> 13#include <linux/ptrace.h>
14#include <linux/prefetch.h>
14#include <asm/sstep.h> 15#include <asm/sstep.h>
15#include <asm/processor.h> 16#include <asm/processor.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
@@ -30,6 +31,7 @@ extern char system_call_common[];
30#define XER_OV 0x40000000U 31#define XER_OV 0x40000000U
31#define XER_CA 0x20000000U 32#define XER_CA 0x20000000U
32 33
34#ifdef CONFIG_PPC_FPU
33/* 35/*
34 * Functions in ldstfp.S 36 * Functions in ldstfp.S
35 */ 37 */
@@ -41,6 +43,19 @@ extern int do_lvx(int rn, unsigned long ea);
41extern int do_stvx(int rn, unsigned long ea); 43extern int do_stvx(int rn, unsigned long ea);
42extern int do_lxvd2x(int rn, unsigned long ea); 44extern int do_lxvd2x(int rn, unsigned long ea);
43extern int do_stxvd2x(int rn, unsigned long ea); 45extern int do_stxvd2x(int rn, unsigned long ea);
46#endif
47
48/*
49 * Emulate the truncation of 64 bit values in 32-bit mode.
50 */
51static unsigned long truncate_if_32bit(unsigned long msr, unsigned long val)
52{
53#ifdef __powerpc64__
54 if ((msr & MSR_64BIT) == 0)
55 val &= 0xffffffffUL;
56#endif
57 return val;
58}
44 59
45/* 60/*
46 * Determine whether a conditional branch instruction would branch. 61 * Determine whether a conditional branch instruction would branch.
@@ -88,11 +103,8 @@ static unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs
88 if (instr & 0x04000000) /* update forms */ 103 if (instr & 0x04000000) /* update forms */
89 regs->gpr[ra] = ea; 104 regs->gpr[ra] = ea;
90 } 105 }
91#ifdef __powerpc64__ 106
92 if (!(regs->msr & MSR_SF)) 107 return truncate_if_32bit(regs->msr, ea);
93 ea &= 0xffffffffUL;
94#endif
95 return ea;
96} 108}
97 109
98#ifdef __powerpc64__ 110#ifdef __powerpc64__
@@ -111,9 +123,8 @@ static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *reg
111 if ((instr & 3) == 1) /* update forms */ 123 if ((instr & 3) == 1) /* update forms */
112 regs->gpr[ra] = ea; 124 regs->gpr[ra] = ea;
113 } 125 }
114 if (!(regs->msr & MSR_SF)) 126
115 ea &= 0xffffffffUL; 127 return truncate_if_32bit(regs->msr, ea);
116 return ea;
117} 128}
118#endif /* __powerpc64 */ 129#endif /* __powerpc64 */
119 130
@@ -134,11 +145,8 @@ static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs
134 if (do_update) /* update forms */ 145 if (do_update) /* update forms */
135 regs->gpr[ra] = ea; 146 regs->gpr[ra] = ea;
136 } 147 }
137#ifdef __powerpc64__ 148
138 if (!(regs->msr & MSR_SF)) 149 return truncate_if_32bit(regs->msr, ea);
139 ea &= 0xffffffffUL;
140#endif
141 return ea;
142} 150}
143 151
144/* 152/*
@@ -290,6 +298,7 @@ static int __kprobes write_mem(unsigned long val, unsigned long ea, int nb,
290 return write_mem_unaligned(val, ea, nb, regs); 298 return write_mem_unaligned(val, ea, nb, regs);
291} 299}
292 300
301#ifdef CONFIG_PPC_FPU
293/* 302/*
294 * Check the address and alignment, and call func to do the actual 303 * Check the address and alignment, and call func to do the actual
295 * load or store. 304 * load or store.
@@ -351,6 +360,7 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
351 } 360 }
352 return err; 361 return err;
353} 362}
363#endif
354 364
355#ifdef CONFIG_ALTIVEC 365#ifdef CONFIG_ALTIVEC
356/* For Altivec/VMX, no need to worry about alignment */ 366/* For Altivec/VMX, no need to worry about alignment */
@@ -462,7 +472,7 @@ static void __kprobes set_cr0(struct pt_regs *regs, int rd)
462 472
463 regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); 473 regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
464#ifdef __powerpc64__ 474#ifdef __powerpc64__
465 if (!(regs->msr & MSR_SF)) 475 if (!(regs->msr & MSR_64BIT))
466 val = (int) val; 476 val = (int) val;
467#endif 477#endif
468 if (val < 0) 478 if (val < 0)
@@ -483,7 +493,7 @@ static void __kprobes add_with_carry(struct pt_regs *regs, int rd,
483 ++val; 493 ++val;
484 regs->gpr[rd] = val; 494 regs->gpr[rd] = val;
485#ifdef __powerpc64__ 495#ifdef __powerpc64__
486 if (!(regs->msr & MSR_SF)) { 496 if (!(regs->msr & MSR_64BIT)) {
487 val = (unsigned int) val; 497 val = (unsigned int) val;
488 val1 = (unsigned int) val1; 498 val1 = (unsigned int) val1;
489 } 499 }
@@ -566,8 +576,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
566 if ((instr & 2) == 0) 576 if ((instr & 2) == 0)
567 imm += regs->nip; 577 imm += regs->nip;
568 regs->nip += 4; 578 regs->nip += 4;
569 if ((regs->msr & MSR_SF) == 0) 579 regs->nip = truncate_if_32bit(regs->msr, regs->nip);
570 regs->nip &= 0xffffffffUL;
571 if (instr & 1) 580 if (instr & 1)
572 regs->link = regs->nip; 581 regs->link = regs->nip;
573 if (branch_taken(instr, regs)) 582 if (branch_taken(instr, regs))
@@ -600,13 +609,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
600 imm -= 0x04000000; 609 imm -= 0x04000000;
601 if ((instr & 2) == 0) 610 if ((instr & 2) == 0)
602 imm += regs->nip; 611 imm += regs->nip;
603 if (instr & 1) { 612 if (instr & 1)
604 regs->link = regs->nip + 4; 613 regs->link = truncate_if_32bit(regs->msr, regs->nip + 4);
605 if ((regs->msr & MSR_SF) == 0) 614 imm = truncate_if_32bit(regs->msr, imm);
606 regs->link &= 0xffffffffUL;
607 }
608 if ((regs->msr & MSR_SF) == 0)
609 imm &= 0xffffffffUL;
610 regs->nip = imm; 615 regs->nip = imm;
611 return 1; 616 return 1;
612 case 19: 617 case 19:
@@ -614,11 +619,8 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
614 case 16: /* bclr */ 619 case 16: /* bclr */
615 case 528: /* bcctr */ 620 case 528: /* bcctr */
616 imm = (instr & 0x400)? regs->ctr: regs->link; 621 imm = (instr & 0x400)? regs->ctr: regs->link;
617 regs->nip += 4; 622 regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
618 if ((regs->msr & MSR_SF) == 0) { 623 imm = truncate_if_32bit(regs->msr, imm);
619 regs->nip &= 0xffffffffUL;
620 imm &= 0xffffffffUL;
621 }
622 if (instr & 1) 624 if (instr & 1)
623 regs->link = regs->nip; 625 regs->link = regs->nip;
624 if (branch_taken(instr, regs)) 626 if (branch_taken(instr, regs))
@@ -1393,6 +1395,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1393 regs->gpr[rd] = byterev_4(val); 1395 regs->gpr[rd] = byterev_4(val);
1394 goto ldst_done; 1396 goto ldst_done;
1395 1397
1398#ifdef CONFIG_PPC_CPU
1396 case 535: /* lfsx */ 1399 case 535: /* lfsx */
1397 case 567: /* lfsux */ 1400 case 567: /* lfsux */
1398 if (!(regs->msr & MSR_FP)) 1401 if (!(regs->msr & MSR_FP))
@@ -1424,6 +1427,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1424 ea = xform_ea(instr, regs, u); 1427 ea = xform_ea(instr, regs, u);
1425 err = do_fp_store(rd, do_stfd, ea, 8, regs); 1428 err = do_fp_store(rd, do_stfd, ea, 8, regs);
1426 goto ldst_done; 1429 goto ldst_done;
1430#endif
1427 1431
1428#ifdef __powerpc64__ 1432#ifdef __powerpc64__
1429 case 660: /* stdbrx */ 1433 case 660: /* stdbrx */
@@ -1534,6 +1538,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1534 } while (++rd < 32); 1538 } while (++rd < 32);
1535 goto instr_done; 1539 goto instr_done;
1536 1540
1541#ifdef CONFIG_PPC_FPU
1537 case 48: /* lfs */ 1542 case 48: /* lfs */
1538 case 49: /* lfsu */ 1543 case 49: /* lfsu */
1539 if (!(regs->msr & MSR_FP)) 1544 if (!(regs->msr & MSR_FP))
@@ -1565,6 +1570,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1565 ea = dform_ea(instr, regs); 1570 ea = dform_ea(instr, regs);
1566 err = do_fp_store(rd, do_stfd, ea, 8, regs); 1571 err = do_fp_store(rd, do_stfd, ea, 8, regs);
1567 goto ldst_done; 1572 goto ldst_done;
1573#endif
1568 1574
1569#ifdef __powerpc64__ 1575#ifdef __powerpc64__
1570 case 58: /* ld[u], lwa */ 1576 case 58: /* ld[u], lwa */
@@ -1608,11 +1614,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1608 return 0; /* invoke DSI if -EFAULT? */ 1614 return 0; /* invoke DSI if -EFAULT? */
1609 } 1615 }
1610 instr_done: 1616 instr_done:
1611 regs->nip += 4; 1617 regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
1612#ifdef __powerpc64__
1613 if ((regs->msr & MSR_SF) == 0)
1614 regs->nip &= 0xffffffffUL;
1615#endif
1616 return 1; 1618 return 1;
1617 1619
1618 logical_done: 1620 logical_done: