aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/lib')
-rw-r--r--arch/powerpc/lib/sstep.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 209a506f8517..54651fc2d412 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1433,11 +1433,24 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs,
1433 break; 1433 break;
1434 1434
1435#endif 1435#endif
1436 case 533: /* lswx */
1437 op->type = MKOP(LOAD_MULTI, 0, regs->xer & 0x7f);
1438 break;
1436 1439
1437 case 534: /* lwbrx */ 1440 case 534: /* lwbrx */
1438 op->type = MKOP(LOAD, BYTEREV, 4); 1441 op->type = MKOP(LOAD, BYTEREV, 4);
1439 break; 1442 break;
1440 1443
1444 case 597: /* lswi */
1445 if (rb == 0)
1446 rb = 32; /* # bytes to load */
1447 op->type = MKOP(LOAD_MULTI, 0, rb);
1448 op->ea = 0;
1449 if (ra)
1450 op->ea = truncate_if_32bit(regs->msr,
1451 regs->gpr[ra]);
1452 break;
1453
1441#ifdef CONFIG_PPC_FPU 1454#ifdef CONFIG_PPC_FPU
1442 case 535: /* lfsx */ 1455 case 535: /* lfsx */
1443 case 567: /* lfsux */ 1456 case 567: /* lfsux */
@@ -1475,11 +1488,25 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs,
1475 break; 1488 break;
1476 1489
1477#endif 1490#endif
1491 case 661: /* stswx */
1492 op->type = MKOP(STORE_MULTI, 0, regs->xer & 0x7f);
1493 break;
1494
1478 case 662: /* stwbrx */ 1495 case 662: /* stwbrx */
1479 op->type = MKOP(STORE, BYTEREV, 4); 1496 op->type = MKOP(STORE, BYTEREV, 4);
1480 op->val = byterev_4(regs->gpr[rd]); 1497 op->val = byterev_4(regs->gpr[rd]);
1481 break; 1498 break;
1482 1499
1500 case 725:
1501 if (rb == 0)
1502 rb = 32; /* # bytes to store */
1503 op->type = MKOP(STORE_MULTI, 0, rb);
1504 op->ea = 0;
1505 if (ra)
1506 op->ea = truncate_if_32bit(regs->msr,
1507 regs->gpr[ra]);
1508 break;
1509
1483 case 790: /* lhbrx */ 1510 case 790: /* lhbrx */
1484 op->type = MKOP(LOAD, BYTEREV, 2); 1511 op->type = MKOP(LOAD, BYTEREV, 2);
1485 break; 1512 break;
@@ -1553,15 +1580,14 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs,
1553 break; 1580 break;
1554 1581
1555 case 46: /* lmw */ 1582 case 46: /* lmw */
1556 ra = (instr >> 16) & 0x1f;
1557 if (ra >= rd) 1583 if (ra >= rd)
1558 break; /* invalid form, ra in range to load */ 1584 break; /* invalid form, ra in range to load */
1559 op->type = MKOP(LOAD_MULTI, 0, 4); 1585 op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
1560 op->ea = dform_ea(instr, regs); 1586 op->ea = dform_ea(instr, regs);
1561 break; 1587 break;
1562 1588
1563 case 47: /* stmw */ 1589 case 47: /* stmw */
1564 op->type = MKOP(STORE_MULTI, 0, 4); 1590 op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
1565 op->ea = dform_ea(instr, regs); 1591 op->ea = dform_ea(instr, regs);
1566 break; 1592 break;
1567 1593
@@ -1744,7 +1770,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1744 int r, err, size; 1770 int r, err, size;
1745 unsigned long val; 1771 unsigned long val;
1746 unsigned int cr; 1772 unsigned int cr;
1747 int rd; 1773 int i, rd, nb;
1748 1774
1749 r = analyse_instr(&op, regs, instr); 1775 r = analyse_instr(&op, regs, instr);
1750 if (r != 0) 1776 if (r != 0)
@@ -1866,12 +1892,18 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1866 if (regs->msr & MSR_LE) 1892 if (regs->msr & MSR_LE)
1867 return 0; 1893 return 0;
1868 rd = op.reg; 1894 rd = op.reg;
1869 do { 1895 for (i = 0; i < size; i += 4) {
1870 err = read_mem(&regs->gpr[rd], op.ea, 4, regs); 1896 nb = size - i;
1897 if (nb > 4)
1898 nb = 4;
1899 err = read_mem(&regs->gpr[rd], op.ea, nb, regs);
1871 if (err) 1900 if (err)
1872 return 0; 1901 return 0;
1902 if (nb < 4) /* left-justify last bytes */
1903 regs->gpr[rd] <<= 32 - 8 * nb;
1873 op.ea += 4; 1904 op.ea += 4;
1874 } while (++rd < 32); 1905 ++rd;
1906 }
1875 goto instr_done; 1907 goto instr_done;
1876 1908
1877 case STORE: 1909 case STORE:
@@ -1914,12 +1946,19 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1914 if (regs->msr & MSR_LE) 1946 if (regs->msr & MSR_LE)
1915 return 0; 1947 return 0;
1916 rd = op.reg; 1948 rd = op.reg;
1917 do { 1949 for (i = 0; i < size; i += 4) {
1918 err = write_mem(regs->gpr[rd], op.ea, 4, regs); 1950 val = regs->gpr[rd];
1951 nb = size - i;
1952 if (nb > 4)
1953 nb = 4;
1954 else
1955 val >>= 32 - 8 * nb;
1956 err = write_mem(val, op.ea, nb, regs);
1919 if (err) 1957 if (err)
1920 return 0; 1958 return 0;
1921 op.ea += 4; 1959 op.ea += 4;
1922 } while (++rd < 32); 1960 ++rd;
1961 }
1923 goto instr_done; 1962 goto instr_done;
1924 1963
1925 case MFMSR: 1964 case MFMSR: