Merge branch 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm: (47 commits)
CLKDEV: Fix clkdev return value for NULL clk case
ARM: 6891/1: prevent heap corruption in OABI semtimedop
ARM: kprobes: Tidy-up kprobes-decode.c
ARM: kprobes: Add emulation of hint instructions like NOP and WFI
ARM: kprobes: Add emulation of SBFX, UBFX, BFI and BFC instructions
ARM: kprobes: Add emulation of MOVW and MOVT instructions
ARM: kprobes: Reject probing of undefined data processing instructions
ARM: kprobes: Remove redundant code in space_1111
ARM: kprobes: Fix emulation of PLD instructions
ARM: kprobes: Reject probing of SETEND instructions
ARM: kprobes: Consolidate stub decoding functions
ARM: kprobes: Reject probing of all coprocessor instructions
ARM: kprobes: Fix emulation of USAD8 instructions
ARM: kprobes: Fix emulation of SMUAD, SMUSD and SMMUL instructions
ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions
ARM: kprobes: Reject probing of undefined media instructions
ARM: kprobes: Add emulation of RBIT instruction
ARM: kprobes: Reject probing of LDRB instructions which load PC
ARM: kprobes: Fix emulation of LDRD and STRD instructions
ARM: kprobes: Reject probing of LDR/STR instructions which update PC unpredictably
...

+536 -361
+3
arch/arm/include/asm/kprobes.h
··· 39 39 struct kprobe; 40 40 typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); 41 41 42 + typedef unsigned long (kprobe_check_cc)(unsigned long); 43 + 42 44 /* Architecture specific copy of original instruction. */ 43 45 struct arch_specific_insn { 44 46 kprobe_opcode_t *insn; 45 47 kprobe_insn_handler_t *insn_handler; 48 + kprobe_check_cc *insn_check_cc; 46 49 }; 47 50 48 51 struct prev_kprobe {
+465 -328
arch/arm/kernel/kprobes-decode.c
··· 34 34 * 35 35 * *) If the PC is written to by the instruction, the 36 36 * instruction must be fully simulated in software. 37 - * If it is a conditional instruction, the handler 38 - * will use insn[0] to copy its condition code to 39 - * set r0 to 1 and insn[1] to "mov pc, lr" to return. 40 37 * 41 38 * *) Otherwise, a modified form of the instruction is 42 39 * directly executed. Its handler calls the ··· 65 68 66 69 #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) 67 70 71 + #define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos)) 72 + 73 + /* 74 + * Test if load/store instructions writeback the address register. 75 + * if P (bit 24) == 0 or W (bit 21) == 1 76 + */ 77 + #define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) 78 + 68 79 #define PSR_fs (PSR_f|PSR_s) 69 80 70 81 #define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ 71 - #define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */ 72 - 73 - #define truecc_insn(insn) (((insn) & 0xf0000000) | \ 74 - (SET_R0_TRUE_INSTRUCTION & 0x0fffffff)) 75 82 76 83 typedef long (insn_0arg_fn_t)(void); 77 84 typedef long (insn_1arg_fn_t)(long); ··· 420 419 421 420 static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) 422 421 { 423 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 424 422 kprobe_opcode_t insn = p->opcode; 425 423 long iaddr = (long)p->addr; 426 424 int disp = branch_displacement(insn); 427 - 428 - if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) 429 - return; 430 425 431 426 if (insn & (1 << 24)) 432 427 regs->ARM_lr = iaddr + 4; ··· 443 446 444 447 static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) 445 448 { 446 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 447 449 kprobe_opcode_t insn = p->opcode; 448 450 int rm = insn & 0xf; 449 451 long rmv = regs->uregs[rm]; 450 - 451 - if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) 452 - return; 453 452 454 453 if (insn & (1 << 5)) 455 454 regs->ARM_lr = (long)p->addr + 4; ··· 456 463 regs->ARM_cpsr |= PSR_T_BIT; 457 464 } 458 465 466 + static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs) 467 + { 468 + kprobe_opcode_t insn = p->opcode; 469 + int rd = (insn >> 12) & 0xf; 470 + unsigned long mask = 0xf8ff03df; /* Mask out execution state */ 471 + regs->uregs[rd] = regs->ARM_cpsr & mask; 472 + } 473 + 459 474 static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) 460 475 { 461 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 462 476 kprobe_opcode_t insn = p->opcode; 463 477 int rn = (insn >> 16) & 0xf; 464 478 int lbit = insn & (1 << 20); ··· 475 475 long *addr = (long *)regs->uregs[rn]; 476 476 int reg_bit_vector; 477 477 int reg_count; 478 - 479 - if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) 480 - return; 481 478 482 479 reg_count = 0; 483 480 reg_bit_vector = insn & 0xffff; ··· 507 510 508 511 static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) 509 512 { 510 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 511 - 512 - if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) 513 - return; 514 - 515 513 regs->ARM_pc = (long)p->addr + str_pc_offset; 516 514 simulate_ldm1stm1(p, regs); 517 515 regs->ARM_pc = (long)p->addr + 4; ··· 517 525 regs->uregs[12] = regs->uregs[13]; 518 526 } 519 527 520 - static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs) 521 - { 522 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 523 - kprobe_opcode_t insn = p->opcode; 524 - int rn = (insn >> 16) & 0xf; 525 - long rnv = regs->uregs[rn]; 526 - 527 - /* Save Rn in case of writeback. */ 528 - regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); 529 - } 530 - 531 528 static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) 532 529 { 533 530 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; 534 531 kprobe_opcode_t insn = p->opcode; 532 + long ppc = (long)p->addr + 8; 535 533 int rd = (insn >> 12) & 0xf; 536 534 int rn = (insn >> 16) & 0xf; 537 535 int rm = insn & 0xf; /* rm may be invalid, don't care. */ 536 + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; 537 + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; 538 538 539 539 /* Not following the C calling convention here, so need asm(). */ 540 540 __asm__ __volatile__ ( ··· 538 554 "str r0, %[rn] \n\t" /* in case of writeback */ 539 555 "str r2, %[rd0] \n\t" 540 556 "str r3, %[rd1] \n\t" 541 - : [rn] "+m" (regs->uregs[rn]), 557 + : [rn] "+m" (rnv), 542 558 [rd0] "=m" (regs->uregs[rd]), 543 559 [rd1] "=m" (regs->uregs[rd+1]) 544 - : [rm] "m" (regs->uregs[rm]), 560 + : [rm] "m" (rmv), 545 561 [cpsr] "r" (regs->ARM_cpsr), 546 562 [i_fn] "r" (i_fn) 547 563 : "r0", "r1", "r2", "r3", "lr", "cc" 548 564 ); 565 + if (is_writeback(insn)) 566 + regs->uregs[rn] = rnv; 549 567 } 550 568 551 569 static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) 552 570 { 553 571 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; 554 572 kprobe_opcode_t insn = p->opcode; 573 + long ppc = (long)p->addr + 8; 555 574 int rd = (insn >> 12) & 0xf; 556 575 int rn = (insn >> 16) & 0xf; 557 576 int rm = insn & 0xf; 558 - long rnv = regs->uregs[rn]; 559 - long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ 577 + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; 578 + /* rm/rmv may be invalid, don't care. */ 579 + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; 580 + long rnv_wb; 560 581 561 - regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], 582 + rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], 562 583 regs->uregs[rd+1], 563 584 regs->ARM_cpsr, i_fn); 585 + if (is_writeback(insn)) 586 + regs->uregs[rn] = rnv_wb; 564 587 } 565 588 566 589 static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) ··· 621 630 regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */ 622 631 } 623 632 624 - static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs) 625 - { 626 - insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0]; 627 - kprobe_opcode_t insn = p->opcode; 628 - union reg_pair fnr; 629 - int rd = (insn >> 12) & 0xf; 630 - int rn = (insn >> 16) & 0xf; 631 - 632 - fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn); 633 - regs->uregs[rn] = fnr.r0; 634 - regs->uregs[rd] = fnr.r1; 635 - } 636 - 637 - static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs) 638 - { 639 - insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; 640 - kprobe_opcode_t insn = p->opcode; 641 - int rd = (insn >> 12) & 0xf; 642 - int rn = (insn >> 16) & 0xf; 643 - long rnv = regs->uregs[rn]; 644 - long rdv = regs->uregs[rd]; 645 - 646 - insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn); 647 - } 648 - 649 633 static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) 650 634 { 651 635 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; ··· 654 688 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); 655 689 } 656 690 657 - static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) 691 + static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs) 658 692 { 659 - insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0]; 693 + } 694 + 695 + static void __kprobes 696 + emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs) 697 + { 698 + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 660 699 kprobe_opcode_t insn = p->opcode; 661 700 int rd = (insn >> 12) & 0xf; 701 + long rdv = regs->uregs[rd]; 662 702 663 - regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); 703 + regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn); 664 704 } 665 705 666 - static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) 706 + static void __kprobes 707 + emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs) 667 708 { 668 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 709 + insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; 669 710 kprobe_opcode_t insn = p->opcode; 670 - int ird = (insn >> 12) & 0xf; 671 - 672 - insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); 673 - } 674 - 675 - static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) 676 - { 677 - insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 678 - kprobe_opcode_t insn = p->opcode; 679 - int rn = (insn >> 16) & 0xf; 711 + int rd = (insn >> 12) & 0xf; 712 + int rn = insn & 0xf; 713 + long rdv = regs->uregs[rd]; 680 714 long rnv = regs->uregs[rn]; 681 715 682 - insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); 716 + regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn); 683 717 } 684 718 685 719 static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) ··· 785 819 } 786 820 787 821 static void __kprobes 822 + emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs) 823 + { 824 + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 825 + kprobe_opcode_t insn = p->opcode; 826 + int rn = (insn >> 16) & 0xf; 827 + long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn]; 828 + 829 + insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn); 830 + } 831 + 832 + static void __kprobes 788 833 emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) 789 834 { 790 835 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; ··· 831 854 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn); 832 855 } 833 856 857 + static void __kprobes 858 + emulate_alu_tests(struct kprobe *p, struct pt_regs *regs) 859 + { 860 + insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; 861 + kprobe_opcode_t insn = p->opcode; 862 + long ppc = (long)p->addr + 8; 863 + int rn = (insn >> 16) & 0xf; 864 + int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */ 865 + int rm = insn & 0xf; 866 + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; 867 + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; 868 + long rsv = regs->uregs[rs]; 869 + 870 + insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn); 871 + } 872 + 834 873 static enum kprobe_insn __kprobes 835 874 prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) 836 875 { 837 - int ibit = (insn & (1 << 26)) ? 25 : 22; 876 + int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25)) 877 + : (~insn & (1 << 22)); 878 + 879 + if (is_writeback(insn) && is_r15(insn, 16)) 880 + return INSN_REJECTED; /* Writeback to PC */ 838 881 839 882 insn &= 0xfff00fff; 840 883 insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 841 - if (insn & (1 << ibit)) { 884 + if (not_imm) { 842 885 insn &= ~0xf; 843 886 insn |= 2; /* Rm = r2 */ 844 887 } ··· 868 871 } 869 872 870 873 static enum kprobe_insn __kprobes 874 + prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi) 875 + { 876 + if (is_r15(insn, 12)) 877 + return INSN_REJECTED; /* Rd is PC */ 878 + 879 + insn &= 0xffff0fff; /* Rd = r0 */ 880 + asi->insn[0] = insn; 881 + asi->insn_handler = emulate_rd12_modify; 882 + return INSN_GOOD; 883 + } 884 + 885 + static enum kprobe_insn __kprobes 886 + prep_emulate_rd12rn0_modify(kprobe_opcode_t insn, 887 + struct arch_specific_insn *asi) 888 + { 889 + if (is_r15(insn, 12)) 890 + return INSN_REJECTED; /* Rd is PC */ 891 + 892 + insn &= 0xffff0ff0; /* Rd = r0 */ 893 + insn |= 0x00000001; /* Rn = r1 */ 894 + asi->insn[0] = insn; 895 + asi->insn_handler = emulate_rd12rn0_modify; 896 + return INSN_GOOD; 897 + } 898 + 899 + static enum kprobe_insn __kprobes 871 900 prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) 872 901 { 902 + if (is_r15(insn, 12)) 903 + return INSN_REJECTED; /* Rd is PC */ 904 + 873 905 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 874 906 asi->insn[0] = insn; 875 907 asi->insn_handler = emulate_rd12rm0; ··· 906 880 } 907 881 908 882 static enum kprobe_insn __kprobes 909 - prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) 910 - { 911 - insn &= 0xffff0fff; /* Rd = r0 */ 912 - asi->insn[0] = insn; 913 - asi->insn_handler = emulate_rd12; 914 - return INSN_GOOD; 915 - } 916 - 917 - static enum kprobe_insn __kprobes 918 883 prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, 919 884 struct arch_specific_insn *asi) 920 885 { 886 + if (is_r15(insn, 12)) 887 + return INSN_REJECTED; /* Rd is PC */ 888 + 921 889 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 922 890 insn |= 0x00000001; /* Rm = r1 */ 923 891 asi->insn[0] = insn; ··· 923 903 prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, 924 904 struct arch_specific_insn *asi) 925 905 { 906 + if (is_r15(insn, 16)) 907 + return INSN_REJECTED; /* Rd is PC */ 908 + 926 909 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ 927 910 insn |= 0x00000001; /* Rm = r1 */ 928 911 asi->insn[0] = insn; ··· 937 914 prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, 938 915 struct arch_specific_insn *asi) 939 916 { 917 + if (is_r15(insn, 16)) 918 + return INSN_REJECTED; /* Rd is PC */ 919 + 940 920 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ 941 921 insn |= 0x00000102; /* Rs = r1, Rm = r2 */ 942 922 asi->insn[0] = insn; ··· 951 925 prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, 952 926 struct arch_specific_insn *asi) 953 927 { 928 + if (is_r15(insn, 16) || is_r15(insn, 12)) 929 + return INSN_REJECTED; /* RdHi or RdLo is PC */ 930 + 954 931 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ 955 932 insn |= 0x00001203; /* Rs = r2, Rm = r3 */ 956 933 asi->insn[0] = insn; ··· 974 945 static enum kprobe_insn __kprobes 975 946 space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) 976 947 { 977 - /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ 978 - /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ 979 - /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ 980 - if ((insn & 0xfff30020) == 0xf1020000 || 981 - (insn & 0xfe500f00) == 0xf8100a00 || 982 - (insn & 0xfe5f0f00) == 0xf84d0500) 983 - return INSN_REJECTED; 984 - 985 - /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */ 986 - if ((insn & 0xfd700000) == 0xf4500000) { 987 - insn &= 0xfff0ffff; /* Rn = r0 */ 988 - asi->insn[0] = insn; 989 - asi->insn_handler = emulate_rn16; 990 - return INSN_GOOD; 948 + /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */ 949 + /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */ 950 + /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */ 951 + /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */ 952 + if ((insn & 0xfe300000) == 0xf4100000) { 953 + asi->insn_handler = emulate_nop; 954 + return INSN_GOOD_NO_SLOT; 991 955 } 992 956 993 957 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ ··· 989 967 return INSN_GOOD_NO_SLOT; 990 968 } 991 969 992 - /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 993 - /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 994 - if ((insn & 0xffff00f0) == 0xf1010000 || 995 - (insn & 0xff000010) == 0xfe000000) { 996 - asi->insn[0] = insn; 997 - asi->insn_handler = emulate_none; 998 - return INSN_GOOD; 999 - } 970 + /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ 971 + /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 1000 972 973 + /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ 974 + /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 975 + 976 + /* Coprocessor instructions... */ 1001 977 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 1002 978 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 1003 - if ((insn & 0xffe00000) == 0xfc400000) { 1004 - insn &= 0xfff00fff; /* Rn = r0 */ 1005 - insn |= 0x00001000; /* Rd = r1 */ 1006 - asi->insn[0] = insn; 1007 - asi->insn_handler = 1008 - (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; 1009 - return INSN_GOOD; 1010 - } 979 + /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 980 + /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ 981 + /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 982 + /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 983 + /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1011 984 1012 - /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1013 - /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ 1014 - if ((insn & 0xfe000000) == 0xfc000000) { 1015 - insn &= 0xfff0ffff; /* Rn = r0 */ 1016 - asi->insn[0] = insn; 1017 - asi->insn_handler = emulate_ldcstc; 1018 - return INSN_GOOD; 1019 - } 1020 - 1021 - /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 1022 - /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1023 - insn &= 0xffff0fff; /* Rd = r0 */ 1024 - asi->insn[0] = insn; 1025 - asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; 1026 - return INSN_GOOD; 985 + return INSN_REJECTED; 1027 986 } 1028 987 1029 988 static enum kprobe_insn __kprobes ··· 1013 1010 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1014 1011 if ((insn & 0x0f900010) == 0x01000000) { 1015 1012 1016 - /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ 1017 - /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ 1018 - if ((insn & 0x0ff000f0) == 0x01200020 || 1019 - (insn & 0x0fb000f0) == 0x01200000) 1020 - return INSN_REJECTED; 1021 - 1022 - /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ 1023 - if ((insn & 0x0fb00010) == 0x01000000) 1024 - return prep_emulate_rd12(insn, asi); 1013 + /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ 1014 + if ((insn & 0x0ff000f0) == 0x01000000) { 1015 + if (is_r15(insn, 12)) 1016 + return INSN_REJECTED; /* Rd is PC */ 1017 + asi->insn_handler = simulate_mrs; 1018 + return INSN_GOOD_NO_SLOT; 1019 + } 1025 1020 1026 1021 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ 1027 1022 if ((insn & 0x0ff00090) == 0x01400080) 1028 - return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1023 + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, 1024 + asi); 1029 1025 1030 1026 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ 1031 1027 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ ··· 1033 1031 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1034 1032 1035 1033 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ 1036 - /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ 1037 - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1034 + /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */ 1035 + if ((insn & 0x0ff00090) == 0x01000080 || 1036 + (insn & 0x0ff000b0) == 0x01200080) 1037 + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1038 1038 1039 + /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ 1040 + /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ 1041 + /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ 1042 + 1043 + /* Other instruction encodings aren't yet defined */ 1044 + return INSN_REJECTED; 1039 1045 } 1040 1046 1041 1047 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ 1042 1048 else if ((insn & 0x0f900090) == 0x01000010) { 1043 1049 1044 - /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ 1045 - if ((insn & 0xfff000f0) == 0xe1200070) 1046 - return INSN_REJECTED; 1047 - 1048 1050 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ 1049 1051 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ 1050 1052 if ((insn & 0x0ff000d0) == 0x01200010) { 1051 - asi->insn[0] = truecc_insn(insn); 1053 + if ((insn & 0x0ff000ff) == 0x0120003f) 1054 + return INSN_REJECTED; /* BLX pc */ 1052 1055 asi->insn_handler = simulate_blx2bx; 1053 - return INSN_GOOD; 1056 + return INSN_GOOD_NO_SLOT; 1054 1057 } 1055 1058 1056 1059 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ ··· 1066 1059 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ 1067 1060 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ 1068 1061 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ 1069 - return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1062 + if ((insn & 0x0f9000f0) == 0x01000050) 1063 + return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1064 + 1065 + /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ 1066 + /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ 1067 + 1068 + /* Other instruction encodings aren't yet defined */ 1069 + return INSN_REJECTED; 1070 1070 } 1071 1071 1072 1072 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ 1073 - else if ((insn & 0x0f000090) == 0x00000090) { 1073 + else if ((insn & 0x0f0000f0) == 0x00000090) { 1074 1074 1075 1075 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ 1076 1076 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ 1077 1077 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ 1078 1078 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ 1079 1079 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ 1080 + /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */ 1081 + /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */ 1082 + /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */ 1080 1083 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ 1081 1084 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ 1082 1085 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ ··· 1095 1078 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ 1096 1079 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ 1097 1080 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ 1098 - if ((insn & 0x0fe000f0) == 0x00000090) { 1099 - return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1100 - } else if ((insn & 0x0fe000f0) == 0x00200090) { 1101 - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1102 - } else { 1103 - return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1104 - } 1081 + if ((insn & 0x00d00000) == 0x00500000) 1082 + return INSN_REJECTED; 1083 + else if ((insn & 0x00e00000) == 0x00000000) 1084 + return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1085 + else if ((insn & 0x00a00000) == 0x00200000) 1086 + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1087 + else 1088 + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, 1089 + asi); 1105 1090 } 1106 1091 1107 1092 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ ··· 1111 1092 1112 1093 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ 1113 1094 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ 1114 - /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ 1115 - /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ 1095 + /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */ 1096 + /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */ 1097 + /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */ 1116 1098 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ 1117 1099 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ 1100 + /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */ 1101 + /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */ 1102 + /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */ 1103 + /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */ 1104 + /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */ 1105 + /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */ 1106 + 1107 + /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ 1108 + /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ 1118 1109 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ 1119 1110 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ 1120 1111 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ 1121 1112 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ 1122 - if ((insn & 0x0fb000f0) == 0x01000090) { 1123 - /* SWP/SWPB */ 1124 - return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1113 + if ((insn & 0x0f0000f0) == 0x01000090) { 1114 + if ((insn & 0x0fb000f0) == 0x01000090) { 1115 + /* SWP/SWPB */ 1116 + return prep_emulate_rd12rn16rm0_wflags(insn, 1117 + asi); 1118 + } else { 1119 + /* STREX/LDREX variants and unallocaed space */ 1120 + return INSN_REJECTED; 1121 + } 1122 + 1125 1123 } else if ((insn & 0x0e1000d0) == 0x00000d0) { 1126 1124 /* STRD/LDRD */ 1125 + if ((insn & 0x0000e000) == 0x0000e000) 1126 + return INSN_REJECTED; /* Rd is LR or PC */ 1127 + if (is_writeback(insn) && is_r15(insn, 16)) 1128 + return INSN_REJECTED; /* Writeback to PC */ 1129 + 1127 1130 insn &= 0xfff00fff; 1128 1131 insn |= 0x00002000; /* Rn = r0, Rd = r2 */ 1129 - if (insn & (1 << 22)) { 1130 - /* I bit */ 1132 + if (!(insn & (1 << 22))) { 1133 + /* Register index */ 1131 1134 insn &= ~0xf; 1132 1135 insn |= 1; /* Rm = r1 */ 1133 1136 } ··· 1159 1118 return INSN_GOOD; 1160 1119 } 1161 1120 1121 + /* LDRH/STRH/LDRSB/LDRSH */ 1122 + if (is_r15(insn, 12)) 1123 + return INSN_REJECTED; /* Rd is PC */ 1162 1124 return prep_emulate_ldr_str(insn, asi); 1163 1125 } 1164 1126 ··· 1169 1125 1170 1126 /* 1171 1127 * ALU op with S bit and Rd == 15 : 1172 - * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx 1128 + * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx 1173 1129 */ 1174 1130 if ((insn & 0x0e10f000) == 0x0010f000) 1175 1131 return INSN_REJECTED; ··· 1198 1154 insn |= 0x00000200; /* Rs = r2 */ 1199 1155 } 1200 1156 asi->insn[0] = insn; 1201 - asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1157 + 1158 + if ((insn & 0x0f900000) == 0x01100000) { 1159 + /* 1160 + * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx 1161 + * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx 1162 + * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx 1163 + * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx 1164 + */ 1165 + asi->insn_handler = emulate_alu_tests; 1166 + } else { 1167 + /* ALU ops which write to Rd */ 1168 + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1202 1169 emulate_alu_rwflags : emulate_alu_rflags; 1170 + } 1203 1171 return INSN_GOOD; 1204 1172 } 1205 1173 1206 1174 static enum kprobe_insn __kprobes 1207 1175 space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1208 1176 { 1177 + /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ 1178 + /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ 1179 + if ((insn & 0x0fb00000) == 0x03000000) 1180 + return prep_emulate_rd12_modify(insn, asi); 1181 + 1182 + /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ 1183 + if ((insn & 0x0fff0000) == 0x03200000) { 1184 + unsigned op2 = insn & 0x000000ff; 1185 + if (op2 == 0x01 || op2 == 0x04) { 1186 + /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ 1187 + /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ 1188 + asi->insn[0] = insn; 1189 + asi->insn_handler = emulate_none; 1190 + return INSN_GOOD; 1191 + } else if (op2 <= 0x03) { 1192 + /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ 1193 + /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ 1194 + /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ 1195 + /* 1196 + * We make WFE and WFI true NOPs to avoid stalls due 1197 + * to missing events whilst processing the probe. 1198 + */ 1199 + asi->insn_handler = emulate_nop; 1200 + return INSN_GOOD_NO_SLOT; 1201 + } 1202 + /* For DBG and unallocated hints it's safest to reject them */ 1203 + return INSN_REJECTED; 1204 + } 1205 + 1209 1206 /* 1210 1207 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx 1211 - * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx 1212 1208 * ALU op with S bit and Rd == 15 : 1213 1209 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx 1214 1210 */ 1215 1211 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ 1216 - (insn & 0x0ff00000) == 0x03400000 || /* Undef */ 1217 1212 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ 1218 1213 return INSN_REJECTED; 1219 1214 ··· 1263 1180 * *S (bit 20) updates condition codes 1264 1181 * ADC/SBC/RSC reads the C flag 1265 1182 */ 1266 - insn &= 0xffff0fff; /* Rd = r0 */ 1183 + insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */ 1267 1184 asi->insn[0] = insn; 1268 - asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1185 + 1186 + if ((insn & 0x0f900000) == 0x03100000) { 1187 + /* 1188 + * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx 1189 + * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx 1190 + * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx 1191 + * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx 1192 + */ 1193 + asi->insn_handler = emulate_alu_tests_imm; 1194 + } else { 1195 + /* ALU ops which write to Rd */ 1196 + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1269 1197 emulate_alu_imm_rwflags : emulate_alu_imm_rflags; 1198 + } 1270 1199 return INSN_GOOD; 1271 1200 } 1272 1201 ··· 1287 1192 { 1288 1193 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ 1289 1194 if ((insn & 0x0ff000f0) == 0x068000b0) { 1195 + if (is_r15(insn, 12)) 1196 + return INSN_REJECTED; /* Rd is PC */ 1290 1197 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 1291 1198 insn |= 0x00000001; /* Rm = r1 */ 1292 1199 asi->insn[0] = insn; ··· 1302 1205 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ 1303 1206 if ((insn & 0x0fa00030) == 0x06a00010 || 1304 1207 (insn & 0x0fb000f0) == 0x06a00030) { 1208 + if (is_r15(insn, 12)) 1209 + return INSN_REJECTED; /* Rd is PC */ 1305 1210 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 1306 1211 asi->insn[0] = insn; 1307 1212 asi->insn_handler = emulate_sat; ··· 1312 1213 1313 1214 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ 1314 1215 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ 1216 + /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ 1315 1217 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ 1316 1218 if ((insn & 0x0ff00070) == 0x06b00030 || 1317 - (insn & 0x0ff000f0) == 0x06f000b0) 1219 + (insn & 0x0ff00070) == 0x06f00030) 1318 1220 return prep_emulate_rd12rm0(insn, asi); 1319 1221 1222 + /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */ 1320 1223 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ 1321 1224 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ 1322 1225 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ 1323 1226 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ 1324 1227 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ 1228 + /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */ 1229 + /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */ 1325 1230 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ 1326 1231 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ 1327 1232 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ 1328 1233 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ 1329 1234 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ 1330 1235 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ 1236 + /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */ 1237 + /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */ 1331 1238 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ 1332 1239 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ 1333 1240 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ 1334 1241 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ 1335 1242 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ 1336 1243 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ 1244 + /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */ 1245 + /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */ 1337 1246 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ 1247 + /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */ 1338 1248 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ 1339 1249 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ 1340 1250 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ 1341 1251 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ 1342 1252 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ 1253 + /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */ 1254 + /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */ 1343 1255 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ 1344 1256 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ 1345 1257 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ 1346 1258 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ 1347 1259 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ 1348 1260 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ 1261 + /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */ 1262 + /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */ 1349 1263 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ 1350 1264 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ 1351 1265 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ 1352 1266 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ 1353 1267 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ 1354 1268 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ 1269 + /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */ 1270 + /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */ 1355 1271 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ 1272 + if ((insn & 0x0f800010) == 0x06000010) { 1273 + if ((insn & 0x00300000) == 0x00000000 || 1274 + (insn & 0x000000e0) == 0x000000a0 || 1275 + (insn & 0x000000e0) == 0x000000c0) 1276 + return INSN_REJECTED; /* Unallocated space */ 1277 + return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1278 + } 1279 + 1356 1280 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ 1357 1281 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ 1282 + if ((insn & 0x0ff00030) == 0x06800010) 1283 + return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1284 + 1358 1285 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ 1359 - /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1286 + /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */ 1287 + /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */ 1360 1288 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1289 + /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */ 1361 1290 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ 1291 + /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */ 1362 1292 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ 1293 + /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */ 1294 + /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */ 1363 1295 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ 1296 + /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */ 1364 1297 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ 1365 - return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1298 + /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */ 1299 + if ((insn & 0x0f8000f0) == 0x06800070) { 1300 + if ((insn & 0x00300000) == 0x00100000) 1301 + return INSN_REJECTED; /* Unallocated space */ 1302 + 1303 + if ((insn & 0x000f0000) == 0x000f0000) 1304 + return prep_emulate_rd12rm0(insn, asi); 1305 + else 1306 + return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1307 + } 1308 + 1309 + /* Other instruction encodings aren't yet defined */ 1310 + return INSN_REJECTED; 1366 1311 } 1367 1312 1368 1313 static enum kprobe_insn __kprobes ··· 1416 1273 if ((insn & 0x0ff000f0) == 0x03f000f0) 1417 1274 return INSN_REJECTED; 1418 1275 1419 - /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ 1420 - /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ 1421 - if ((insn & 0x0ff000f0) == 0x07800010) 1422 - return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1423 - 1424 1276 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ 1425 1277 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ 1426 1278 if ((insn & 0x0ff00090) == 0x07400010) 1427 1279 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1428 1280 1429 1281 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ 1282 + /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ 1430 1283 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ 1284 + /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */ 1431 1285 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ 1432 - /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ 1286 + /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ 1287 + /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */ 1288 + /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */ 1433 1289 if ((insn & 0x0ff00090) == 0x07000010 || 1434 1290 (insn & 0x0ff000d0) == 0x07500010 || 1435 - (insn & 0x0ff000d0) == 0x075000d0) 1291 + (insn & 0x0ff000f0) == 0x07800010) { 1292 + 1293 + if ((insn & 0x0000f000) == 0x0000f000) 1294 + return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1295 + else 1296 + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1297 + } 1298 + 1299 + /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ 1300 + if ((insn & 0x0ff000d0) == 0x075000d0) 1436 1301 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1437 1302 1438 - /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ 1439 - /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ 1440 - /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ 1441 - return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1303 + /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */ 1304 + /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */ 1305 + if ((insn & 0x0fa00070) == 0x07a00050) 1306 + return prep_emulate_rd12rm0(insn, asi); 1307 + 1308 + /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */ 1309 + /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */ 1310 + if ((insn & 0x0fe00070) == 0x07c00010) { 1311 + 1312 + if ((insn & 0x0000000f) == 0x0000000f) 1313 + return prep_emulate_rd12_modify(insn, asi); 1314 + else 1315 + return prep_emulate_rd12rn0_modify(insn, asi); 1316 + } 1317 + 1318 + return INSN_REJECTED; 1442 1319 } 1443 1320 1444 1321 static enum kprobe_insn __kprobes ··· 1472 1309 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ 1473 1310 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ 1474 1311 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ 1312 + 1313 + if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12)) 1314 + return INSN_REJECTED; /* LDRB into PC */ 1315 + 1475 1316 return prep_emulate_ldr_str(insn, asi); 1476 1317 } 1477 1318 ··· 1490 1323 1491 1324 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 1492 1325 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 1493 - asi->insn[0] = truecc_insn(insn); 1494 1326 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ 1495 1327 simulate_stm1_pc : simulate_ldm1stm1; 1496 - return INSN_GOOD; 1328 + return INSN_GOOD_NO_SLOT; 1497 1329 } 1498 1330 1499 1331 static enum kprobe_insn __kprobes ··· 1500 1334 { 1501 1335 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 1502 1336 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 1503 - asi->insn[0] = truecc_insn(insn); 1504 1337 asi->insn_handler = simulate_bbl; 1505 - return INSN_GOOD; 1338 + return INSN_GOOD_NO_SLOT; 1506 1339 } 1507 1340 1508 1341 static enum kprobe_insn __kprobes 1509 - space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1342 + space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1510 1343 { 1344 + /* Coprocessor instructions... */ 1511 1345 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1512 1346 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1513 - insn &= 0xfff00fff; 1514 - insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 1515 - asi->insn[0] = insn; 1516 - asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; 1517 - return INSN_GOOD; 1347 + /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1348 + /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ 1349 + /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1350 + /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 1351 + /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1352 + 1353 + /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ 1354 + 1355 + return INSN_REJECTED; 1518 1356 } 1519 1357 1520 - static enum kprobe_insn __kprobes 1521 - space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1358 + static unsigned long __kprobes __check_eq(unsigned long cpsr) 1522 1359 { 1523 - /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1524 - /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ 1525 - insn &= 0xfff0ffff; /* Rn = r0 */ 1526 - asi->insn[0] = insn; 1527 - asi->insn_handler = emulate_ldcstc; 1528 - return INSN_GOOD; 1360 + return cpsr & PSR_Z_BIT; 1529 1361 } 1530 1362 1531 - static enum kprobe_insn __kprobes 1532 - space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1363 + static unsigned long __kprobes __check_ne(unsigned long cpsr) 1533 1364 { 1534 - /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ 1535 - /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ 1536 - if ((insn & 0xfff000f0) == 0xe1200070 || 1537 - (insn & 0x0f000000) == 0x0f000000) 1538 - return INSN_REJECTED; 1539 - 1540 - /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1541 - if ((insn & 0x0f000010) == 0x0e000000) { 1542 - asi->insn[0] = insn; 1543 - asi->insn_handler = emulate_none; 1544 - return INSN_GOOD; 1545 - } 1546 - 1547 - /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 1548 - /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1549 - insn &= 0xffff0fff; /* Rd = r0 */ 1550 - asi->insn[0] = insn; 1551 - asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; 1552 - return INSN_GOOD; 1365 + return (~cpsr) & PSR_Z_BIT; 1553 1366 } 1367 + 1368 + static unsigned long __kprobes __check_cs(unsigned long cpsr) 1369 + { 1370 + return cpsr & PSR_C_BIT; 1371 + } 1372 + 1373 + static unsigned long __kprobes __check_cc(unsigned long cpsr) 1374 + { 1375 + return (~cpsr) & PSR_C_BIT; 1376 + } 1377 + 1378 + static unsigned long __kprobes __check_mi(unsigned long cpsr) 1379 + { 1380 + return cpsr & PSR_N_BIT; 1381 + } 1382 + 1383 + static unsigned long __kprobes __check_pl(unsigned long cpsr) 1384 + { 1385 + return (~cpsr) & PSR_N_BIT; 1386 + } 1387 + 1388 + static unsigned long __kprobes __check_vs(unsigned long cpsr) 1389 + { 1390 + return cpsr & PSR_V_BIT; 1391 + } 1392 + 1393 + static unsigned long __kprobes __check_vc(unsigned long cpsr) 1394 + { 1395 + return (~cpsr) & PSR_V_BIT; 1396 + } 1397 + 1398 + static unsigned long __kprobes __check_hi(unsigned long cpsr) 1399 + { 1400 + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ 1401 + return cpsr & PSR_C_BIT; 1402 + } 1403 + 1404 + static unsigned long __kprobes __check_ls(unsigned long cpsr) 1405 + { 1406 + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ 1407 + return (~cpsr) & PSR_C_BIT; 1408 + } 1409 + 1410 + static unsigned long __kprobes __check_ge(unsigned long cpsr) 1411 + { 1412 + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ 1413 + return (~cpsr) & PSR_N_BIT; 1414 + } 1415 + 1416 + static unsigned long __kprobes __check_lt(unsigned long cpsr) 1417 + { 1418 + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ 1419 + return cpsr & PSR_N_BIT; 1420 + } 1421 + 1422 + static unsigned long __kprobes __check_gt(unsigned long cpsr) 1423 + { 1424 + unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ 1425 + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ 1426 + return (~temp) & PSR_N_BIT; 1427 + } 1428 + 1429 + static unsigned long __kprobes __check_le(unsigned long cpsr) 1430 + { 1431 + unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ 1432 + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ 1433 + return temp & PSR_N_BIT; 1434 + } 1435 + 1436 + static unsigned long __kprobes __check_al(unsigned long cpsr) 1437 + { 1438 + return true; 1439 + } 1440 + 1441 + static kprobe_check_cc * const condition_checks[16] = { 1442 + &__check_eq, &__check_ne, &__check_cs, &__check_cc, 1443 + &__check_mi, &__check_pl, &__check_vs, &__check_vc, 1444 + &__check_hi, &__check_ls, &__check_ge, &__check_lt, 1445 + &__check_gt, &__check_le, &__check_al, &__check_al 1446 + }; 1554 1447 1555 1448 /* Return: 1556 1449 * INSN_REJECTED If instruction is one not allowed to kprobe, ··· 1626 1401 enum kprobe_insn __kprobes 1627 1402 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1628 1403 { 1404 + asi->insn_check_cc = condition_checks[insn>>28]; 1629 1405 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1630 1406 1631 - if ((insn & 0xf0000000) == 0xf0000000) { 1407 + if ((insn & 0xf0000000) == 0xf0000000) 1632 1408 1633 1409 return space_1111(insn, asi); 1634 1410 1635 - } else if ((insn & 0x0e000000) == 0x00000000) { 1411 + else if ((insn & 0x0e000000) == 0x00000000) 1636 1412 1637 1413 return space_cccc_000x(insn, asi); 1638 1414 1639 - } else if ((insn & 0x0e000000) == 0x02000000) { 1415 + else if ((insn & 0x0e000000) == 0x02000000) 1640 1416 1641 1417 return space_cccc_001x(insn, asi); 1642 1418 1643 - } else if ((insn & 0x0f000010) == 0x06000010) { 1419 + else if ((insn & 0x0f000010) == 0x06000010) 1644 1420 1645 1421 return space_cccc_0110__1(insn, asi); 1646 1422 1647 - } else if ((insn & 0x0f000010) == 0x07000010) { 1423 + else if ((insn & 0x0f000010) == 0x07000010) 1648 1424 1649 1425 return space_cccc_0111__1(insn, asi); 1650 1426 1651 - } else if ((insn & 0x0c000000) == 0x04000000) { 1427 + else if ((insn & 0x0c000000) == 0x04000000) 1652 1428 1653 1429 return space_cccc_01xx(insn, asi); 1654 1430 1655 - } else if ((insn & 0x0e000000) == 0x08000000) { 1431 + else if ((insn & 0x0e000000) == 0x08000000) 1656 1432 1657 1433 return space_cccc_100x(insn, asi); 1658 1434 1659 - } else if ((insn & 0x0e000000) == 0x0a000000) { 1435 + else if ((insn & 0x0e000000) == 0x0a000000) 1660 1436 1661 1437 return space_cccc_101x(insn, asi); 1662 1438 1663 - } else if ((insn & 0x0fe00000) == 0x0c400000) { 1664 - 1665 - return space_cccc_1100_010x(insn, asi); 1666 - 1667 - } else if ((insn & 0x0e000000) == 0x0c000000) { 1668 - 1669 - return space_cccc_110x(insn, asi); 1670 - 1671 - } 1672 - 1673 - return space_cccc_111x(insn, asi); 1439 + return space_cccc_11xx(insn, asi); 1674 1440 } 1675 1441 1676 1442 void __init arm_kprobe_decode_init(void) 1677 1443 { 1678 1444 find_str_pc_offset(); 1679 1445 } 1680 - 1681 - 1682 - /* 1683 - * All ARM instructions listed below. 1684 - * 1685 - * Instructions and their general purpose registers are given. 1686 - * If a particular register may not use R15, it is prefixed with a "!". 1687 - * If marked with a "*" means the value returned by reading R15 1688 - * is implementation defined. 1689 - * 1690 - * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ 1691 - * TST: Rd, Rn, Rm, !Rs 1692 - * BX: Rm 1693 - * BLX(2): !Rm 1694 - * BX: Rm (R15 legal, but discouraged) 1695 - * BXJ: !Rm, 1696 - * CLZ: !Rd, !Rm 1697 - * CPY: Rd, Rm 1698 - * LDC/2,STC/2 immediate offset & unindex: Rn 1699 - * LDC/2,STC/2 immediate pre/post-indexed: !Rn 1700 - * LDM(1/3): !Rn, register_list 1701 - * LDM(2): !Rn, !register_list 1702 - * LDR,STR,PLD immediate offset: Rd, Rn 1703 - * LDR,STR,PLD register offset: Rd, Rn, !Rm 1704 - * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm 1705 - * LDR,STR immediate pre/post-indexed: Rd, !Rn 1706 - * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm 1707 - * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm 1708 - * LDRB,STRB immediate offset: !Rd, Rn 1709 - * LDRB,STRB register offset: !Rd, Rn, !Rm 1710 - * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm 1711 - * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn 1712 - * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm 1713 - * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm 1714 - * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn 1715 - * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm 1716 - * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm 1717 - * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn 1718 - * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm 1719 - * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn 1720 - * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm 1721 - * LDREX: !Rd, !Rn 1722 - * MCR/2: !Rd 1723 - * MCRR/2,MRRC/2: !Rd, !Rn 1724 - * MLA: !Rd, !Rn, !Rm, !Rs 1725 - * MOV: Rd 1726 - * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register) 1727 - * MRS,MSR: !Rd 1728 - * MUL: !Rd, !Rm, !Rs 1729 - * PKH{BT,TB}: !Rd, !Rn, !Rm 1730 - * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn 1731 - * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn 1732 - * REV/16/SH: !Rd, !Rm 1733 - * RFE: !Rn 1734 - * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm 1735 - * SEL: !Rd, !Rn, !Rm 1736 - * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs 1737 - * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs 1738 - * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs 1739 - * SSAT/16: !Rd, !Rm 1740 - * STM(1/2): !Rn, register_list* (R15 in reg list not recommended) 1741 - * STRT immediate pre/post-indexed: Rd*, !Rn 1742 - * STRT register pre/post-indexed: Rd*, !Rn, !Rm 1743 - * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm 1744 - * STREX: !Rd, !Rn, !Rm 1745 - * SWP/B: !Rd, !Rn, !Rm 1746 - * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm 1747 - * {S,U}XT{B,B16,H}: !Rd, !Rm 1748 - * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs 1749 - * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs 1750 - * 1751 - * May transfer control by writing R15 (possible mode changes or alternate 1752 - * mode accesses marked by "*"): 1753 - * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY, 1754 - * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI* 1755 - * 1756 - * Instructions that do not take general registers, nor transfer control: 1757 - * CDP/2, SETEND, SRS* 1758 - */
+2 -1
arch/arm/kernel/kprobes.c
··· 134 134 struct kprobe_ctlblk *kcb) 135 135 { 136 136 regs->ARM_pc += 4; 137 - p->ainsn.insn_handler(p, regs); 137 + if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) 138 + p->ainsn.insn_handler(p, regs); 138 139 } 139 140 140 141 /*
+2 -1
arch/arm/kernel/perf_event.c
··· 746 746 747 747 tail = (struct frame_tail __user *)regs->ARM_fp - 1; 748 748 749 - while (tail && !((unsigned long)tail & 0x3)) 749 + while ((entry->nr < PERF_MAX_STACK_DEPTH) && 750 + tail && !((unsigned long)tail & 0x3)) 750 751 tail = user_backtrace(tail, entry); 751 752 } 752 753
+1 -1
arch/arm/kernel/smp.c
··· 479 479 { 480 480 } 481 481 482 - static void broadcast_timer_setup(struct clock_event_device *evt) 482 + static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) 483 483 { 484 484 evt->name = "dummy_timer"; 485 485 evt->features = CLOCK_EVT_FEAT_ONESHOT |
+1 -1
arch/arm/kernel/sys_oabi-compat.c
··· 311 311 long err; 312 312 int i; 313 313 314 - if (nsops < 1) 314 + if (nsops < 1 || nsops > SEMOPM) 315 315 return -EINVAL; 316 316 sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); 317 317 if (!sops)
+6
arch/arm/mach-davinci/Kconfig
··· 63 63 depends on ARCH_DAVINCI_DM644x 64 64 select MISC_DEVICES 65 65 select EEPROM_AT24 66 + select I2C 66 67 help 67 68 Configure this option to specify the whether the board used 68 69 for development is a DM644x EVM ··· 73 72 depends on ARCH_DAVINCI_DM644x 74 73 select MISC_DEVICES 75 74 select EEPROM_AT24 75 + select I2C 76 76 help 77 77 Say Y here to select the Lyrtech Small Form Factor 78 78 Software Defined Radio (SFFSDR) board. ··· 107 105 select MACH_DAVINCI_DM6467TEVM 108 106 select MISC_DEVICES 109 107 select EEPROM_AT24 108 + select I2C 110 109 help 111 110 Configure this option to specify the whether the board used 112 111 for development is a DM6467 EVM ··· 121 118 depends on ARCH_DAVINCI_DM365 122 119 select MISC_DEVICES 123 120 select EEPROM_AT24 121 + select I2C 124 122 help 125 123 Configure this option to specify whether the board used 126 124 for development is a DM365 EVM ··· 133 129 select GPIO_PCF857X 134 130 select MISC_DEVICES 135 131 select EEPROM_AT24 132 + select I2C 136 133 help 137 134 Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. 138 135 ··· 210 205 depends on ARCH_DAVINCI_DA850 211 206 select MISC_DEVICES 212 207 select EEPROM_AT24 208 + select I2C 213 209 help 214 210 Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 215 211 System on Module. Information on this SoM may be found at
+2 -2
arch/arm/mach-davinci/board-mityomapl138.c
··· 29 29 #include <mach/mux.h> 30 30 #include <mach/spi.h> 31 31 32 - #define MITYOMAPL138_PHY_ID "0:03" 32 + #define MITYOMAPL138_PHY_ID "" 33 33 34 34 #define FACTORY_CONFIG_MAGIC 0x012C0138 35 35 #define FACTORY_CONFIG_VERSION 0x00010001 ··· 414 414 415 415 static struct platform_device mityomapl138_nandflash_device = { 416 416 .name = "davinci_nand", 417 - .id = 0, 417 + .id = 1, 418 418 .dev = { 419 419 .platform_data = &mityomapl138_nandflash_data, 420 420 },
+9 -3
arch/arm/mach-davinci/devices-da8xx.c
··· 39 39 #define DA8XX_GPIO_BASE 0x01e26000 40 40 #define DA8XX_I2C1_BASE 0x01e28000 41 41 #define DA8XX_SPI0_BASE 0x01c41000 42 - #define DA8XX_SPI1_BASE 0x01f0e000 42 + #define DA830_SPI1_BASE 0x01e12000 43 + #define DA850_SPI1_BASE 0x01f0e000 43 44 44 45 #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 45 46 #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 ··· 763 762 764 763 static struct resource da8xx_spi1_resources[] = { 765 764 [0] = { 766 - .start = DA8XX_SPI1_BASE, 767 - .end = DA8XX_SPI1_BASE + SZ_4K - 1, 765 + .start = DA830_SPI1_BASE, 766 + .end = DA830_SPI1_BASE + SZ_4K - 1, 768 767 .flags = IORESOURCE_MEM, 769 768 }, 770 769 [1] = { ··· 832 831 " %d\n", __func__, instance, ret); 833 832 834 833 da8xx_spi_pdata[instance].num_chipselect = len; 834 + 835 + if (instance == 1 && cpu_is_davinci_da850()) { 836 + da8xx_spi1_resources[0].start = DA850_SPI1_BASE; 837 + da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1; 838 + } 835 839 836 840 return platform_device_register(&da8xx_spi_device[instance]); 837 841 }
+8 -5
arch/arm/mach-davinci/include/mach/debug-macro.S
··· 24 24 25 25 #define UART_SHIFT 2 26 26 27 + #define davinci_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) 28 + #define davinci_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) 29 + 27 30 .pushsection .data 28 31 davinci_uart_phys: .word 0 29 32 davinci_uart_virt: .word 0 ··· 37 34 /* Use davinci_uart_phys/virt if already configured */ 38 35 10: mrc p15, 0, \rp, c1, c0 39 36 tst \rp, #1 @ MMU enabled? 40 - ldreq \rp, =__virt_to_phys(davinci_uart_phys) 37 + ldreq \rp, =davinci_uart_v2p(davinci_uart_phys) 41 38 ldrne \rp, =davinci_uart_phys 42 39 add \rv, \rp, #4 @ davinci_uart_virt 43 40 ldr \rp, [\rp, #0] ··· 51 48 tst \rp, #1 @ MMU enabled? 52 49 53 50 /* Copy uart phys address from decompressor uart info */ 54 - ldreq \rv, =__virt_to_phys(davinci_uart_phys) 51 + ldreq \rv, =davinci_uart_v2p(davinci_uart_phys) 55 52 ldrne \rv, =davinci_uart_phys 56 53 ldreq \rp, =DAVINCI_UART_INFO 57 - ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) 54 + ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) 58 55 ldr \rp, [\rp, #0] 59 56 str \rp, [\rv] 60 57 61 58 /* Copy uart virt address from decompressor uart info */ 62 - ldreq \rv, =__virt_to_phys(davinci_uart_virt) 59 + ldreq \rv, =davinci_uart_v2p(davinci_uart_virt) 63 60 ldrne \rv, =davinci_uart_virt 64 61 ldreq \rp, =DAVINCI_UART_INFO 65 - ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) 62 + ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) 66 63 ldr \rp, [\rp, #4] 67 64 str \rp, [\rv] 68 65
+1 -1
arch/arm/mach-davinci/include/mach/serial.h
··· 22 22 * 23 23 * This area sits just below the page tables (see arch/arm/kernel/head.S). 24 24 */ 25 - #define DAVINCI_UART_INFO (PHYS_OFFSET + 0x3ff8) 25 + #define DAVINCI_UART_INFO (PLAT_PHYS_OFFSET + 0x3ff8) 26 26 27 27 #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) 28 28 #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
+8 -3
arch/arm/mach-mx3/mach-vpr200.c
··· 257 257 .workaround = FLS_USB2_WORKAROUND_ENGCM09152, 258 258 }; 259 259 260 + static int vpr200_usbh_init(struct platform_device *pdev) 261 + { 262 + return mx35_initialize_usb_hw(pdev->id, 263 + MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY); 264 + } 265 + 260 266 /* USB HOST config */ 261 267 static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { 262 - .portsc = MXC_EHCI_MODE_SERIAL, 263 - .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | 264 - MXC_EHCI_INTERNAL_PHY, 268 + .init = vpr200_usbh_init, 269 + .portsc = MXC_EHCI_MODE_SERIAL, 265 270 }; 266 271 267 272 static struct platform_device *devices[] __initdata = {
+1 -1
arch/arm/mach-mx5/board-mx53_loco.c
··· 193 193 .wakeup = wake, \ 194 194 } 195 195 196 - static const struct gpio_keys_button loco_buttons[] __initconst = { 196 + static struct gpio_keys_button loco_buttons[] = { 197 197 GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), 198 198 GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), 199 199 GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+6 -1
arch/arm/mach-mxs/clock-mx28.c
··· 295 295 unsigned long diff, parent_rate, calc_rate; \ 296 296 int i; \ 297 297 \ 298 - parent_rate = clk_get_rate(clk->parent); \ 299 298 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ 300 299 bm_busy = BM_CLKCTRL_##dr##_BUSY; \ 301 300 \ 302 301 if (clk->parent == &ref_xtal_clk) { \ 302 + parent_rate = clk_get_rate(clk->parent); \ 303 303 div = DIV_ROUND_UP(parent_rate, rate); \ 304 304 if (clk == &cpu_clk) { \ 305 305 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \ ··· 309 309 if (div == 0 || div > div_max) \ 310 310 return -EINVAL; \ 311 311 } else { \ 312 + /* \ 313 + * hack alert: this block modifies clk->parent, too, \ 314 + * so the base to use it the grand parent. \ 315 + */ \ 316 + parent_rate = clk_get_rate(clk->parent->parent); \ 312 317 rate >>= PARENT_RATE_SHIFT; \ 313 318 parent_rate >>= PARENT_RATE_SHIFT; \ 314 319 diff = parent_rate; \
+1 -1
arch/arm/mach-pxa/hx4700.c
··· 711 711 static struct regulator_init_data bq24022_init_data = { 712 712 .constraints = { 713 713 .max_uA = 500000, 714 - .valid_ops_mask = REGULATOR_CHANGE_CURRENT, 714 + .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS, 715 715 }, 716 716 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), 717 717 .consumer_supplies = bq24022_consumers,
+1 -1
arch/arm/mach-pxa/magician.c
··· 599 599 static struct regulator_init_data bq24022_init_data = { 600 600 .constraints = { 601 601 .max_uA = 500000, 602 - .valid_ops_mask = REGULATOR_CHANGE_CURRENT, 602 + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS, 603 603 }, 604 604 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), 605 605 .consumer_supplies = bq24022_consumers,
+1 -1
arch/arm/mm/proc-xscale.S
··· 395 395 teq r2, #DMA_TO_DEVICE 396 396 beq xscale_dma_clean_range 397 397 b xscale_dma_flush_range 398 - ENDPROC(xscsale_dma_a0_map_area) 398 + ENDPROC(xscale_dma_a0_map_area) 399 399 400 400 /* 401 401 * dma_unmap_area(start, size, dir)
+7
arch/arm/plat-mxc/gpio.c
··· 295 295 return 0; 296 296 } 297 297 298 + /* 299 + * This lock class tells lockdep that GPIO irqs are in a different 300 + * category than their parents, so it won't report false recursion. 301 + */ 302 + static struct lock_class_key gpio_lock_class; 303 + 298 304 int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) 299 305 { 300 306 int i, j; ··· 317 311 __raw_writel(~0, port[i].base + GPIO_ISR); 318 312 for (j = port[i].virtual_irq_start; 319 313 j < port[i].virtual_irq_start + 32; j++) { 314 + irq_set_lockdep_class(j, &gpio_lock_class); 320 315 irq_set_chip_and_handler(j, &gpio_irq_chip, 321 316 handle_level_irq); 322 317 set_irq_flags(j, IRQF_VALID);
+2
arch/arm/plat-mxc/ssi-fiq.S
··· 124 124 1: 125 125 @ return from FIQ 126 126 subs pc, lr, #4 127 + 128 + .align 127 129 imx_ssi_fiq_base: 128 130 .word 0x0 129 131 imx_ssi_fiq_rx_buffer:
+9 -10
drivers/clk/clkdev.c
··· 32 32 * Then we take the most specific entry - with the following 33 33 * order of precedence: dev+con > dev only > con only. 34 34 */ 35 - static struct clk *clk_find(const char *dev_id, const char *con_id) 35 + static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) 36 36 { 37 - struct clk_lookup *p; 38 - struct clk *clk = NULL; 37 + struct clk_lookup *p, *cl = NULL; 39 38 int match, best = 0; 40 39 41 40 list_for_each_entry(p, &clocks, node) { ··· 51 52 } 52 53 53 54 if (match > best) { 54 - clk = p->clk; 55 + cl = p; 55 56 if (match != 3) 56 57 best = match; 57 58 else 58 59 break; 59 60 } 60 61 } 61 - return clk; 62 + return cl; 62 63 } 63 64 64 65 struct clk *clk_get_sys(const char *dev_id, const char *con_id) 65 66 { 66 - struct clk *clk; 67 + struct clk_lookup *cl; 67 68 68 69 mutex_lock(&clocks_mutex); 69 - clk = clk_find(dev_id, con_id); 70 - if (clk && !__clk_get(clk)) 71 - clk = NULL; 70 + cl = clk_find(dev_id, con_id); 71 + if (cl && !__clk_get(cl->clk)) 72 + cl = NULL; 72 73 mutex_unlock(&clocks_mutex); 73 74 74 - return clk ? clk : ERR_PTR(-ENOENT); 75 + return cl ? cl->clk : ERR_PTR(-ENOENT); 75 76 } 76 77 EXPORT_SYMBOL(clk_get_sys); 77 78