aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-05-10 11:05:24 -0400
committerIngo Molnar <mingo@elte.hu>2011-05-10 11:05:45 -0400
commit932fed4e2e42c3d730c01bb63b1c4f812c533d5b (patch)
tree11b1afac3a40d253cdb905c42901edfaae5e196e /arch
parent57d524154ffe99d27fb55e0e30ddbad9f4c35806 (diff)
parent693d92a1bbc9e42681c42ed190bd42b636ca876f (diff)
Merge commit 'v2.6.39-rc7' into perf/core
Merge reason: pull in the latest fixes. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/configs/at91x40_defconfig48
-rw-r--r--arch/arm/include/asm/kprobes.h3
-rw-r--r--arch/arm/kernel/kprobes-decode.c777
-rw-r--r--arch/arm/kernel/kprobes.c3
-rw-r--r--arch/arm/kernel/perf_event.c3
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm/kernel/smp.c2
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c2
-rw-r--r--arch/arm/mach-at91/Kconfig1
-rw-r--r--arch/arm/mach-at91/board-eb01.c7
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h28
-rw-r--r--arch/arm/mach-davinci/Kconfig6
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c4
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c12
-rw-r--r--arch/arm/mach-davinci/dm355.c2
-rw-r--r--arch/arm/mach-davinci/dm644x.c2
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S13
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h2
-rw-r--r--arch/arm/mach-mx3/mach-vpr200.c11
-rw-r--r--arch/arm/mach-mx5/board-mx53_loco.c2
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c7
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/board-rx51.c9
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c9
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c17
-rw-r--r--arch/arm/mach-omap2/control.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c6
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.c4
-rw-r--r--arch/arm/mach-omap2/pm.c1
-rw-r--r--arch/arm/mach-omap2/voltage.c1
-rw-r--r--arch/arm/mach-pxa/hx4700.c2
-rw-r--r--arch/arm/mach-pxa/magician.c2
-rw-r--r--arch/arm/mm/proc-xscale.S2
-rw-r--r--arch/arm/plat-mxc/gpio.c7
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S2
-rw-r--r--arch/m68k/mm/motorola.c2
-rw-r--r--arch/parisc/mm/init.c4
-rw-r--r--arch/powerpc/include/asm/8xx_immap.h4
-rw-r--r--arch/powerpc/include/asm/uninorth.h2
-rw-r--r--arch/powerpc/kernel/ptrace.c12
-rw-r--r--arch/s390/crypto/prng.c2
-rw-r--r--arch/s390/kvm/sie64a.S4
-rw-r--r--arch/s390/mm/fault.c6
-rw-r--r--arch/s390/mm/pageattr.c5
-rw-r--r--arch/sh/kernel/ptrace_32.c4
-rw-r--r--arch/um/Kconfig.um2
-rw-r--r--arch/um/include/asm/thread_info.h5
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/atomic64_cx8_32.S225
-rw-r--r--arch/x86/boot/memory.c2
-rw-r--r--arch/x86/include/asm/io_apic.h2
-rw-r--r--arch/x86/kernel/apic/io_apic.c10
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c87
-rw-r--r--arch/x86/kernel/devicetree.c2
-rw-r--r--arch/x86/kernel/ptrace.c36
-rw-r--r--arch/x86/kernel/reboot_32.S12
-rw-r--r--arch/x86/mm/numa_64.c2
-rw-r--r--arch/x86/platform/ce4100/falconfalls.dts6
-rw-r--r--arch/x86/xen/mmu.c125
63 files changed, 1152 insertions, 445 deletions
diff --git a/arch/arm/configs/at91x40_defconfig b/arch/arm/configs/at91x40_defconfig
new file mode 100644
index 000000000000..c55e9212fcbb
--- /dev/null
+++ b/arch/arm/configs/at91x40_defconfig
@@ -0,0 +1,48 @@
1CONFIG_EXPERIMENTAL=y
2CONFIG_LOG_BUF_SHIFT=14
3CONFIG_EMBEDDED=y
4# CONFIG_HOTPLUG is not set
5# CONFIG_ELF_CORE is not set
6# CONFIG_FUTEX is not set
7# CONFIG_TIMERFD is not set
8# CONFIG_VM_EVENT_COUNTERS is not set
9# CONFIG_COMPAT_BRK is not set
10CONFIG_SLAB=y
11# CONFIG_LBDAF is not set
12# CONFIG_BLK_DEV_BSG is not set
13# CONFIG_IOSCHED_DEADLINE is not set
14# CONFIG_IOSCHED_CFQ is not set
15# CONFIG_MMU is not set
16CONFIG_ARCH_AT91=y
17CONFIG_ARCH_AT91X40=y
18CONFIG_MACH_AT91EB01=y
19CONFIG_AT91_EARLY_USART0=y
20CONFIG_CPU_ARM7TDMI=y
21CONFIG_SET_MEM_PARAM=y
22CONFIG_DRAM_BASE=0x01000000
23CONFIG_DRAM_SIZE=0x00400000
24CONFIG_FLASH_MEM_BASE=0x01400000
25CONFIG_PROCESSOR_ID=0x14000040
26CONFIG_ZBOOT_ROM_TEXT=0x0
27CONFIG_ZBOOT_ROM_BSS=0x0
28CONFIG_BINFMT_FLAT=y
29# CONFIG_SUSPEND is not set
30# CONFIG_FW_LOADER is not set
31CONFIG_MTD=y
32CONFIG_MTD_PARTITIONS=y
33CONFIG_MTD_CHAR=y
34CONFIG_MTD_BLOCK=y
35CONFIG_MTD_RAM=y
36CONFIG_MTD_ROM=y
37CONFIG_BLK_DEV_RAM=y
38# CONFIG_INPUT is not set
39# CONFIG_SERIO is not set
40# CONFIG_VT is not set
41# CONFIG_DEVKMEM is not set
42# CONFIG_HW_RANDOM is not set
43# CONFIG_HWMON is not set
44# CONFIG_USB_SUPPORT is not set
45CONFIG_EXT2_FS=y
46# CONFIG_DNOTIFY is not set
47CONFIG_ROMFS_FS=y
48# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index bb8a19bd5822..e46bdd0097eb 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -39,10 +39,13 @@ typedef u32 kprobe_opcode_t;
39struct kprobe; 39struct kprobe;
40typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); 40typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
41 41
42typedef unsigned long (kprobe_check_cc)(unsigned long);
43
42/* Architecture specific copy of original instruction. */ 44/* Architecture specific copy of original instruction. */
43struct arch_specific_insn { 45struct arch_specific_insn {
44 kprobe_opcode_t *insn; 46 kprobe_opcode_t *insn;
45 kprobe_insn_handler_t *insn_handler; 47 kprobe_insn_handler_t *insn_handler;
48 kprobe_check_cc *insn_check_cc;
46}; 49};
47 50
48struct prev_kprobe { 51struct prev_kprobe {
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 23891317dc4b..15eeff6aea0e 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -34,9 +34,6 @@
34 * 34 *
35 * *) If the PC is written to by the instruction, the 35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software. 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 * *) Otherwise, a modified form of the instruction is 38 * *) Otherwise, a modified form of the instruction is
42 * directly executed. Its handler calls the 39 * directly executed. Its handler calls the
@@ -68,13 +65,17 @@
68 65
69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) 66#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
70 67
68#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
69
70/*
71 * Test if load/store instructions writeback the address register.
72 * if P (bit 24) == 0 or W (bit 21) == 1
73 */
74#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
75
71#define PSR_fs (PSR_f|PSR_s) 76#define PSR_fs (PSR_f|PSR_s)
72 77
73#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ 78#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */
74#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */
75
76#define truecc_insn(insn) (((insn) & 0xf0000000) | \
77 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
78 79
79typedef long (insn_0arg_fn_t)(void); 80typedef long (insn_0arg_fn_t)(void);
80typedef long (insn_1arg_fn_t)(long); 81typedef long (insn_1arg_fn_t)(long);
@@ -419,14 +420,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
419 420
420static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) 421static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
421{ 422{
422 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
423 kprobe_opcode_t insn = p->opcode; 423 kprobe_opcode_t insn = p->opcode;
424 long iaddr = (long)p->addr; 424 long iaddr = (long)p->addr;
425 int disp = branch_displacement(insn); 425 int disp = branch_displacement(insn);
426 426
427 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
428 return;
429
430 if (insn & (1 << 24)) 427 if (insn & (1 << 24))
431 regs->ARM_lr = iaddr + 4; 428 regs->ARM_lr = iaddr + 4;
432 429
@@ -446,14 +443,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
446 443
447static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) 444static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
448{ 445{
449 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
450 kprobe_opcode_t insn = p->opcode; 446 kprobe_opcode_t insn = p->opcode;
451 int rm = insn & 0xf; 447 int rm = insn & 0xf;
452 long rmv = regs->uregs[rm]; 448 long rmv = regs->uregs[rm];
453 449
454 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
455 return;
456
457 if (insn & (1 << 5)) 450 if (insn & (1 << 5))
458 regs->ARM_lr = (long)p->addr + 4; 451 regs->ARM_lr = (long)p->addr + 4;
459 452
@@ -463,9 +456,16 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
463 regs->ARM_cpsr |= PSR_T_BIT; 456 regs->ARM_cpsr |= PSR_T_BIT;
464} 457}
465 458
459static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
460{
461 kprobe_opcode_t insn = p->opcode;
462 int rd = (insn >> 12) & 0xf;
463 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
464 regs->uregs[rd] = regs->ARM_cpsr & mask;
465}
466
466static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) 467static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
467{ 468{
468 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
469 kprobe_opcode_t insn = p->opcode; 469 kprobe_opcode_t insn = p->opcode;
470 int rn = (insn >> 16) & 0xf; 470 int rn = (insn >> 16) & 0xf;
471 int lbit = insn & (1 << 20); 471 int lbit = insn & (1 << 20);
@@ -476,9 +476,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
476 int reg_bit_vector; 476 int reg_bit_vector;
477 int reg_count; 477 int reg_count;
478 478
479 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
480 return;
481
482 reg_count = 0; 479 reg_count = 0;
483 reg_bit_vector = insn & 0xffff; 480 reg_bit_vector = insn & 0xffff;
484 while (reg_bit_vector) { 481 while (reg_bit_vector) {
@@ -510,11 +507,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
510 507
511static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) 508static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
512{ 509{
513 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
514
515 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
516 return;
517
518 regs->ARM_pc = (long)p->addr + str_pc_offset; 510 regs->ARM_pc = (long)p->addr + str_pc_offset;
519 simulate_ldm1stm1(p, regs); 511 simulate_ldm1stm1(p, regs);
520 regs->ARM_pc = (long)p->addr + 4; 512 regs->ARM_pc = (long)p->addr + 4;
@@ -525,24 +517,16 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
525 regs->uregs[12] = regs->uregs[13]; 517 regs->uregs[12] = regs->uregs[13];
526} 518}
527 519
528static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
529{
530 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
531 kprobe_opcode_t insn = p->opcode;
532 int rn = (insn >> 16) & 0xf;
533 long rnv = regs->uregs[rn];
534
535 /* Save Rn in case of writeback. */
536 regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
537}
538
539static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) 520static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
540{ 521{
541 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; 522 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
542 kprobe_opcode_t insn = p->opcode; 523 kprobe_opcode_t insn = p->opcode;
524 long ppc = (long)p->addr + 8;
543 int rd = (insn >> 12) & 0xf; 525 int rd = (insn >> 12) & 0xf;
544 int rn = (insn >> 16) & 0xf; 526 int rn = (insn >> 16) & 0xf;
545 int rm = insn & 0xf; /* rm may be invalid, don't care. */ 527 int rm = insn & 0xf; /* rm may be invalid, don't care. */
528 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
529 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
546 530
547 /* Not following the C calling convention here, so need asm(). */ 531 /* Not following the C calling convention here, so need asm(). */
548 __asm__ __volatile__ ( 532 __asm__ __volatile__ (
@@ -554,29 +538,36 @@ static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
554 "str r0, %[rn] \n\t" /* in case of writeback */ 538 "str r0, %[rn] \n\t" /* in case of writeback */
555 "str r2, %[rd0] \n\t" 539 "str r2, %[rd0] \n\t"
556 "str r3, %[rd1] \n\t" 540 "str r3, %[rd1] \n\t"
557 : [rn] "+m" (regs->uregs[rn]), 541 : [rn] "+m" (rnv),
558 [rd0] "=m" (regs->uregs[rd]), 542 [rd0] "=m" (regs->uregs[rd]),
559 [rd1] "=m" (regs->uregs[rd+1]) 543 [rd1] "=m" (regs->uregs[rd+1])
560 : [rm] "m" (regs->uregs[rm]), 544 : [rm] "m" (rmv),
561 [cpsr] "r" (regs->ARM_cpsr), 545 [cpsr] "r" (regs->ARM_cpsr),
562 [i_fn] "r" (i_fn) 546 [i_fn] "r" (i_fn)
563 : "r0", "r1", "r2", "r3", "lr", "cc" 547 : "r0", "r1", "r2", "r3", "lr", "cc"
564 ); 548 );
549 if (is_writeback(insn))
550 regs->uregs[rn] = rnv;
565} 551}
566 552
567static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) 553static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
568{ 554{
569 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; 555 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
570 kprobe_opcode_t insn = p->opcode; 556 kprobe_opcode_t insn = p->opcode;
557 long ppc = (long)p->addr + 8;
571 int rd = (insn >> 12) & 0xf; 558 int rd = (insn >> 12) & 0xf;
572 int rn = (insn >> 16) & 0xf; 559 int rn = (insn >> 16) & 0xf;
573 int rm = insn & 0xf; 560 int rm = insn & 0xf;
574 long rnv = regs->uregs[rn]; 561 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
575 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ 562 /* rm/rmv may be invalid, don't care. */
563 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
564 long rnv_wb;
576 565
577 regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], 566 rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
578 regs->uregs[rd+1], 567 regs->uregs[rd+1],
579 regs->ARM_cpsr, i_fn); 568 regs->ARM_cpsr, i_fn);
569 if (is_writeback(insn))
570 regs->uregs[rn] = rnv_wb;
580} 571}
581 572
582static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) 573static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
@@ -630,31 +621,6 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
630 regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */ 621 regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */
631} 622}
632 623
633static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
634{
635 insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
636 kprobe_opcode_t insn = p->opcode;
637 union reg_pair fnr;
638 int rd = (insn >> 12) & 0xf;
639 int rn = (insn >> 16) & 0xf;
640
641 fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
642 regs->uregs[rn] = fnr.r0;
643 regs->uregs[rd] = fnr.r1;
644}
645
646static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
647{
648 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
649 kprobe_opcode_t insn = p->opcode;
650 int rd = (insn >> 12) & 0xf;
651 int rn = (insn >> 16) & 0xf;
652 long rnv = regs->uregs[rn];
653 long rdv = regs->uregs[rd];
654
655 insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
656}
657
658static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) 624static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
659{ 625{
660 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 626 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
@@ -688,32 +654,32 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
688 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); 654 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
689} 655}
690 656
691static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) 657static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
692{ 658{
693 insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
694 kprobe_opcode_t insn = p->opcode;
695 int rd = (insn >> 12) & 0xf;
696
697 regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
698} 659}
699 660
700static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) 661static void __kprobes
662emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
701{ 663{
702 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 664 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
703 kprobe_opcode_t insn = p->opcode; 665 kprobe_opcode_t insn = p->opcode;
704 int ird = (insn >> 12) & 0xf; 666 int rd = (insn >> 12) & 0xf;
667 long rdv = regs->uregs[rd];
705 668
706 insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); 669 regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
707} 670}
708 671
709static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) 672static void __kprobes
673emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
710{ 674{
711 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 675 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
712 kprobe_opcode_t insn = p->opcode; 676 kprobe_opcode_t insn = p->opcode;
713 int rn = (insn >> 16) & 0xf; 677 int rd = (insn >> 12) & 0xf;
678 int rn = insn & 0xf;
679 long rdv = regs->uregs[rd];
714 long rnv = regs->uregs[rn]; 680 long rnv = regs->uregs[rn];
715 681
716 insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); 682 regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
717} 683}
718 684
719static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) 685static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
@@ -819,6 +785,17 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
819} 785}
820 786
821static void __kprobes 787static void __kprobes
788emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
789{
790 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
791 kprobe_opcode_t insn = p->opcode;
792 int rn = (insn >> 16) & 0xf;
793 long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
794
795 insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
796}
797
798static void __kprobes
822emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) 799emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
823{ 800{
824 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; 801 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
@@ -854,14 +831,34 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
854 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn); 831 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
855} 832}
856 833
834static void __kprobes
835emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
836{
837 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
838 kprobe_opcode_t insn = p->opcode;
839 long ppc = (long)p->addr + 8;
840 int rn = (insn >> 16) & 0xf;
841 int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */
842 int rm = insn & 0xf;
843 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
844 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
845 long rsv = regs->uregs[rs];
846
847 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
848}
849
857static enum kprobe_insn __kprobes 850static enum kprobe_insn __kprobes
858prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) 851prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
859{ 852{
860 int ibit = (insn & (1 << 26)) ? 25 : 22; 853 int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
854 : (~insn & (1 << 22));
855
856 if (is_writeback(insn) && is_r15(insn, 16))
857 return INSN_REJECTED; /* Writeback to PC */
861 858
862 insn &= 0xfff00fff; 859 insn &= 0xfff00fff;
863 insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 860 insn |= 0x00001000; /* Rn = r0, Rd = r1 */
864 if (insn & (1 << ibit)) { 861 if (not_imm) {
865 insn &= ~0xf; 862 insn &= ~0xf;
866 insn |= 2; /* Rm = r2 */ 863 insn |= 2; /* Rm = r2 */
867 } 864 }
@@ -871,20 +868,40 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
871} 868}
872 869
873static enum kprobe_insn __kprobes 870static enum kprobe_insn __kprobes
874prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) 871prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
875{ 872{
876 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 873 if (is_r15(insn, 12))
874 return INSN_REJECTED; /* Rd is PC */
875
876 insn &= 0xffff0fff; /* Rd = r0 */
877 asi->insn[0] = insn; 877 asi->insn[0] = insn;
878 asi->insn_handler = emulate_rd12rm0; 878 asi->insn_handler = emulate_rd12_modify;
879 return INSN_GOOD; 879 return INSN_GOOD;
880} 880}
881 881
882static enum kprobe_insn __kprobes 882static enum kprobe_insn __kprobes
883prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) 883prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
884 struct arch_specific_insn *asi)
884{ 885{
885 insn &= 0xffff0fff; /* Rd = r0 */ 886 if (is_r15(insn, 12))
887 return INSN_REJECTED; /* Rd is PC */
888
889 insn &= 0xffff0ff0; /* Rd = r0 */
890 insn |= 0x00000001; /* Rn = r1 */
891 asi->insn[0] = insn;
892 asi->insn_handler = emulate_rd12rn0_modify;
893 return INSN_GOOD;
894}
895
896static enum kprobe_insn __kprobes
897prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
898{
899 if (is_r15(insn, 12))
900 return INSN_REJECTED; /* Rd is PC */
901
902 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
886 asi->insn[0] = insn; 903 asi->insn[0] = insn;
887 asi->insn_handler = emulate_rd12; 904 asi->insn_handler = emulate_rd12rm0;
888 return INSN_GOOD; 905 return INSN_GOOD;
889} 906}
890 907
@@ -892,6 +909,9 @@ static enum kprobe_insn __kprobes
892prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, 909prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
893 struct arch_specific_insn *asi) 910 struct arch_specific_insn *asi)
894{ 911{
912 if (is_r15(insn, 12))
913 return INSN_REJECTED; /* Rd is PC */
914
895 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 915 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
896 insn |= 0x00000001; /* Rm = r1 */ 916 insn |= 0x00000001; /* Rm = r1 */
897 asi->insn[0] = insn; 917 asi->insn[0] = insn;
@@ -903,6 +923,9 @@ static enum kprobe_insn __kprobes
903prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, 923prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
904 struct arch_specific_insn *asi) 924 struct arch_specific_insn *asi)
905{ 925{
926 if (is_r15(insn, 16))
927 return INSN_REJECTED; /* Rd is PC */
928
906 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ 929 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */
907 insn |= 0x00000001; /* Rm = r1 */ 930 insn |= 0x00000001; /* Rm = r1 */
908 asi->insn[0] = insn; 931 asi->insn[0] = insn;
@@ -914,6 +937,9 @@ static enum kprobe_insn __kprobes
914prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, 937prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
915 struct arch_specific_insn *asi) 938 struct arch_specific_insn *asi)
916{ 939{
940 if (is_r15(insn, 16))
941 return INSN_REJECTED; /* Rd is PC */
942
917 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ 943 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */
918 insn |= 0x00000102; /* Rs = r1, Rm = r2 */ 944 insn |= 0x00000102; /* Rs = r1, Rm = r2 */
919 asi->insn[0] = insn; 945 asi->insn[0] = insn;
@@ -925,6 +951,9 @@ static enum kprobe_insn __kprobes
925prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, 951prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
926 struct arch_specific_insn *asi) 952 struct arch_specific_insn *asi)
927{ 953{
954 if (is_r15(insn, 16) || is_r15(insn, 12))
955 return INSN_REJECTED; /* RdHi or RdLo is PC */
956
928 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ 957 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */
929 insn |= 0x00001203; /* Rs = r2, Rm = r3 */ 958 insn |= 0x00001203; /* Rs = r2, Rm = r3 */
930 asi->insn[0] = insn; 959 asi->insn[0] = insn;
@@ -945,20 +974,13 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
945static enum kprobe_insn __kprobes 974static enum kprobe_insn __kprobes
946space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) 975space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
947{ 976{
948 /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ 977 /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
949 /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ 978 /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
950 /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ 979 /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
951 if ((insn & 0xfff30020) == 0xf1020000 || 980 /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
952 (insn & 0xfe500f00) == 0xf8100a00 || 981 if ((insn & 0xfe300000) == 0xf4100000) {
953 (insn & 0xfe5f0f00) == 0xf84d0500) 982 asi->insn_handler = emulate_nop;
954 return INSN_REJECTED; 983 return INSN_GOOD_NO_SLOT;
955
956 /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
957 if ((insn & 0xfd700000) == 0xf4500000) {
958 insn &= 0xfff0ffff; /* Rn = r0 */
959 asi->insn[0] = insn;
960 asi->insn_handler = emulate_rn16;
961 return INSN_GOOD;
962 } 984 }
963 985
964 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ 986 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
@@ -967,41 +989,22 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
967 return INSN_GOOD_NO_SLOT; 989 return INSN_GOOD_NO_SLOT;
968 } 990 }
969 991
970 /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 992 /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
971 /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 993 /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
972 if ((insn & 0xffff00f0) == 0xf1010000 ||
973 (insn & 0xff000010) == 0xfe000000) {
974 asi->insn[0] = insn;
975 asi->insn_handler = emulate_none;
976 return INSN_GOOD;
977 }
978 994
995 /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
996 /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
997
998 /* Coprocessor instructions... */
979 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 999 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
980 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 1000 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
981 if ((insn & 0xffe00000) == 0xfc400000) { 1001 /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
982 insn &= 0xfff00fff; /* Rn = r0 */ 1002 /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
983 insn |= 0x00001000; /* Rd = r1 */ 1003 /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
984 asi->insn[0] = insn; 1004 /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
985 asi->insn_handler = 1005 /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
986 (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
987 return INSN_GOOD;
988 }
989 1006
990 /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1007 return INSN_REJECTED;
991 /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
992 if ((insn & 0xfe000000) == 0xfc000000) {
993 insn &= 0xfff0ffff; /* Rn = r0 */
994 asi->insn[0] = insn;
995 asi->insn_handler = emulate_ldcstc;
996 return INSN_GOOD;
997 }
998
999 /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1000 /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1001 insn &= 0xffff0fff; /* Rd = r0 */
1002 asi->insn[0] = insn;
1003 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1004 return INSN_GOOD;
1005} 1008}
1006 1009
1007static enum kprobe_insn __kprobes 1010static enum kprobe_insn __kprobes
@@ -1010,19 +1013,18 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1010 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1013 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
1011 if ((insn & 0x0f900010) == 0x01000000) { 1014 if ((insn & 0x0f900010) == 0x01000000) {
1012 1015
1013 /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ 1016 /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
1014 /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ 1017 if ((insn & 0x0ff000f0) == 0x01000000) {
1015 if ((insn & 0x0ff000f0) == 0x01200020 || 1018 if (is_r15(insn, 12))
1016 (insn & 0x0fb000f0) == 0x01200000) 1019 return INSN_REJECTED; /* Rd is PC */
1017 return INSN_REJECTED; 1020 asi->insn_handler = simulate_mrs;
1018 1021 return INSN_GOOD_NO_SLOT;
1019 /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ 1022 }
1020 if ((insn & 0x0fb00010) == 0x01000000)
1021 return prep_emulate_rd12(insn, asi);
1022 1023
1023 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ 1024 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
1024 if ((insn & 0x0ff00090) == 0x01400080) 1025 if ((insn & 0x0ff00090) == 0x01400080)
1025 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1026 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1027 asi);
1026 1028
1027 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ 1029 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1028 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ 1030 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
@@ -1031,24 +1033,29 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1031 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1033 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1032 1034
1033 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ 1035 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
1034 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ 1036 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
1035 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1037 if ((insn & 0x0ff00090) == 0x01000080 ||
1038 (insn & 0x0ff000b0) == 0x01200080)
1039 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1040
1041 /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
1042 /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
1043 /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
1036 1044
1045 /* Other instruction encodings aren't yet defined */
1046 return INSN_REJECTED;
1037 } 1047 }
1038 1048
1039 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ 1049 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
1040 else if ((insn & 0x0f900090) == 0x01000010) { 1050 else if ((insn & 0x0f900090) == 0x01000010) {
1041 1051
1042 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1043 if ((insn & 0xfff000f0) == 0xe1200070)
1044 return INSN_REJECTED;
1045
1046 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ 1052 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1047 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ 1053 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1048 if ((insn & 0x0ff000d0) == 0x01200010) { 1054 if ((insn & 0x0ff000d0) == 0x01200010) {
1049 asi->insn[0] = truecc_insn(insn); 1055 if ((insn & 0x0ff000ff) == 0x0120003f)
1056 return INSN_REJECTED; /* BLX pc */
1050 asi->insn_handler = simulate_blx2bx; 1057 asi->insn_handler = simulate_blx2bx;
1051 return INSN_GOOD; 1058 return INSN_GOOD_NO_SLOT;
1052 } 1059 }
1053 1060
1054 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ 1061 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
@@ -1059,17 +1066,27 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1059 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ 1066 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
1060 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ 1067 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
1061 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ 1068 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
1062 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1069 if ((insn & 0x0f9000f0) == 0x01000050)
1070 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1071
1072 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1073 /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
1074
1075 /* Other instruction encodings aren't yet defined */
1076 return INSN_REJECTED;
1063 } 1077 }
1064 1078
1065 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ 1079 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
1066 else if ((insn & 0x0f000090) == 0x00000090) { 1080 else if ((insn & 0x0f0000f0) == 0x00000090) {
1067 1081
1068 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ 1082 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */
1069 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ 1083 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
1070 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ 1084 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */
1071 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ 1085 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
1072 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ 1086 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */
1087 /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */
1088 /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */
1089 /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */
1073 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ 1090 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */
1074 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ 1091 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
1075 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ 1092 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */
@@ -1078,13 +1095,15 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1078 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ 1095 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1079 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ 1096 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */
1080 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ 1097 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1081 if ((insn & 0x0fe000f0) == 0x00000090) { 1098 if ((insn & 0x00d00000) == 0x00500000)
1082 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1099 return INSN_REJECTED;
1083 } else if ((insn & 0x0fe000f0) == 0x00200090) { 1100 else if ((insn & 0x00e00000) == 0x00000000)
1084 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1101 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1085 } else { 1102 else if ((insn & 0x00a00000) == 0x00200000)
1086 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1103 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1087 } 1104 else
1105 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1106 asi);
1088 } 1107 }
1089 1108
1090 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ 1109 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
@@ -1092,23 +1111,45 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1092 1111
1093 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ 1112 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1094 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ 1113 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1095 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ 1114 /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
1096 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ 1115 /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
1116 /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
1097 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ 1117 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1098 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ 1118 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1119 /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
1120 /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
1121 /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
1122 /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
1123 /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
1124 /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
1125
1126 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1127 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1099 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ 1128 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1100 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ 1129 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1101 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ 1130 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1102 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ 1131 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1103 if ((insn & 0x0fb000f0) == 0x01000090) { 1132 if ((insn & 0x0f0000f0) == 0x01000090) {
1104 /* SWP/SWPB */ 1133 if ((insn & 0x0fb000f0) == 0x01000090) {
1105 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1134 /* SWP/SWPB */
1135 return prep_emulate_rd12rn16rm0_wflags(insn,
1136 asi);
1137 } else {
1138 /* STREX/LDREX variants and unallocaed space */
1139 return INSN_REJECTED;
1140 }
1141
1106 } else if ((insn & 0x0e1000d0) == 0x00000d0) { 1142 } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1107 /* STRD/LDRD */ 1143 /* STRD/LDRD */
1144 if ((insn & 0x0000e000) == 0x0000e000)
1145 return INSN_REJECTED; /* Rd is LR or PC */
1146 if (is_writeback(insn) && is_r15(insn, 16))
1147 return INSN_REJECTED; /* Writeback to PC */
1148
1108 insn &= 0xfff00fff; 1149 insn &= 0xfff00fff;
1109 insn |= 0x00002000; /* Rn = r0, Rd = r2 */ 1150 insn |= 0x00002000; /* Rn = r0, Rd = r2 */
1110 if (insn & (1 << 22)) { 1151 if (!(insn & (1 << 22))) {
1111 /* I bit */ 1152 /* Register index */
1112 insn &= ~0xf; 1153 insn &= ~0xf;
1113 insn |= 1; /* Rm = r1 */ 1154 insn |= 1; /* Rm = r1 */
1114 } 1155 }
@@ -1118,6 +1159,9 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1118 return INSN_GOOD; 1159 return INSN_GOOD;
1119 } 1160 }
1120 1161
1162 /* LDRH/STRH/LDRSB/LDRSH */
1163 if (is_r15(insn, 12))
1164 return INSN_REJECTED; /* Rd is PC */
1121 return prep_emulate_ldr_str(insn, asi); 1165 return prep_emulate_ldr_str(insn, asi);
1122 } 1166 }
1123 1167
@@ -1125,7 +1169,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1125 1169
1126 /* 1170 /*
1127 * ALU op with S bit and Rd == 15 : 1171 * ALU op with S bit and Rd == 15 :
1128 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx 1172 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1129 */ 1173 */
1130 if ((insn & 0x0e10f000) == 0x0010f000) 1174 if ((insn & 0x0e10f000) == 0x0010f000)
1131 return INSN_REJECTED; 1175 return INSN_REJECTED;
@@ -1154,22 +1198,61 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1154 insn |= 0x00000200; /* Rs = r2 */ 1198 insn |= 0x00000200; /* Rs = r2 */
1155 } 1199 }
1156 asi->insn[0] = insn; 1200 asi->insn[0] = insn;
1157 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1201
1202 if ((insn & 0x0f900000) == 0x01100000) {
1203 /*
1204 * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
1205 * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
1206 * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
1207 * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
1208 */
1209 asi->insn_handler = emulate_alu_tests;
1210 } else {
1211 /* ALU ops which write to Rd */
1212 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1158 emulate_alu_rwflags : emulate_alu_rflags; 1213 emulate_alu_rwflags : emulate_alu_rflags;
1214 }
1159 return INSN_GOOD; 1215 return INSN_GOOD;
1160} 1216}
1161 1217
1162static enum kprobe_insn __kprobes 1218static enum kprobe_insn __kprobes
1163space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1219space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1164{ 1220{
1221 /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
1222 /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
1223 if ((insn & 0x0fb00000) == 0x03000000)
1224 return prep_emulate_rd12_modify(insn, asi);
1225
1226 /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
1227 if ((insn & 0x0fff0000) == 0x03200000) {
1228 unsigned op2 = insn & 0x000000ff;
1229 if (op2 == 0x01 || op2 == 0x04) {
1230 /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
1231 /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
1232 asi->insn[0] = insn;
1233 asi->insn_handler = emulate_none;
1234 return INSN_GOOD;
1235 } else if (op2 <= 0x03) {
1236 /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
1237 /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
1238 /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
1239 /*
1240 * We make WFE and WFI true NOPs to avoid stalls due
1241 * to missing events whilst processing the probe.
1242 */
1243 asi->insn_handler = emulate_nop;
1244 return INSN_GOOD_NO_SLOT;
1245 }
1246 /* For DBG and unallocated hints it's safest to reject them */
1247 return INSN_REJECTED;
1248 }
1249
1165 /* 1250 /*
1166 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx 1251 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
1167 * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx
1168 * ALU op with S bit and Rd == 15 : 1252 * ALU op with S bit and Rd == 15 :
1169 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx 1253 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1170 */ 1254 */
1171 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ 1255 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */
1172 (insn & 0x0ff00000) == 0x03400000 || /* Undef */
1173 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ 1256 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
1174 return INSN_REJECTED; 1257 return INSN_REJECTED;
1175 1258
@@ -1180,10 +1263,22 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1180 * *S (bit 20) updates condition codes 1263 * *S (bit 20) updates condition codes
1181 * ADC/SBC/RSC reads the C flag 1264 * ADC/SBC/RSC reads the C flag
1182 */ 1265 */
1183 insn &= 0xffff0fff; /* Rd = r0 */ 1266 insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */
1184 asi->insn[0] = insn; 1267 asi->insn[0] = insn;
1185 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1268
1269 if ((insn & 0x0f900000) == 0x03100000) {
1270 /*
1271 * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
1272 * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
1273 * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
1274 * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
1275 */
1276 asi->insn_handler = emulate_alu_tests_imm;
1277 } else {
1278 /* ALU ops which write to Rd */
1279 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1186 emulate_alu_imm_rwflags : emulate_alu_imm_rflags; 1280 emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1281 }
1187 return INSN_GOOD; 1282 return INSN_GOOD;
1188} 1283}
1189 1284
@@ -1192,6 +1287,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1192{ 1287{
1193 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ 1288 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
1194 if ((insn & 0x0ff000f0) == 0x068000b0) { 1289 if ((insn & 0x0ff000f0) == 0x068000b0) {
1290 if (is_r15(insn, 12))
1291 return INSN_REJECTED; /* Rd is PC */
1195 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 1292 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
1196 insn |= 0x00000001; /* Rm = r1 */ 1293 insn |= 0x00000001; /* Rm = r1 */
1197 asi->insn[0] = insn; 1294 asi->insn[0] = insn;
@@ -1205,6 +1302,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1205 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ 1302 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
1206 if ((insn & 0x0fa00030) == 0x06a00010 || 1303 if ((insn & 0x0fa00030) == 0x06a00010 ||
1207 (insn & 0x0fb000f0) == 0x06a00030) { 1304 (insn & 0x0fb000f0) == 0x06a00030) {
1305 if (is_r15(insn, 12))
1306 return INSN_REJECTED; /* Rd is PC */
1208 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 1307 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
1209 asi->insn[0] = insn; 1308 asi->insn[0] = insn;
1210 asi->insn_handler = emulate_sat; 1309 asi->insn_handler = emulate_sat;
@@ -1213,57 +1312,101 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1213 1312
1214 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ 1313 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
1215 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ 1314 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
1315 /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
1216 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ 1316 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
1217 if ((insn & 0x0ff00070) == 0x06b00030 || 1317 if ((insn & 0x0ff00070) == 0x06b00030 ||
1218 (insn & 0x0ff000f0) == 0x06f000b0) 1318 (insn & 0x0ff00070) == 0x06f00030)
1219 return prep_emulate_rd12rm0(insn, asi); 1319 return prep_emulate_rd12rm0(insn, asi);
1220 1320
1321 /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */
1221 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ 1322 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
1222 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ 1323 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
1223 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ 1324 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
1224 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ 1325 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
1225 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ 1326 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
1327 /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */
1328 /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */
1226 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ 1329 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
1227 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ 1330 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */
1228 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ 1331 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */
1229 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ 1332 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */
1230 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ 1333 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */
1231 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ 1334 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */
1335 /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */
1336 /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */
1232 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ 1337 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */
1233 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ 1338 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */
1234 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ 1339 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */
1235 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ 1340 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */
1236 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ 1341 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */
1237 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ 1342 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */
1343 /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */
1344 /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */
1238 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ 1345 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */
1346 /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */
1239 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ 1347 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
1240 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ 1348 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
1241 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ 1349 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
1242 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ 1350 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
1243 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ 1351 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
1352 /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */
1353 /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */
1244 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ 1354 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
1245 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ 1355 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */
1246 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ 1356 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */
1247 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ 1357 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */
1248 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ 1358 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */
1249 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ 1359 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */
1360 /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */
1361 /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */
1250 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ 1362 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */
1251 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ 1363 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */
1252 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ 1364 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */
1253 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ 1365 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */
1254 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ 1366 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */
1255 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ 1367 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */
1368 /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */
1369 /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */
1256 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ 1370 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */
1371 if ((insn & 0x0f800010) == 0x06000010) {
1372 if ((insn & 0x00300000) == 0x00000000 ||
1373 (insn & 0x000000e0) == 0x000000a0 ||
1374 (insn & 0x000000e0) == 0x000000c0)
1375 return INSN_REJECTED; /* Unallocated space */
1376 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1377 }
1378
1257 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ 1379 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */
1258 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ 1380 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */
1381 if ((insn & 0x0ff00030) == 0x06800010)
1382 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1383
1259 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ 1384 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */
1260 /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1385 /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */
1386 /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */
1261 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1387 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
1388 /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */
1262 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ 1389 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */
1390 /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */
1263 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ 1391 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */
1392 /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */
1393 /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */
1264 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ 1394 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */
1395 /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */
1265 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ 1396 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */
1266 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1397 /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */
1398 if ((insn & 0x0f8000f0) == 0x06800070) {
1399 if ((insn & 0x00300000) == 0x00100000)
1400 return INSN_REJECTED; /* Unallocated space */
1401
1402 if ((insn & 0x000f0000) == 0x000f0000)
1403 return prep_emulate_rd12rm0(insn, asi);
1404 else
1405 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1406 }
1407
1408 /* Other instruction encodings aren't yet defined */
1409 return INSN_REJECTED;
1267} 1410}
1268 1411
1269static enum kprobe_insn __kprobes 1412static enum kprobe_insn __kprobes
@@ -1273,29 +1416,49 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1273 if ((insn & 0x0ff000f0) == 0x03f000f0) 1416 if ((insn & 0x0ff000f0) == 0x03f000f0)
1274 return INSN_REJECTED; 1417 return INSN_REJECTED;
1275 1418
1276 /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
1277 /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
1278 if ((insn & 0x0ff000f0) == 0x07800010)
1279 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1280
1281 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ 1419 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
1282 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ 1420 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
1283 if ((insn & 0x0ff00090) == 0x07400010) 1421 if ((insn & 0x0ff00090) == 0x07400010)
1284 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1422 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1285 1423
1286 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ 1424 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
1425 /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
1287 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ 1426 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
1427 /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */
1288 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ 1428 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */
1289 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ 1429 /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */
1430 /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */
1431 /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */
1290 if ((insn & 0x0ff00090) == 0x07000010 || 1432 if ((insn & 0x0ff00090) == 0x07000010 ||
1291 (insn & 0x0ff000d0) == 0x07500010 || 1433 (insn & 0x0ff000d0) == 0x07500010 ||
1292 (insn & 0x0ff000d0) == 0x075000d0) 1434 (insn & 0x0ff000f0) == 0x07800010) {
1435
1436 if ((insn & 0x0000f000) == 0x0000f000)
1437 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1438 else
1439 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1440 }
1441
1442 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */
1443 if ((insn & 0x0ff000d0) == 0x075000d0)
1293 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1444 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1294 1445
1295 /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ 1446 /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */
1296 /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ 1447 /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */
1297 /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ 1448 if ((insn & 0x0fa00070) == 0x07a00050)
1298 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1449 return prep_emulate_rd12rm0(insn, asi);
1450
1451 /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */
1452 /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */
1453 if ((insn & 0x0fe00070) == 0x07c00010) {
1454
1455 if ((insn & 0x0000000f) == 0x0000000f)
1456 return prep_emulate_rd12_modify(insn, asi);
1457 else
1458 return prep_emulate_rd12rn0_modify(insn, asi);
1459 }
1460
1461 return INSN_REJECTED;
1299} 1462}
1300 1463
1301static enum kprobe_insn __kprobes 1464static enum kprobe_insn __kprobes
@@ -1309,6 +1472,10 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1309 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ 1472 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
1310 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ 1473 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
1311 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ 1474 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
1475
1476 if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
1477 return INSN_REJECTED; /* LDRB into PC */
1478
1312 return prep_emulate_ldr_str(insn, asi); 1479 return prep_emulate_ldr_str(insn, asi);
1313} 1480}
1314 1481
@@ -1323,10 +1490,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1323 1490
1324 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 1491 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1325 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 1492 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1326 asi->insn[0] = truecc_insn(insn);
1327 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ 1493 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1328 simulate_stm1_pc : simulate_ldm1stm1; 1494 simulate_stm1_pc : simulate_ldm1stm1;
1329 return INSN_GOOD; 1495 return INSN_GOOD_NO_SLOT;
1330} 1496}
1331 1497
1332static enum kprobe_insn __kprobes 1498static enum kprobe_insn __kprobes
@@ -1334,58 +1500,117 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1334{ 1500{
1335 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 1501 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1336 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 1502 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1337 asi->insn[0] = truecc_insn(insn);
1338 asi->insn_handler = simulate_bbl; 1503 asi->insn_handler = simulate_bbl;
1339 return INSN_GOOD; 1504 return INSN_GOOD_NO_SLOT;
1340} 1505}
1341 1506
1342static enum kprobe_insn __kprobes 1507static enum kprobe_insn __kprobes
1343space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1508space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1344{ 1509{
1510 /* Coprocessor instructions... */
1345 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1511 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1346 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1512 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1347 insn &= 0xfff00fff; 1513 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1348 insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 1514 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1349 asi->insn[0] = insn; 1515 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1350 asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; 1516 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1351 return INSN_GOOD; 1517 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1518
1519 /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1520
1521 return INSN_REJECTED;
1352} 1522}
1353 1523
1354static enum kprobe_insn __kprobes 1524static unsigned long __kprobes __check_eq(unsigned long cpsr)
1355space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1356{ 1525{
1357 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1526 return cpsr & PSR_Z_BIT;
1358 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1359 insn &= 0xfff0ffff; /* Rn = r0 */
1360 asi->insn[0] = insn;
1361 asi->insn_handler = emulate_ldcstc;
1362 return INSN_GOOD;
1363} 1527}
1364 1528
1365static enum kprobe_insn __kprobes 1529static unsigned long __kprobes __check_ne(unsigned long cpsr)
1366space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1367{ 1530{
1368 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ 1531 return (~cpsr) & PSR_Z_BIT;
1369 /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ 1532}
1370 if ((insn & 0xfff000f0) == 0xe1200070 ||
1371 (insn & 0x0f000000) == 0x0f000000)
1372 return INSN_REJECTED;
1373 1533
1374 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1534static unsigned long __kprobes __check_cs(unsigned long cpsr)
1375 if ((insn & 0x0f000010) == 0x0e000000) { 1535{
1376 asi->insn[0] = insn; 1536 return cpsr & PSR_C_BIT;
1377 asi->insn_handler = emulate_none; 1537}
1378 return INSN_GOOD;
1379 }
1380 1538
1381 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 1539static unsigned long __kprobes __check_cc(unsigned long cpsr)
1382 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1540{
1383 insn &= 0xffff0fff; /* Rd = r0 */ 1541 return (~cpsr) & PSR_C_BIT;
1384 asi->insn[0] = insn; 1542}
1385 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; 1543
1386 return INSN_GOOD; 1544static unsigned long __kprobes __check_mi(unsigned long cpsr)
1545{
1546 return cpsr & PSR_N_BIT;
1547}
1548
1549static unsigned long __kprobes __check_pl(unsigned long cpsr)
1550{
1551 return (~cpsr) & PSR_N_BIT;
1552}
1553
1554static unsigned long __kprobes __check_vs(unsigned long cpsr)
1555{
1556 return cpsr & PSR_V_BIT;
1557}
1558
1559static unsigned long __kprobes __check_vc(unsigned long cpsr)
1560{
1561 return (~cpsr) & PSR_V_BIT;
1562}
1563
1564static unsigned long __kprobes __check_hi(unsigned long cpsr)
1565{
1566 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1567 return cpsr & PSR_C_BIT;
1387} 1568}
1388 1569
1570static unsigned long __kprobes __check_ls(unsigned long cpsr)
1571{
1572 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1573 return (~cpsr) & PSR_C_BIT;
1574}
1575
1576static unsigned long __kprobes __check_ge(unsigned long cpsr)
1577{
1578 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1579 return (~cpsr) & PSR_N_BIT;
1580}
1581
1582static unsigned long __kprobes __check_lt(unsigned long cpsr)
1583{
1584 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1585 return cpsr & PSR_N_BIT;
1586}
1587
1588static unsigned long __kprobes __check_gt(unsigned long cpsr)
1589{
1590 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1591 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1592 return (~temp) & PSR_N_BIT;
1593}
1594
1595static unsigned long __kprobes __check_le(unsigned long cpsr)
1596{
1597 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1598 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1599 return temp & PSR_N_BIT;
1600}
1601
1602static unsigned long __kprobes __check_al(unsigned long cpsr)
1603{
1604 return true;
1605}
1606
1607static kprobe_check_cc * const condition_checks[16] = {
1608 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
1609 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
1610 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
1611 &__check_gt, &__check_le, &__check_al, &__check_al
1612};
1613
1389/* Return: 1614/* Return:
1390 * INSN_REJECTED If instruction is one not allowed to kprobe, 1615 * INSN_REJECTED If instruction is one not allowed to kprobe,
1391 * INSN_GOOD If instruction is supported and uses instruction slot, 1616 * INSN_GOOD If instruction is supported and uses instruction slot,
@@ -1401,133 +1626,45 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1401enum kprobe_insn __kprobes 1626enum kprobe_insn __kprobes
1402arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1627arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1403{ 1628{
1629 asi->insn_check_cc = condition_checks[insn>>28];
1404 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1630 asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1405 1631
1406 if ((insn & 0xf0000000) == 0xf0000000) { 1632 if ((insn & 0xf0000000) == 0xf0000000)
1407 1633
1408 return space_1111(insn, asi); 1634 return space_1111(insn, asi);
1409 1635
1410 } else if ((insn & 0x0e000000) == 0x00000000) { 1636 else if ((insn & 0x0e000000) == 0x00000000)
1411 1637
1412 return space_cccc_000x(insn, asi); 1638 return space_cccc_000x(insn, asi);
1413 1639
1414 } else if ((insn & 0x0e000000) == 0x02000000) { 1640 else if ((insn & 0x0e000000) == 0x02000000)
1415 1641
1416 return space_cccc_001x(insn, asi); 1642 return space_cccc_001x(insn, asi);
1417 1643
1418 } else if ((insn & 0x0f000010) == 0x06000010) { 1644 else if ((insn & 0x0f000010) == 0x06000010)
1419 1645
1420 return space_cccc_0110__1(insn, asi); 1646 return space_cccc_0110__1(insn, asi);
1421 1647
1422 } else if ((insn & 0x0f000010) == 0x07000010) { 1648 else if ((insn & 0x0f000010) == 0x07000010)
1423 1649
1424 return space_cccc_0111__1(insn, asi); 1650 return space_cccc_0111__1(insn, asi);
1425 1651
1426 } else if ((insn & 0x0c000000) == 0x04000000) { 1652 else if ((insn & 0x0c000000) == 0x04000000)
1427 1653
1428 return space_cccc_01xx(insn, asi); 1654 return space_cccc_01xx(insn, asi);
1429 1655
1430 } else if ((insn & 0x0e000000) == 0x08000000) { 1656 else if ((insn & 0x0e000000) == 0x08000000)
1431 1657
1432 return space_cccc_100x(insn, asi); 1658 return space_cccc_100x(insn, asi);
1433 1659
1434 } else if ((insn & 0x0e000000) == 0x0a000000) { 1660 else if ((insn & 0x0e000000) == 0x0a000000)
1435 1661
1436 return space_cccc_101x(insn, asi); 1662 return space_cccc_101x(insn, asi);
1437 1663
1438 } else if ((insn & 0x0fe00000) == 0x0c400000) { 1664 return space_cccc_11xx(insn, asi);
1439
1440 return space_cccc_1100_010x(insn, asi);
1441
1442 } else if ((insn & 0x0e000000) == 0x0c000000) {
1443
1444 return space_cccc_110x(insn, asi);
1445
1446 }
1447
1448 return space_cccc_111x(insn, asi);
1449} 1665}
1450 1666
1451void __init arm_kprobe_decode_init(void) 1667void __init arm_kprobe_decode_init(void)
1452{ 1668{
1453 find_str_pc_offset(); 1669 find_str_pc_offset();
1454} 1670}
1455
1456
1457/*
1458 * All ARM instructions listed below.
1459 *
1460 * Instructions and their general purpose registers are given.
1461 * If a particular register may not use R15, it is prefixed with a "!".
1462 * If marked with a "*" means the value returned by reading R15
1463 * is implementation defined.
1464 *
1465 * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
1466 * TST: Rd, Rn, Rm, !Rs
1467 * BX: Rm
1468 * BLX(2): !Rm
1469 * BX: Rm (R15 legal, but discouraged)
1470 * BXJ: !Rm,
1471 * CLZ: !Rd, !Rm
1472 * CPY: Rd, Rm
1473 * LDC/2,STC/2 immediate offset & unindex: Rn
1474 * LDC/2,STC/2 immediate pre/post-indexed: !Rn
1475 * LDM(1/3): !Rn, register_list
1476 * LDM(2): !Rn, !register_list
1477 * LDR,STR,PLD immediate offset: Rd, Rn
1478 * LDR,STR,PLD register offset: Rd, Rn, !Rm
1479 * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
1480 * LDR,STR immediate pre/post-indexed: Rd, !Rn
1481 * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
1482 * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
1483 * LDRB,STRB immediate offset: !Rd, Rn
1484 * LDRB,STRB register offset: !Rd, Rn, !Rm
1485 * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
1486 * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
1487 * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
1488 * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
1489 * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
1490 * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
1491 * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
1492 * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
1493 * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
1494 * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
1495 * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
1496 * LDREX: !Rd, !Rn
1497 * MCR/2: !Rd
1498 * MCRR/2,MRRC/2: !Rd, !Rn
1499 * MLA: !Rd, !Rn, !Rm, !Rs
1500 * MOV: Rd
1501 * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
1502 * MRS,MSR: !Rd
1503 * MUL: !Rd, !Rm, !Rs
1504 * PKH{BT,TB}: !Rd, !Rn, !Rm
1505 * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
1506 * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
1507 * REV/16/SH: !Rd, !Rm
1508 * RFE: !Rn
1509 * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
1510 * SEL: !Rd, !Rn, !Rm
1511 * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
1512 * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
1513 * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
1514 * SSAT/16: !Rd, !Rm
1515 * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
1516 * STRT immediate pre/post-indexed: Rd*, !Rn
1517 * STRT register pre/post-indexed: Rd*, !Rn, !Rm
1518 * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
1519 * STREX: !Rd, !Rn, !Rm
1520 * SWP/B: !Rd, !Rn, !Rm
1521 * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
1522 * {S,U}XT{B,B16,H}: !Rd, !Rm
1523 * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
1524 * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
1525 *
1526 * May transfer control by writing R15 (possible mode changes or alternate
1527 * mode accesses marked by "*"):
1528 * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
1529 * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
1530 *
1531 * Instructions that do not take general registers, nor transfer control:
1532 * CDP/2, SETEND, SRS*
1533 */
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 2ba7deb3072e..1656c87501c0 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -134,7 +134,8 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
134 struct kprobe_ctlblk *kcb) 134 struct kprobe_ctlblk *kcb)
135{ 135{
136 regs->ARM_pc += 4; 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/*
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 979da3947f42..139e3c827369 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -746,7 +746,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
746 746
747 tail = (struct frame_tail __user *)regs->ARM_fp - 1; 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 tail = user_backtrace(tail, entry); 751 tail = user_backtrace(tail, entry);
751} 752}
752 753
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 2bf27f364d09..8182f45ca493 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request,
767 767
768#ifdef CONFIG_HAVE_HW_BREAKPOINT 768#ifdef CONFIG_HAVE_HW_BREAKPOINT
769 case PTRACE_GETHBPREGS: 769 case PTRACE_GETHBPREGS:
770 if (ptrace_get_breakpoints(child) < 0)
771 return -ESRCH;
772
770 ret = ptrace_gethbpregs(child, addr, 773 ret = ptrace_gethbpregs(child, addr,
771 (unsigned long __user *)data); 774 (unsigned long __user *)data);
775 ptrace_put_breakpoints(child);
772 break; 776 break;
773 case PTRACE_SETHBPREGS: 777 case PTRACE_SETHBPREGS:
778 if (ptrace_get_breakpoints(child) < 0)
779 return -ESRCH;
780
774 ret = ptrace_sethbpregs(child, addr, 781 ret = ptrace_sethbpregs(child, addr,
775 (unsigned long __user *)data); 782 (unsigned long __user *)data);
783 ptrace_put_breakpoints(child);
776 break; 784 break;
777#endif 785#endif
778 786
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8fe05ad932e4..f29b8a29b174 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -479,7 +479,7 @@ static void broadcast_timer_set_mode(enum clock_event_mode mode,
479{ 479{
480} 480}
481 481
482static void broadcast_timer_setup(struct clock_event_device *evt) 482static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
483{ 483{
484 evt->name = "dummy_timer"; 484 evt->name = "dummy_timer";
485 evt->features = CLOCK_EVT_FEAT_ONESHOT | 485 evt->features = CLOCK_EVT_FEAT_ONESHOT |
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 4ad8da15ef2b..af0aaebf4de6 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int semid,
311 long err; 311 long err;
312 int i; 312 int i;
313 313
314 if (nsops < 1) 314 if (nsops < 1 || nsops > SEMOPM)
315 return -EINVAL; 315 return -EINVAL;
316 sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); 316 sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
317 if (!sops) 317 if (!sops)
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 19390231a0e9..2d299bf5d72f 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -83,6 +83,7 @@ config ARCH_AT91CAP9
83 select CPU_ARM926T 83 select CPU_ARM926T
84 select GENERIC_CLOCKEVENTS 84 select GENERIC_CLOCKEVENTS
85 select HAVE_FB_ATMEL 85 select HAVE_FB_ATMEL
86 select HAVE_NET_MACB
86 87
87config ARCH_AT572D940HF 88config ARCH_AT572D940HF
88 bool "AT572D940HF" 89 bool "AT572D940HF"
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c
index 1f9d3cb64c50..d8df59a3426d 100644
--- a/arch/arm/mach-at91/board-eb01.c
+++ b/arch/arm/mach-at91/board-eb01.c
@@ -30,6 +30,11 @@
30#include <mach/board.h> 30#include <mach/board.h>
31#include "generic.h" 31#include "generic.h"
32 32
33static void __init at91eb01_init_irq(void)
34{
35 at91x40_init_interrupts(NULL);
36}
37
33static void __init at91eb01_map_io(void) 38static void __init at91eb01_map_io(void)
34{ 39{
35 at91x40_initialize(40000000); 40 at91x40_initialize(40000000);
@@ -38,7 +43,7 @@ static void __init at91eb01_map_io(void)
38MACHINE_START(AT91EB01, "Atmel AT91 EB01") 43MACHINE_START(AT91EB01, "Atmel AT91 EB01")
39 /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ 44 /* Maintainer: Greg Ungerer <gerg@snapgear.com> */
40 .timer = &at91x40_timer, 45 .timer = &at91x40_timer,
41 .init_irq = at91x40_init_interrupts, 46 .init_irq = at91eb01_init_irq,
42 .map_io = at91eb01_map_io, 47 .map_io = at91eb01_map_io,
43MACHINE_END 48MACHINE_END
44 49
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 3bef931d0b1c..0700f2125305 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -27,6 +27,7 @@
27#define ARCH_ID_AT91SAM9G45 0x819b05a0 27#define ARCH_ID_AT91SAM9G45 0x819b05a0
28#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ 28#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
29#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ 29#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
30#define ARCH_ID_AT91SAM9X5 0x819a05a0
30#define ARCH_ID_AT91CAP9 0x039A03A0 31#define ARCH_ID_AT91CAP9 0x039A03A0
31 32
32#define ARCH_ID_AT91SAM9XE128 0x329973a0 33#define ARCH_ID_AT91SAM9XE128 0x329973a0
@@ -55,6 +56,12 @@ static inline unsigned long at91_cpu_fully_identify(void)
55#define ARCH_EXID_AT91SAM9G46 0x00000003 56#define ARCH_EXID_AT91SAM9G46 0x00000003
56#define ARCH_EXID_AT91SAM9G45 0x00000004 57#define ARCH_EXID_AT91SAM9G45 0x00000004
57 58
59#define ARCH_EXID_AT91SAM9G15 0x00000000
60#define ARCH_EXID_AT91SAM9G35 0x00000001
61#define ARCH_EXID_AT91SAM9X35 0x00000002
62#define ARCH_EXID_AT91SAM9G25 0x00000003
63#define ARCH_EXID_AT91SAM9X25 0x00000004
64
58static inline unsigned long at91_exid_identify(void) 65static inline unsigned long at91_exid_identify(void)
59{ 66{
60 return at91_sys_read(AT91_DBGU_EXID); 67 return at91_sys_read(AT91_DBGU_EXID);
@@ -143,6 +150,27 @@ static inline unsigned long at91cap9_rev_identify(void)
143#define cpu_is_at91sam9m11() (0) 150#define cpu_is_at91sam9m11() (0)
144#endif 151#endif
145 152
153#ifdef CONFIG_ARCH_AT91SAM9X5
154#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5)
155#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \
156 (at91_exid_identify() == ARCH_EXID_AT91SAM9G15))
157#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \
158 (at91_exid_identify() == ARCH_EXID_AT91SAM9G35))
159#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \
160 (at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
161#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \
162 (at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
163#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \
164 (at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
165#else
166#define cpu_is_at91sam9x5() (0)
167#define cpu_is_at91sam9g15() (0)
168#define cpu_is_at91sam9g35() (0)
169#define cpu_is_at91sam9x35() (0)
170#define cpu_is_at91sam9g25() (0)
171#define cpu_is_at91sam9x25() (0)
172#endif
173
146#ifdef CONFIG_ARCH_AT91CAP9 174#ifdef CONFIG_ARCH_AT91CAP9
147#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) 175#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
148#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) 176#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 32f147998cd9..c0deacae778d 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -63,6 +63,7 @@ config MACH_DAVINCI_EVM
63 depends on ARCH_DAVINCI_DM644x 63 depends on ARCH_DAVINCI_DM644x
64 select MISC_DEVICES 64 select MISC_DEVICES
65 select EEPROM_AT24 65 select EEPROM_AT24
66 select I2C
66 help 67 help
67 Configure this option to specify the whether the board used 68 Configure this option to specify the whether the board used
68 for development is a DM644x EVM 69 for development is a DM644x EVM
@@ -72,6 +73,7 @@ config MACH_SFFSDR
72 depends on ARCH_DAVINCI_DM644x 73 depends on ARCH_DAVINCI_DM644x
73 select MISC_DEVICES 74 select MISC_DEVICES
74 select EEPROM_AT24 75 select EEPROM_AT24
76 select I2C
75 help 77 help
76 Say Y here to select the Lyrtech Small Form Factor 78 Say Y here to select the Lyrtech Small Form Factor
77 Software Defined Radio (SFFSDR) board. 79 Software Defined Radio (SFFSDR) board.
@@ -105,6 +107,7 @@ config MACH_DAVINCI_DM6467_EVM
105 select MACH_DAVINCI_DM6467TEVM 107 select MACH_DAVINCI_DM6467TEVM
106 select MISC_DEVICES 108 select MISC_DEVICES
107 select EEPROM_AT24 109 select EEPROM_AT24
110 select I2C
108 help 111 help
109 Configure this option to specify the whether the board used 112 Configure this option to specify the whether the board used
110 for development is a DM6467 EVM 113 for development is a DM6467 EVM
@@ -118,6 +121,7 @@ config MACH_DAVINCI_DM365_EVM
118 depends on ARCH_DAVINCI_DM365 121 depends on ARCH_DAVINCI_DM365
119 select MISC_DEVICES 122 select MISC_DEVICES
120 select EEPROM_AT24 123 select EEPROM_AT24
124 select I2C
121 help 125 help
122 Configure this option to specify whether the board used 126 Configure this option to specify whether the board used
123 for development is a DM365 EVM 127 for development is a DM365 EVM
@@ -129,6 +133,7 @@ config MACH_DAVINCI_DA830_EVM
129 select GPIO_PCF857X 133 select GPIO_PCF857X
130 select MISC_DEVICES 134 select MISC_DEVICES
131 select EEPROM_AT24 135 select EEPROM_AT24
136 select I2C
132 help 137 help
133 Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. 138 Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
134 139
@@ -205,6 +210,7 @@ config MACH_MITYOMAPL138
205 depends on ARCH_DAVINCI_DA850 210 depends on ARCH_DAVINCI_DA850
206 select MISC_DEVICES 211 select MISC_DEVICES
207 select EEPROM_AT24 212 select EEPROM_AT24
213 select I2C
208 help 214 help
209 Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 215 Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
210 System on Module. Information on this SoM may be found at 216 System on Module. Information on this SoM may be found at
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 2aa79c54f98e..606a6f27ed6c 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -29,7 +29,7 @@
29#include <mach/mux.h> 29#include <mach/mux.h>
30#include <mach/spi.h> 30#include <mach/spi.h>
31 31
32#define MITYOMAPL138_PHY_ID "0:03" 32#define MITYOMAPL138_PHY_ID ""
33 33
34#define FACTORY_CONFIG_MAGIC 0x012C0138 34#define FACTORY_CONFIG_MAGIC 0x012C0138
35#define FACTORY_CONFIG_VERSION 0x00010001 35#define FACTORY_CONFIG_VERSION 0x00010001
@@ -414,7 +414,7 @@ static struct resource mityomapl138_nandflash_resource[] = {
414 414
415static struct platform_device mityomapl138_nandflash_device = { 415static struct platform_device mityomapl138_nandflash_device = {
416 .name = "davinci_nand", 416 .name = "davinci_nand",
417 .id = 0, 417 .id = 1,
418 .dev = { 418 .dev = {
419 .platform_data = &mityomapl138_nandflash_data, 419 .platform_data = &mityomapl138_nandflash_data,
420 }, 420 },
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 625d4b66718b..58a02dc7b15a 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -39,7 +39,8 @@
39#define DA8XX_GPIO_BASE 0x01e26000 39#define DA8XX_GPIO_BASE 0x01e26000
40#define DA8XX_I2C1_BASE 0x01e28000 40#define DA8XX_I2C1_BASE 0x01e28000
41#define DA8XX_SPI0_BASE 0x01c41000 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#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 45#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000
45#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 46#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000
@@ -762,8 +763,8 @@ static struct resource da8xx_spi0_resources[] = {
762 763
763static struct resource da8xx_spi1_resources[] = { 764static struct resource da8xx_spi1_resources[] = {
764 [0] = { 765 [0] = {
765 .start = DA8XX_SPI1_BASE, 766 .start = DA830_SPI1_BASE,
766 .end = DA8XX_SPI1_BASE + SZ_4K - 1, 767 .end = DA830_SPI1_BASE + SZ_4K - 1,
767 .flags = IORESOURCE_MEM, 768 .flags = IORESOURCE_MEM,
768 }, 769 },
769 [1] = { 770 [1] = {
@@ -832,5 +833,10 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info,
832 833
833 da8xx_spi_pdata[instance].num_chipselect = len; 834 da8xx_spi_pdata[instance].num_chipselect = len;
834 835
836 if (instance == 1 && cpu_is_davinci_da850()) {
837 da8xx_spi1_resources[0].start = DA850_SPI1_BASE;
838 da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1;
839 }
840
835 return platform_device_register(&da8xx_spi_device[instance]); 841 return platform_device_register(&da8xx_spi_device[instance]);
836} 842}
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f68012239641..a3a94e9c9378 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -314,7 +314,7 @@ static struct clk timer2_clk = {
314 .name = "timer2", 314 .name = "timer2",
315 .parent = &pll1_aux_clk, 315 .parent = &pll1_aux_clk,
316 .lpsc = DAVINCI_LPSC_TIMER2, 316 .lpsc = DAVINCI_LPSC_TIMER2,
317 .usecount = 1, /* REVISIT: why can't' this be disabled? */ 317 .usecount = 1, /* REVISIT: why can't this be disabled? */
318}; 318};
319 319
320static struct clk timer3_clk = { 320static struct clk timer3_clk = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 5f8a65424184..4c82c2716293 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -274,7 +274,7 @@ static struct clk timer2_clk = {
274 .name = "timer2", 274 .name = "timer2",
275 .parent = &pll1_aux_clk, 275 .parent = &pll1_aux_clk,
276 .lpsc = DAVINCI_LPSC_TIMER2, 276 .lpsc = DAVINCI_LPSC_TIMER2,
277 .usecount = 1, /* REVISIT: why can't' this be disabled? */ 277 .usecount = 1, /* REVISIT: why can't this be disabled? */
278}; 278};
279 279
280static struct clk_lookup dm644x_clks[] = { 280static struct clk_lookup dm644x_clks[] = {
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index 9f1befc5ac38..f8b7ea4f6235 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -24,6 +24,9 @@
24 24
25#define UART_SHIFT 2 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 .pushsection .data 30 .pushsection .data
28davinci_uart_phys: .word 0 31davinci_uart_phys: .word 0
29davinci_uart_virt: .word 0 32davinci_uart_virt: .word 0
@@ -34,7 +37,7 @@ davinci_uart_virt: .word 0
34 /* Use davinci_uart_phys/virt if already configured */ 37 /* Use davinci_uart_phys/virt if already configured */
3510: mrc p15, 0, \rp, c1, c0 3810: mrc p15, 0, \rp, c1, c0
36 tst \rp, #1 @ MMU enabled? 39 tst \rp, #1 @ MMU enabled?
37 ldreq \rp, =__virt_to_phys(davinci_uart_phys) 40 ldreq \rp, =davinci_uart_v2p(davinci_uart_phys)
38 ldrne \rp, =davinci_uart_phys 41 ldrne \rp, =davinci_uart_phys
39 add \rv, \rp, #4 @ davinci_uart_virt 42 add \rv, \rp, #4 @ davinci_uart_virt
40 ldr \rp, [\rp, #0] 43 ldr \rp, [\rp, #0]
@@ -48,18 +51,18 @@ davinci_uart_virt: .word 0
48 tst \rp, #1 @ MMU enabled? 51 tst \rp, #1 @ MMU enabled?
49 52
50 /* Copy uart phys address from decompressor uart info */ 53 /* Copy uart phys address from decompressor uart info */
51 ldreq \rv, =__virt_to_phys(davinci_uart_phys) 54 ldreq \rv, =davinci_uart_v2p(davinci_uart_phys)
52 ldrne \rv, =davinci_uart_phys 55 ldrne \rv, =davinci_uart_phys
53 ldreq \rp, =DAVINCI_UART_INFO 56 ldreq \rp, =DAVINCI_UART_INFO
54 ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) 57 ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
55 ldr \rp, [\rp, #0] 58 ldr \rp, [\rp, #0]
56 str \rp, [\rv] 59 str \rp, [\rv]
57 60
58 /* Copy uart virt address from decompressor uart info */ 61 /* Copy uart virt address from decompressor uart info */
59 ldreq \rv, =__virt_to_phys(davinci_uart_virt) 62 ldreq \rv, =davinci_uart_v2p(davinci_uart_virt)
60 ldrne \rv, =davinci_uart_virt 63 ldrne \rv, =davinci_uart_virt
61 ldreq \rp, =DAVINCI_UART_INFO 64 ldreq \rp, =DAVINCI_UART_INFO
62 ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) 65 ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
63 ldr \rp, [\rp, #4] 66 ldr \rp, [\rp, #4]
64 str \rp, [\rv] 67 str \rp, [\rv]
65 68
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
index 8051110b8ac3..c9e6ce185a66 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -22,7 +22,7 @@
22 * 22 *
23 * This area sits just below the page tables (see arch/arm/kernel/head.S). 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#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) 27#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
28#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) 28#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
diff --git a/arch/arm/mach-mx3/mach-vpr200.c b/arch/arm/mach-mx3/mach-vpr200.c
index 2cf390fbd980..47a69cbc31a8 100644
--- a/arch/arm/mach-mx3/mach-vpr200.c
+++ b/arch/arm/mach-mx3/mach-vpr200.c
@@ -257,11 +257,16 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
257 .workaround = FLS_USB2_WORKAROUND_ENGCM09152, 257 .workaround = FLS_USB2_WORKAROUND_ENGCM09152,
258}; 258};
259 259
260static 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/* USB HOST config */ 266/* USB HOST config */
261static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { 267static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
262 .portsc = MXC_EHCI_MODE_SERIAL, 268 .init = vpr200_usbh_init,
263 .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | 269 .portsc = MXC_EHCI_MODE_SERIAL,
264 MXC_EHCI_INTERNAL_PHY,
265}; 270};
266 271
267static struct platform_device *devices[] __initdata = { 272static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 10a1bea10548..6206b1191fe8 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -193,7 +193,7 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {
193 .wakeup = wake, \ 193 .wakeup = wake, \
194} 194}
195 195
196static const struct gpio_keys_button loco_buttons[] __initconst = { 196static struct gpio_keys_button loco_buttons[] = {
197 GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), 197 GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0),
198 GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), 198 GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
199 GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0), 199 GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 1ad97fed1e94..5dcc59d5b9ec 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
295 unsigned long diff, parent_rate, calc_rate; \ 295 unsigned long diff, parent_rate, calc_rate; \
296 int i; \ 296 int i; \
297 \ 297 \
298 parent_rate = clk_get_rate(clk->parent); \
299 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ 298 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
300 bm_busy = BM_CLKCTRL_##dr##_BUSY; \ 299 bm_busy = BM_CLKCTRL_##dr##_BUSY; \
301 \ 300 \
302 if (clk->parent == &ref_xtal_clk) { \ 301 if (clk->parent == &ref_xtal_clk) { \
302 parent_rate = clk_get_rate(clk->parent); \
303 div = DIV_ROUND_UP(parent_rate, rate); \ 303 div = DIV_ROUND_UP(parent_rate, rate); \
304 if (clk == &cpu_clk) { \ 304 if (clk == &cpu_clk) { \
305 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \ 305 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
@@ -309,6 +309,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
309 if (div == 0 || div > div_max) \ 309 if (div == 0 || div > div_max) \
310 return -EINVAL; \ 310 return -EINVAL; \
311 } else { \ 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 rate >>= PARENT_RATE_SHIFT; \ 317 rate >>= PARENT_RATE_SHIFT; \
313 parent_rate >>= PARENT_RATE_SHIFT; \ 318 parent_rate >>= PARENT_RATE_SHIFT; \
314 diff = parent_rate; \ 319 diff = parent_rate; \
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a45cd6409686..512b15204450 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -68,7 +68,7 @@ obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
68obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 68obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
69 69
70AFLAGS_sleep24xx.o :=-Wa,-march=armv6 70AFLAGS_sleep24xx.o :=-Wa,-march=armv6
71AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a 71AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
72 72
73ifeq ($(CONFIG_PM_VERBOSE),y) 73ifeq ($(CONFIG_PM_VERBOSE),y)
74CFLAGS_pm_bus.o += -DDEBUG 74CFLAGS_pm_bus.o += -DDEBUG
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index e964895b80e8..f8ba20a14e62 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -141,14 +141,19 @@ static void __init rx51_init(void)
141static void __init rx51_map_io(void) 141static void __init rx51_map_io(void)
142{ 142{
143 omap2_set_globals_3xxx(); 143 omap2_set_globals_3xxx();
144 rx51_video_mem_init();
145 omap34xx_map_common_io(); 144 omap34xx_map_common_io();
146} 145}
147 146
147static void __init rx51_reserve(void)
148{
149 rx51_video_mem_init();
150 omap_reserve();
151}
152
148MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") 153MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
149 /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */ 154 /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
150 .boot_params = 0x80000100, 155 .boot_params = 0x80000100,
151 .reserve = omap_reserve, 156 .reserve = rx51_reserve,
152 .map_io = rx51_map_io, 157 .map_io = rx51_map_io,
153 .init_early = rx51_init_early, 158 .init_early = rx51_init_early,
154 .init_irq = omap_init_irq, 159 .init_irq = omap_init_irq,
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 276992d3b7fb..8c965671b4d4 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3116,14 +3116,9 @@ static struct omap_clk omap44xx_clks[] = {
3116 CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), 3116 CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
3117 CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X), 3117 CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X),
3118 CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X), 3118 CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X),
3119 CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X),
3120 CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X), 3119 CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X),
3121 CLK("omapdss_dss", "fck", &dss_fck, CK_443X), 3120 CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X),
3122 /* 3121 CLK("omapdss_dss", "ick", &dss_fck, CK_443X),
3123 * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility
3124 * with OMAP2/3.
3125 */
3126 CLK("omapdss_dss", "ick", &dummy_ck, CK_443X),
3127 CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), 3122 CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
3128 CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), 3123 CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
3129 CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), 3124 CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index 9d0dec806e92..38830d8d4783 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -247,6 +247,7 @@ struct omap3_cm_regs {
247 u32 per_cm_clksel; 247 u32 per_cm_clksel;
248 u32 emu_cm_clksel; 248 u32 emu_cm_clksel;
249 u32 emu_cm_clkstctrl; 249 u32 emu_cm_clkstctrl;
250 u32 pll_cm_autoidle;
250 u32 pll_cm_autoidle2; 251 u32 pll_cm_autoidle2;
251 u32 pll_cm_clksel4; 252 u32 pll_cm_clksel4;
252 u32 pll_cm_clksel5; 253 u32 pll_cm_clksel5;
@@ -319,6 +320,15 @@ void omap3_cm_save_context(void)
319 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1); 320 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
320 cm_context.emu_cm_clkstctrl = 321 cm_context.emu_cm_clkstctrl =
321 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); 322 omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
323 /*
324 * As per erratum i671, ROM code does not respect the PER DPLL
325 * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
326 * In this case, even though this register has been saved in
327 * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
328 * by ourselves. So, we need to save it anyway.
329 */
330 cm_context.pll_cm_autoidle =
331 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
322 cm_context.pll_cm_autoidle2 = 332 cm_context.pll_cm_autoidle2 =
323 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2); 333 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
324 cm_context.pll_cm_clksel4 = 334 cm_context.pll_cm_clksel4 =
@@ -441,6 +451,13 @@ void omap3_cm_restore_context(void)
441 CM_CLKSEL1); 451 CM_CLKSEL1);
442 omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD, 452 omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
443 OMAP2_CM_CLKSTCTRL); 453 OMAP2_CM_CLKSTCTRL);
454 /*
455 * As per erratum i671, ROM code does not respect the PER DPLL
456 * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
457 * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
458 */
459 omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
460 CM_AUTOIDLE);
444 omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD, 461 omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
445 CM_AUTOIDLE2); 462 CM_AUTOIDLE2);
446 omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD, 463 omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 695279419020..da53ba3917ca 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -316,8 +316,14 @@ void omap3_save_scratchpad_contents(void)
316 omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); 316 omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
317 prcm_block_contents.cm_clken_pll = 317 prcm_block_contents.cm_clken_pll =
318 omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); 318 omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
319 /*
320 * As per erratum i671, ROM code does not respect the PER DPLL
321 * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
322 * Then, in anycase, clear these bits to avoid extra latencies.
323 */
319 prcm_block_contents.cm_autoidle_pll = 324 prcm_block_contents.cm_autoidle_pll =
320 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL); 325 omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
326 ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
321 prcm_block_contents.cm_clksel1_pll = 327 prcm_block_contents.cm_clksel1_pll =
322 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); 328 omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
323 prcm_block_contents.cm_clksel2_pll = 329 prcm_block_contents.cm_clksel2_pll =
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 8eb3ce1bbfbe..c4d0ae87d62a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -1639,6 +1639,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = {
1639 1639
1640static struct omap_hwmod omap2420_gpio1_hwmod = { 1640static struct omap_hwmod omap2420_gpio1_hwmod = {
1641 .name = "gpio1", 1641 .name = "gpio1",
1642 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1642 .mpu_irqs = omap242x_gpio1_irqs, 1643 .mpu_irqs = omap242x_gpio1_irqs,
1643 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs), 1644 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs),
1644 .main_clk = "gpios_fck", 1645 .main_clk = "gpios_fck",
@@ -1669,6 +1670,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = {
1669 1670
1670static struct omap_hwmod omap2420_gpio2_hwmod = { 1671static struct omap_hwmod omap2420_gpio2_hwmod = {
1671 .name = "gpio2", 1672 .name = "gpio2",
1673 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1672 .mpu_irqs = omap242x_gpio2_irqs, 1674 .mpu_irqs = omap242x_gpio2_irqs,
1673 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs), 1675 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs),
1674 .main_clk = "gpios_fck", 1676 .main_clk = "gpios_fck",
@@ -1699,6 +1701,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = {
1699 1701
1700static struct omap_hwmod omap2420_gpio3_hwmod = { 1702static struct omap_hwmod omap2420_gpio3_hwmod = {
1701 .name = "gpio3", 1703 .name = "gpio3",
1704 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1702 .mpu_irqs = omap242x_gpio3_irqs, 1705 .mpu_irqs = omap242x_gpio3_irqs,
1703 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs), 1706 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs),
1704 .main_clk = "gpios_fck", 1707 .main_clk = "gpios_fck",
@@ -1729,6 +1732,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = {
1729 1732
1730static struct omap_hwmod omap2420_gpio4_hwmod = { 1733static struct omap_hwmod omap2420_gpio4_hwmod = {
1731 .name = "gpio4", 1734 .name = "gpio4",
1735 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1732 .mpu_irqs = omap242x_gpio4_irqs, 1736 .mpu_irqs = omap242x_gpio4_irqs,
1733 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs), 1737 .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs),
1734 .main_clk = "gpios_fck", 1738 .main_clk = "gpios_fck",
@@ -1782,7 +1786,7 @@ static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = {
1782static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = { 1786static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = {
1783 { 1787 {
1784 .pa_start = 0x48056000, 1788 .pa_start = 0x48056000,
1785 .pa_end = 0x4a0560ff, 1789 .pa_end = 0x48056fff,
1786 .flags = ADDR_TYPE_RT 1790 .flags = ADDR_TYPE_RT
1787 }, 1791 },
1788}; 1792};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index e6e3810db77f..9682dd519f8d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -1742,6 +1742,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = {
1742 1742
1743static struct omap_hwmod omap2430_gpio1_hwmod = { 1743static struct omap_hwmod omap2430_gpio1_hwmod = {
1744 .name = "gpio1", 1744 .name = "gpio1",
1745 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1745 .mpu_irqs = omap243x_gpio1_irqs, 1746 .mpu_irqs = omap243x_gpio1_irqs,
1746 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs), 1747 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs),
1747 .main_clk = "gpios_fck", 1748 .main_clk = "gpios_fck",
@@ -1772,6 +1773,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = {
1772 1773
1773static struct omap_hwmod omap2430_gpio2_hwmod = { 1774static struct omap_hwmod omap2430_gpio2_hwmod = {
1774 .name = "gpio2", 1775 .name = "gpio2",
1776 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1775 .mpu_irqs = omap243x_gpio2_irqs, 1777 .mpu_irqs = omap243x_gpio2_irqs,
1776 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs), 1778 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs),
1777 .main_clk = "gpios_fck", 1779 .main_clk = "gpios_fck",
@@ -1802,6 +1804,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = {
1802 1804
1803static struct omap_hwmod omap2430_gpio3_hwmod = { 1805static struct omap_hwmod omap2430_gpio3_hwmod = {
1804 .name = "gpio3", 1806 .name = "gpio3",
1807 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1805 .mpu_irqs = omap243x_gpio3_irqs, 1808 .mpu_irqs = omap243x_gpio3_irqs,
1806 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs), 1809 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs),
1807 .main_clk = "gpios_fck", 1810 .main_clk = "gpios_fck",
@@ -1832,6 +1835,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = {
1832 1835
1833static struct omap_hwmod omap2430_gpio4_hwmod = { 1836static struct omap_hwmod omap2430_gpio4_hwmod = {
1834 .name = "gpio4", 1837 .name = "gpio4",
1838 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1835 .mpu_irqs = omap243x_gpio4_irqs, 1839 .mpu_irqs = omap243x_gpio4_irqs,
1836 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs), 1840 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs),
1837 .main_clk = "gpios_fck", 1841 .main_clk = "gpios_fck",
@@ -1862,6 +1866,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = {
1862 1866
1863static struct omap_hwmod omap2430_gpio5_hwmod = { 1867static struct omap_hwmod omap2430_gpio5_hwmod = {
1864 .name = "gpio5", 1868 .name = "gpio5",
1869 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
1865 .mpu_irqs = omap243x_gpio5_irqs, 1870 .mpu_irqs = omap243x_gpio5_irqs,
1866 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs), 1871 .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs),
1867 .main_clk = "gpio5_fck", 1872 .main_clk = "gpio5_fck",
@@ -1915,7 +1920,7 @@ static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = {
1915static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = { 1920static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = {
1916 { 1921 {
1917 .pa_start = 0x48056000, 1922 .pa_start = 0x48056000,
1918 .pa_end = 0x4a0560ff, 1923 .pa_end = 0x48056fff,
1919 .flags = ADDR_TYPE_RT 1924 .flags = ADDR_TYPE_RT
1920 }, 1925 },
1921}; 1926};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index b98e2dfcba28..909a84de6682 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -2141,6 +2141,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = {
2141 2141
2142static struct omap_hwmod omap3xxx_gpio1_hwmod = { 2142static struct omap_hwmod omap3xxx_gpio1_hwmod = {
2143 .name = "gpio1", 2143 .name = "gpio1",
2144 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2144 .mpu_irqs = omap3xxx_gpio1_irqs, 2145 .mpu_irqs = omap3xxx_gpio1_irqs,
2145 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs), 2146 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs),
2146 .main_clk = "gpio1_ick", 2147 .main_clk = "gpio1_ick",
@@ -2177,6 +2178,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = {
2177 2178
2178static struct omap_hwmod omap3xxx_gpio2_hwmod = { 2179static struct omap_hwmod omap3xxx_gpio2_hwmod = {
2179 .name = "gpio2", 2180 .name = "gpio2",
2181 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2180 .mpu_irqs = omap3xxx_gpio2_irqs, 2182 .mpu_irqs = omap3xxx_gpio2_irqs,
2181 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs), 2183 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs),
2182 .main_clk = "gpio2_ick", 2184 .main_clk = "gpio2_ick",
@@ -2213,6 +2215,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = {
2213 2215
2214static struct omap_hwmod omap3xxx_gpio3_hwmod = { 2216static struct omap_hwmod omap3xxx_gpio3_hwmod = {
2215 .name = "gpio3", 2217 .name = "gpio3",
2218 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2216 .mpu_irqs = omap3xxx_gpio3_irqs, 2219 .mpu_irqs = omap3xxx_gpio3_irqs,
2217 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs), 2220 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs),
2218 .main_clk = "gpio3_ick", 2221 .main_clk = "gpio3_ick",
@@ -2249,6 +2252,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = {
2249 2252
2250static struct omap_hwmod omap3xxx_gpio4_hwmod = { 2253static struct omap_hwmod omap3xxx_gpio4_hwmod = {
2251 .name = "gpio4", 2254 .name = "gpio4",
2255 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2252 .mpu_irqs = omap3xxx_gpio4_irqs, 2256 .mpu_irqs = omap3xxx_gpio4_irqs,
2253 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs), 2257 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs),
2254 .main_clk = "gpio4_ick", 2258 .main_clk = "gpio4_ick",
@@ -2285,6 +2289,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = {
2285 2289
2286static struct omap_hwmod omap3xxx_gpio5_hwmod = { 2290static struct omap_hwmod omap3xxx_gpio5_hwmod = {
2287 .name = "gpio5", 2291 .name = "gpio5",
2292 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2288 .mpu_irqs = omap3xxx_gpio5_irqs, 2293 .mpu_irqs = omap3xxx_gpio5_irqs,
2289 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs), 2294 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs),
2290 .main_clk = "gpio5_ick", 2295 .main_clk = "gpio5_ick",
@@ -2321,6 +2326,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = {
2321 2326
2322static struct omap_hwmod omap3xxx_gpio6_hwmod = { 2327static struct omap_hwmod omap3xxx_gpio6_hwmod = {
2323 .name = "gpio6", 2328 .name = "gpio6",
2329 .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
2324 .mpu_irqs = omap3xxx_gpio6_irqs, 2330 .mpu_irqs = omap3xxx_gpio6_irqs,
2325 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs), 2331 .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs),
2326 .main_clk = "gpio6_ick", 2332 .main_clk = "gpio6_ick",
@@ -2386,7 +2392,7 @@ static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = {
2386static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = { 2392static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
2387 { 2393 {
2388 .pa_start = 0x48056000, 2394 .pa_start = 0x48056000,
2389 .pa_end = 0x4a0560ff, 2395 .pa_end = 0x48056fff,
2390 .flags = ADDR_TYPE_RT 2396 .flags = ADDR_TYPE_RT
2391 }, 2397 },
2392}; 2398};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 3e88dd3f8ef3..abc548a0c98d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -885,7 +885,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = {
885static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = { 885static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = {
886 { 886 {
887 .pa_start = 0x4a056000, 887 .pa_start = 0x4a056000,
888 .pa_end = 0x4a0560ff, 888 .pa_end = 0x4a056fff,
889 .flags = ADDR_TYPE_RT 889 .flags = ADDR_TYPE_RT
890 }, 890 },
891}; 891};
diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c
index 5f2da7565b68..4321e7938929 100644
--- a/arch/arm/mach-omap2/omap_l3_smx.c
+++ b/arch/arm/mach-omap2/omap_l3_smx.c
@@ -196,11 +196,11 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
196 /* No timeout error for debug sources */ 196 /* No timeout error for debug sources */
197 } 197 }
198 198
199 base = ((l3->rt) + (*(omap3_l3_bases[int_type] + err_source)));
200
201 /* identify the error source */ 199 /* identify the error source */
202 for (err_source = 0; !(status & (1 << err_source)); err_source++) 200 for (err_source = 0; !(status & (1 << err_source)); err_source++)
203 ; 201 ;
202
203 base = l3->rt + *(omap3_l3_bases[int_type] + err_source);
204 error = omap3_l3_readll(base, L3_ERROR_LOG); 204 error = omap3_l3_readll(base, L3_ERROR_LOG);
205 205
206 if (error) { 206 if (error) {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 30af3351c2d6..49486f522dca 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -89,6 +89,7 @@ static void omap2_init_processor_devices(void)
89 if (cpu_is_omap44xx()) { 89 if (cpu_is_omap44xx()) {
90 _init_omap_device("l3_main_1", &l3_dev); 90 _init_omap_device("l3_main_1", &l3_dev);
91 _init_omap_device("dsp", &dsp_dev); 91 _init_omap_device("dsp", &dsp_dev);
92 _init_omap_device("iva", &iva_dev);
92 } else { 93 } else {
93 _init_omap_device("l3_main", &l3_dev); 94 _init_omap_device("l3_main", &l3_dev);
94 } 95 }
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 6fb520999b6e..0c1552d9d995 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -114,7 +114,6 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
114 sys_clk_speed /= 1000; 114 sys_clk_speed /= 1000;
115 115
116 /* Generic voltage parameters */ 116 /* Generic voltage parameters */
117 vdd->curr_volt = 1200000;
118 vdd->volt_scale = vp_forceupdate_scale_voltage; 117 vdd->volt_scale = vp_forceupdate_scale_voltage;
119 vdd->vp_enabled = false; 118 vdd->vp_enabled = false;
120 119
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 6de0ad0eea65..9cdcca597924 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -711,7 +711,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
711static struct regulator_init_data bq24022_init_data = { 711static struct regulator_init_data bq24022_init_data = {
712 .constraints = { 712 .constraints = {
713 .max_uA = 500000, 713 .max_uA = 500000,
714 .valid_ops_mask = REGULATOR_CHANGE_CURRENT, 714 .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS,
715 }, 715 },
716 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), 716 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
717 .consumer_supplies = bq24022_consumers, 717 .consumer_supplies = bq24022_consumers,
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index a72993dde2b3..9984ef70bd79 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -599,7 +599,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
599static struct regulator_init_data bq24022_init_data = { 599static struct regulator_init_data bq24022_init_data = {
600 .constraints = { 600 .constraints = {
601 .max_uA = 500000, 601 .max_uA = 500000,
602 .valid_ops_mask = REGULATOR_CHANGE_CURRENT, 602 .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
603 }, 603 },
604 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), 604 .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
605 .consumer_supplies = bq24022_consumers, 605 .consumer_supplies = bq24022_consumers,
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index ce233bcbf506..42af97664c9d 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -395,7 +395,7 @@ ENTRY(xscale_dma_a0_map_area)
395 teq r2, #DMA_TO_DEVICE 395 teq r2, #DMA_TO_DEVICE
396 beq xscale_dma_clean_range 396 beq xscale_dma_clean_range
397 b xscale_dma_flush_range 397 b xscale_dma_flush_range
398ENDPROC(xscsale_dma_a0_map_area) 398ENDPROC(xscale_dma_a0_map_area)
399 399
400/* 400/*
401 * dma_unmap_area(start, size, dir) 401 * dma_unmap_area(start, size, dir)
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 7a107246fd98..6cd6d7f686f6 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -295,6 +295,12 @@ static int mxc_gpio_direction_output(struct gpio_chip *chip,
295 return 0; 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 */
302static struct lock_class_key gpio_lock_class;
303
298int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) 304int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
299{ 305{
300 int i, j; 306 int i, j;
@@ -311,6 +317,7 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
311 __raw_writel(~0, port[i].base + GPIO_ISR); 317 __raw_writel(~0, port[i].base + GPIO_ISR);
312 for (j = port[i].virtual_irq_start; 318 for (j = port[i].virtual_irq_start;
313 j < port[i].virtual_irq_start + 32; j++) { 319 j < port[i].virtual_irq_start + 32; j++) {
320 irq_set_lockdep_class(j, &gpio_lock_class);
314 irq_set_chip_and_handler(j, &gpio_irq_chip, 321 irq_set_chip_and_handler(j, &gpio_irq_chip,
315 handle_level_irq); 322 handle_level_irq);
316 set_irq_flags(j, IRQF_VALID); 323 set_irq_flags(j, IRQF_VALID);
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
index 4ddce565b353..8397a2dd19f2 100644
--- a/arch/arm/plat-mxc/ssi-fiq.S
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -124,6 +124,8 @@ imx_ssi_fiq_start:
1241: 1241:
125 @ return from FIQ 125 @ return from FIQ
126 subs pc, lr, #4 126 subs pc, lr, #4
127
128 .align
127imx_ssi_fiq_base: 129imx_ssi_fiq_base:
128 .word 0x0 130 .word 0x0
129imx_ssi_fiq_rx_buffer: 131imx_ssi_fiq_rx_buffer:
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 02b7a03e4226..8b3db1c587fc 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -300,6 +300,8 @@ void __init paging_init(void)
300 zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT; 300 zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
301 free_area_init_node(i, zones_size, 301 free_area_init_node(i, zones_size,
302 m68k_memory[i].addr >> PAGE_SHIFT, NULL); 302 m68k_memory[i].addr >> PAGE_SHIFT, NULL);
303 if (node_present_pages(i))
304 node_set_state(i, N_NORMAL_MEMORY);
303 } 305 }
304} 306}
305 307
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index b7ed8d7a9b33..b1d126258dee 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -266,8 +266,10 @@ static void __init setup_bootmem(void)
266 } 266 }
267 memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); 267 memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
268 268
269 for (i = 0; i < npmem_ranges; i++) 269 for (i = 0; i < npmem_ranges; i++) {
270 node_set_state(i, N_NORMAL_MEMORY);
270 node_set_online(i); 271 node_set_online(i);
272 }
271#endif 273#endif
272 274
273 /* 275 /*
diff --git a/arch/powerpc/include/asm/8xx_immap.h b/arch/powerpc/include/asm/8xx_immap.h
index 6b6dc20b0beb..bdf0563ba423 100644
--- a/arch/powerpc/include/asm/8xx_immap.h
+++ b/arch/powerpc/include/asm/8xx_immap.h
@@ -393,8 +393,8 @@ typedef struct fec {
393 uint fec_addr_low; /* lower 32 bits of station address */ 393 uint fec_addr_low; /* lower 32 bits of station address */
394 ushort fec_addr_high; /* upper 16 bits of station address */ 394 ushort fec_addr_high; /* upper 16 bits of station address */
395 ushort res1; /* reserved */ 395 ushort res1; /* reserved */
396 uint fec_hash_table_high; /* upper 32-bits of hash table */ 396 uint fec_grp_hash_table_high; /* upper 32-bits of hash table */
397 uint fec_hash_table_low; /* lower 32-bits of hash table */ 397 uint fec_grp_hash_table_low; /* lower 32-bits of hash table */
398 uint fec_r_des_start; /* beginning of Rx descriptor ring */ 398 uint fec_r_des_start; /* beginning of Rx descriptor ring */
399 uint fec_x_des_start; /* beginning of Tx descriptor ring */ 399 uint fec_x_des_start; /* beginning of Tx descriptor ring */
400 uint fec_r_buff_size; /* Rx buffer size */ 400 uint fec_r_buff_size; /* Rx buffer size */
diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h
index ae9c899c8a6d..d12b11d7641e 100644
--- a/arch/powerpc/include/asm/uninorth.h
+++ b/arch/powerpc/include/asm/uninorth.h
@@ -60,7 +60,7 @@
60 * 60 *
61 * Obviously, the GART is not cache coherent and so any change to it 61 * Obviously, the GART is not cache coherent and so any change to it
62 * must be flushed to memory (or maybe just make the GART space non 62 * must be flushed to memory (or maybe just make the GART space non
63 * cachable). AGP memory itself does't seem to be cache coherent neither. 63 * cachable). AGP memory itself doesn't seem to be cache coherent neither.
64 * 64 *
65 * In order to invalidate the GART (which is probably necessary to inval 65 * In order to invalidate the GART (which is probably necessary to inval
66 * the bridge internal TLBs), the following sequence has to be written, 66 * the bridge internal TLBs), the following sequence has to be written,
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 55613e33e263..a6ae1cfad86c 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -933,12 +933,16 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
933 if (data && !(data & DABR_TRANSLATION)) 933 if (data && !(data & DABR_TRANSLATION))
934 return -EIO; 934 return -EIO;
935#ifdef CONFIG_HAVE_HW_BREAKPOINT 935#ifdef CONFIG_HAVE_HW_BREAKPOINT
936 if (ptrace_get_breakpoints(task) < 0)
937 return -ESRCH;
938
936 bp = thread->ptrace_bps[0]; 939 bp = thread->ptrace_bps[0];
937 if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { 940 if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
938 if (bp) { 941 if (bp) {
939 unregister_hw_breakpoint(bp); 942 unregister_hw_breakpoint(bp);
940 thread->ptrace_bps[0] = NULL; 943 thread->ptrace_bps[0] = NULL;
941 } 944 }
945 ptrace_put_breakpoints(task);
942 return 0; 946 return 0;
943 } 947 }
944 if (bp) { 948 if (bp) {
@@ -948,9 +952,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
948 (DABR_DATA_WRITE | DABR_DATA_READ), 952 (DABR_DATA_WRITE | DABR_DATA_READ),
949 &attr.bp_type); 953 &attr.bp_type);
950 ret = modify_user_hw_breakpoint(bp, &attr); 954 ret = modify_user_hw_breakpoint(bp, &attr);
951 if (ret) 955 if (ret) {
956 ptrace_put_breakpoints(task);
952 return ret; 957 return ret;
958 }
953 thread->ptrace_bps[0] = bp; 959 thread->ptrace_bps[0] = bp;
960 ptrace_put_breakpoints(task);
954 thread->dabr = data; 961 thread->dabr = data;
955 return 0; 962 return 0;
956 } 963 }
@@ -965,9 +972,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
965 ptrace_triggered, task); 972 ptrace_triggered, task);
966 if (IS_ERR(bp)) { 973 if (IS_ERR(bp)) {
967 thread->ptrace_bps[0] = NULL; 974 thread->ptrace_bps[0] = NULL;
975 ptrace_put_breakpoints(task);
968 return PTR_ERR(bp); 976 return PTR_ERR(bp);
969 } 977 }
970 978
979 ptrace_put_breakpoints(task);
980
971#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 981#endif /* CONFIG_HAVE_HW_BREAKPOINT */
972 982
973 /* Move contents to the DABR register */ 983 /* Move contents to the DABR register */
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index 975e3ab13cb5..8b16c479585b 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -76,7 +76,7 @@ static void prng_seed(int nbytes)
76 76
77 /* Add the entropy */ 77 /* Add the entropy */
78 while (nbytes >= 8) { 78 while (nbytes >= 8) {
79 *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8); 79 *((__u64 *)parm_block) ^= *((__u64 *)(buf+i));
80 prng_add_entropy(); 80 prng_add_entropy();
81 i += 8; 81 i += 8;
82 nbytes -= 8; 82 nbytes -= 8;
diff --git a/arch/s390/kvm/sie64a.S b/arch/s390/kvm/sie64a.S
index 7e9d30d567b0..ab0e041ac54c 100644
--- a/arch/s390/kvm/sie64a.S
+++ b/arch/s390/kvm/sie64a.S
@@ -48,10 +48,10 @@ sie_irq_handler:
48 tm __TI_flags+7(%r2),_TIF_EXIT_SIE 48 tm __TI_flags+7(%r2),_TIF_EXIT_SIE
49 jz 0f 49 jz 0f
50 larl %r2,sie_exit # work pending, leave sie 50 larl %r2,sie_exit # work pending, leave sie
51 stg %r2,__LC_RETURN_PSW+8 51 stg %r2,SPI_PSW+8(0,%r15)
52 br %r14 52 br %r14
530: larl %r2,sie_reenter # re-enter with guest id 530: larl %r2,sie_reenter # re-enter with guest id
54 stg %r2,__LC_RETURN_PSW+8 54 stg %r2,SPI_PSW+8(0,%r15)
551: br %r14 551: br %r14
56 56
57/* 57/*
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 9217e332b118..ab988135e5c6 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -543,7 +543,6 @@ static void pfault_interrupt(unsigned int ext_int_code,
543 struct task_struct *tsk; 543 struct task_struct *tsk;
544 __u16 subcode; 544 __u16 subcode;
545 545
546 kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
547 /* 546 /*
548 * Get the external interruption subcode & pfault 547 * Get the external interruption subcode & pfault
549 * initial/completion signal bit. VM stores this 548 * initial/completion signal bit. VM stores this
@@ -553,14 +552,15 @@ static void pfault_interrupt(unsigned int ext_int_code,
553 subcode = ext_int_code >> 16; 552 subcode = ext_int_code >> 16;
554 if ((subcode & 0xff00) != __SUBCODE_MASK) 553 if ((subcode & 0xff00) != __SUBCODE_MASK)
555 return; 554 return;
555 kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
556 556
557 /* 557 /*
558 * Get the token (= address of the task structure of the affected task). 558 * Get the token (= address of the task structure of the affected task).
559 */ 559 */
560#ifdef CONFIG_64BIT 560#ifdef CONFIG_64BIT
561 tsk = *(struct task_struct **) param64; 561 tsk = (struct task_struct *) param64;
562#else 562#else
563 tsk = *(struct task_struct **) param32; 563 tsk = (struct task_struct *) param32;
564#endif 564#endif
565 565
566 if (subcode & 0x0080) { 566 if (subcode & 0x0080) {
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 122ffbd08ce0..0607e4b14b27 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -24,12 +24,13 @@ static void change_page_attr(unsigned long addr, int numpages,
24 WARN_ON_ONCE(1); 24 WARN_ON_ONCE(1);
25 continue; 25 continue;
26 } 26 }
27 ptep = pte_offset_kernel(pmdp, addr + i * PAGE_SIZE); 27 ptep = pte_offset_kernel(pmdp, addr);
28 28
29 pte = *ptep; 29 pte = *ptep;
30 pte = set(pte); 30 pte = set(pte);
31 ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep); 31 ptep_invalidate(&init_mm, addr, ptep);
32 *ptep = pte; 32 *ptep = pte;
33 addr += PAGE_SIZE;
33 } 34 }
34} 35}
35 36
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 2130ca674e9b..3d7b209b2178 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -117,7 +117,11 @@ void user_enable_single_step(struct task_struct *child)
117 117
118 set_tsk_thread_flag(child, TIF_SINGLESTEP); 118 set_tsk_thread_flag(child, TIF_SINGLESTEP);
119 119
120 if (ptrace_get_breakpoints(child) < 0)
121 return;
122
120 set_single_step(child, pc); 123 set_single_step(child, pc);
124 ptrace_put_breakpoints(child);
121} 125}
122 126
123void user_disable_single_step(struct task_struct *child) 127void user_disable_single_step(struct task_struct *child)
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 90a438acbfaf..b5e675e370c6 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -47,7 +47,7 @@ config HOSTFS
47 47
48config HPPFS 48config HPPFS
49 tristate "HoneyPot ProcFS (EXPERIMENTAL)" 49 tristate "HoneyPot ProcFS (EXPERIMENTAL)"
50 depends on EXPERIMENTAL 50 depends on EXPERIMENTAL && PROC_FS
51 help 51 help
52 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 52 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
53 entries to be overridden, removed, or fabricated from the host. 53 entries to be overridden, removed, or fabricated from the host.
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index e2cf786bda0a..5bd1bad33fab 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -49,7 +49,10 @@ static inline struct thread_info *current_thread_info(void)
49{ 49{
50 struct thread_info *ti; 50 struct thread_info *ti;
51 unsigned long mask = THREAD_SIZE - 1; 51 unsigned long mask = THREAD_SIZE - 1;
52 ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); 52 void *p;
53
54 asm volatile ("" : "=r" (p) : "0" (&ti));
55 ti = (struct thread_info *) (((unsigned long)p) & ~mask);
53 return ti; 56 return ti;
54} 57}
55 58
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 804b28dd0328..b1da91c1b200 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 5obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
7 sys_call_table.o tls.o 7 sys_call_table.o tls.o atomic64_cx8_32.o
8 8
9obj-$(CONFIG_BINFMT_ELF) += elfcore.o 9obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10 10
diff --git a/arch/um/sys-i386/atomic64_cx8_32.S b/arch/um/sys-i386/atomic64_cx8_32.S
new file mode 100644
index 000000000000..1e901d3d4a95
--- /dev/null
+++ b/arch/um/sys-i386/atomic64_cx8_32.S
@@ -0,0 +1,225 @@
1/*
2 * atomic64_t for 586+
3 *
4 * Copied from arch/x86/lib/atomic64_cx8_32.S
5 *
6 * Copyright © 2010 Luca Barbieri
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <linux/linkage.h>
16#include <asm/alternative-asm.h>
17#include <asm/dwarf2.h>
18
19.macro SAVE reg
20 pushl_cfi %\reg
21 CFI_REL_OFFSET \reg, 0
22.endm
23
24.macro RESTORE reg
25 popl_cfi %\reg
26 CFI_RESTORE \reg
27.endm
28
29.macro read64 reg
30 movl %ebx, %eax
31 movl %ecx, %edx
32/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
33 LOCK_PREFIX
34 cmpxchg8b (\reg)
35.endm
36
37ENTRY(atomic64_read_cx8)
38 CFI_STARTPROC
39
40 read64 %ecx
41 ret
42 CFI_ENDPROC
43ENDPROC(atomic64_read_cx8)
44
45ENTRY(atomic64_set_cx8)
46 CFI_STARTPROC
47
481:
49/* we don't need LOCK_PREFIX since aligned 64-bit writes
50 * are atomic on 586 and newer */
51 cmpxchg8b (%esi)
52 jne 1b
53
54 ret
55 CFI_ENDPROC
56ENDPROC(atomic64_set_cx8)
57
58ENTRY(atomic64_xchg_cx8)
59 CFI_STARTPROC
60
61 movl %ebx, %eax
62 movl %ecx, %edx
631:
64 LOCK_PREFIX
65 cmpxchg8b (%esi)
66 jne 1b
67
68 ret
69 CFI_ENDPROC
70ENDPROC(atomic64_xchg_cx8)
71
72.macro addsub_return func ins insc
73ENTRY(atomic64_\func\()_return_cx8)
74 CFI_STARTPROC
75 SAVE ebp
76 SAVE ebx
77 SAVE esi
78 SAVE edi
79
80 movl %eax, %esi
81 movl %edx, %edi
82 movl %ecx, %ebp
83
84 read64 %ebp
851:
86 movl %eax, %ebx
87 movl %edx, %ecx
88 \ins\()l %esi, %ebx
89 \insc\()l %edi, %ecx
90 LOCK_PREFIX
91 cmpxchg8b (%ebp)
92 jne 1b
93
9410:
95 movl %ebx, %eax
96 movl %ecx, %edx
97 RESTORE edi
98 RESTORE esi
99 RESTORE ebx
100 RESTORE ebp
101 ret
102 CFI_ENDPROC
103ENDPROC(atomic64_\func\()_return_cx8)
104.endm
105
106addsub_return add add adc
107addsub_return sub sub sbb
108
109.macro incdec_return func ins insc
110ENTRY(atomic64_\func\()_return_cx8)
111 CFI_STARTPROC
112 SAVE ebx
113
114 read64 %esi
1151:
116 movl %eax, %ebx
117 movl %edx, %ecx
118 \ins\()l $1, %ebx
119 \insc\()l $0, %ecx
120 LOCK_PREFIX
121 cmpxchg8b (%esi)
122 jne 1b
123
12410:
125 movl %ebx, %eax
126 movl %ecx, %edx
127 RESTORE ebx
128 ret
129 CFI_ENDPROC
130ENDPROC(atomic64_\func\()_return_cx8)
131.endm
132
133incdec_return inc add adc
134incdec_return dec sub sbb
135
136ENTRY(atomic64_dec_if_positive_cx8)
137 CFI_STARTPROC
138 SAVE ebx
139
140 read64 %esi
1411:
142 movl %eax, %ebx
143 movl %edx, %ecx
144 subl $1, %ebx
145 sbb $0, %ecx
146 js 2f
147 LOCK_PREFIX
148 cmpxchg8b (%esi)
149 jne 1b
150
1512:
152 movl %ebx, %eax
153 movl %ecx, %edx
154 RESTORE ebx
155 ret
156 CFI_ENDPROC
157ENDPROC(atomic64_dec_if_positive_cx8)
158
159ENTRY(atomic64_add_unless_cx8)
160 CFI_STARTPROC
161 SAVE ebp
162 SAVE ebx
163/* these just push these two parameters on the stack */
164 SAVE edi
165 SAVE esi
166
167 movl %ecx, %ebp
168 movl %eax, %esi
169 movl %edx, %edi
170
171 read64 %ebp
1721:
173 cmpl %eax, 0(%esp)
174 je 4f
1752:
176 movl %eax, %ebx
177 movl %edx, %ecx
178 addl %esi, %ebx
179 adcl %edi, %ecx
180 LOCK_PREFIX
181 cmpxchg8b (%ebp)
182 jne 1b
183
184 movl $1, %eax
1853:
186 addl $8, %esp
187 CFI_ADJUST_CFA_OFFSET -8
188 RESTORE ebx
189 RESTORE ebp
190 ret
1914:
192 cmpl %edx, 4(%esp)
193 jne 2b
194 xorl %eax, %eax
195 jmp 3b
196 CFI_ENDPROC
197ENDPROC(atomic64_add_unless_cx8)
198
199ENTRY(atomic64_inc_not_zero_cx8)
200 CFI_STARTPROC
201 SAVE ebx
202
203 read64 %esi
2041:
205 testl %eax, %eax
206 je 4f
2072:
208 movl %eax, %ebx
209 movl %edx, %ecx
210 addl $1, %ebx
211 adcl $0, %ecx
212 LOCK_PREFIX
213 cmpxchg8b (%esi)
214 jne 1b
215
216 movl $1, %eax
2173:
218 RESTORE ebx
219 ret
2204:
221 testl %edx, %edx
222 jne 2b
223 jmp 3b
224 CFI_ENDPROC
225ENDPROC(atomic64_inc_not_zero_cx8)
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index cae3feb1035e..db75d07c3645 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -91,7 +91,7 @@ static int detect_memory_e801(void)
91 if (oreg.ax > 15*1024) { 91 if (oreg.ax > 15*1024) {
92 return -1; /* Bogus! */ 92 return -1; /* Bogus! */
93 } else if (oreg.ax == 15*1024) { 93 } else if (oreg.ax == 15*1024) {
94 boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax; 94 boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax;
95 } else { 95 } else {
96 /* 96 /*
97 * This ignores memory above 16MB if we have a memory 97 * This ignores memory above 16MB if we have a memory
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index c4bd267dfc50..a97a240f67f3 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -150,7 +150,7 @@ void setup_IO_APIC_irq_extra(u32 gsi);
150extern void ioapic_and_gsi_init(void); 150extern void ioapic_and_gsi_init(void);
151extern void ioapic_insert_resources(void); 151extern void ioapic_insert_resources(void);
152 152
153int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr); 153int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
154 154
155extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); 155extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
156extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); 156extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 68df09bba92e..45fd33d1fd3a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -128,8 +128,8 @@ static int __init parse_noapic(char *str)
128} 128}
129early_param("noapic", parse_noapic); 129early_param("noapic", parse_noapic);
130 130
131static int io_apic_setup_irq_pin_once(unsigned int irq, int node, 131static int io_apic_setup_irq_pin(unsigned int irq, int node,
132 struct io_apic_irq_attr *attr); 132 struct io_apic_irq_attr *attr);
133 133
134/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ 134/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
135void mp_save_irq(struct mpc_intsrc *m) 135void mp_save_irq(struct mpc_intsrc *m)
@@ -3570,7 +3570,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
3570} 3570}
3571#endif /* CONFIG_HT_IRQ */ 3571#endif /* CONFIG_HT_IRQ */
3572 3572
3573int 3573static int
3574io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) 3574io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
3575{ 3575{
3576 struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); 3576 struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node);
@@ -3585,8 +3585,8 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
3585 return ret; 3585 return ret;
3586} 3586}
3587 3587
3588static int io_apic_setup_irq_pin_once(unsigned int irq, int node, 3588int io_apic_setup_irq_pin_once(unsigned int irq, int node,
3589 struct io_apic_irq_attr *attr) 3589 struct io_apic_irq_attr *attr)
3590{ 3590{
3591 unsigned int id = attr->ioapic, pin = attr->ioapic_pin; 3591 unsigned int id = attr->ioapic, pin = attr->ioapic_pin;
3592 int ret; 3592 int ret;
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 3532d3bf8105..bb9eb29a52dd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -698,7 +698,7 @@ cpu_dev_register(amd_cpu_dev);
698 */ 698 */
699 699
700const int amd_erratum_400[] = 700const int amd_erratum_400[] =
701 AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), 701 AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0x0f, 0x4, 0x2, 0xff, 0xf),
702 AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); 702 AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
703EXPORT_SYMBOL_GPL(amd_erratum_400); 703EXPORT_SYMBOL_GPL(amd_erratum_400);
704 704
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 61cbf4831d71..41178c826c48 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -184,26 +184,23 @@ static __initconst const u64 snb_hw_cache_event_ids
184 }, 184 },
185 }, 185 },
186 [ C(LL ) ] = { 186 [ C(LL ) ] = {
187 /*
188 * TBD: Need Off-core Response Performance Monitoring support
189 */
190 [ C(OP_READ) ] = { 187 [ C(OP_READ) ] = {
191 /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ 188 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
192 [ C(RESULT_ACCESS) ] = 0x01b7, 189 [ C(RESULT_ACCESS) ] = 0x01b7,
193 /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ 190 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
194 [ C(RESULT_MISS) ] = 0x01bb, 191 [ C(RESULT_MISS) ] = 0x01b7,
195 }, 192 },
196 [ C(OP_WRITE) ] = { 193 [ C(OP_WRITE) ] = {
197 /* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ 194 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
198 [ C(RESULT_ACCESS) ] = 0x01b7, 195 [ C(RESULT_ACCESS) ] = 0x01b7,
199 /* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ 196 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
200 [ C(RESULT_MISS) ] = 0x01bb, 197 [ C(RESULT_MISS) ] = 0x01b7,
201 }, 198 },
202 [ C(OP_PREFETCH) ] = { 199 [ C(OP_PREFETCH) ] = {
203 /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ 200 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
204 [ C(RESULT_ACCESS) ] = 0x01b7, 201 [ C(RESULT_ACCESS) ] = 0x01b7,
205 /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ 202 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
206 [ C(RESULT_MISS) ] = 0x01bb, 203 [ C(RESULT_MISS) ] = 0x01b7,
207 }, 204 },
208 }, 205 },
209 [ C(DTLB) ] = { 206 [ C(DTLB) ] = {
@@ -285,26 +282,26 @@ static __initconst const u64 westmere_hw_cache_event_ids
285 }, 282 },
286 [ C(LL ) ] = { 283 [ C(LL ) ] = {
287 [ C(OP_READ) ] = { 284 [ C(OP_READ) ] = {
288 /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ 285 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
289 [ C(RESULT_ACCESS) ] = 0x01b7, 286 [ C(RESULT_ACCESS) ] = 0x01b7,
290 /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ 287 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
291 [ C(RESULT_MISS) ] = 0x01bb, 288 [ C(RESULT_MISS) ] = 0x01b7,
292 }, 289 },
293 /* 290 /*
294 * Use RFO, not WRITEBACK, because a write miss would typically occur 291 * Use RFO, not WRITEBACK, because a write miss would typically occur
295 * on RFO. 292 * on RFO.
296 */ 293 */
297 [ C(OP_WRITE) ] = { 294 [ C(OP_WRITE) ] = {
298 /* OFFCORE_RESPONSE_1.ANY_RFO.LOCAL_CACHE */ 295 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
299 [ C(RESULT_ACCESS) ] = 0x01bb, 296 [ C(RESULT_ACCESS) ] = 0x01b7,
300 /* OFFCORE_RESPONSE_0.ANY_RFO.ANY_LLC_MISS */ 297 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
301 [ C(RESULT_MISS) ] = 0x01b7, 298 [ C(RESULT_MISS) ] = 0x01b7,
302 }, 299 },
303 [ C(OP_PREFETCH) ] = { 300 [ C(OP_PREFETCH) ] = {
304 /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ 301 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
305 [ C(RESULT_ACCESS) ] = 0x01b7, 302 [ C(RESULT_ACCESS) ] = 0x01b7,
306 /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ 303 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
307 [ C(RESULT_MISS) ] = 0x01bb, 304 [ C(RESULT_MISS) ] = 0x01b7,
308 }, 305 },
309 }, 306 },
310 [ C(DTLB) ] = { 307 [ C(DTLB) ] = {
@@ -352,16 +349,36 @@ static __initconst const u64 westmere_hw_cache_event_ids
352}; 349};
353 350
354/* 351/*
355 * OFFCORE_RESPONSE MSR bits (subset), See IA32 SDM Vol 3 30.6.1.3 352 * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
353 * See IA32 SDM Vol 3B 30.6.1.3
356 */ 354 */
357 355
358#define DMND_DATA_RD (1 << 0) 356#define NHM_DMND_DATA_RD (1 << 0)
359#define DMND_RFO (1 << 1) 357#define NHM_DMND_RFO (1 << 1)
360#define DMND_WB (1 << 3) 358#define NHM_DMND_IFETCH (1 << 2)
361#define PF_DATA_RD (1 << 4) 359#define NHM_DMND_WB (1 << 3)
362#define PF_DATA_RFO (1 << 5) 360#define NHM_PF_DATA_RD (1 << 4)
363#define RESP_UNCORE_HIT (1 << 8) 361#define NHM_PF_DATA_RFO (1 << 5)
364#define RESP_MISS (0xf600) /* non uncore hit */ 362#define NHM_PF_IFETCH (1 << 6)
363#define NHM_OFFCORE_OTHER (1 << 7)
364#define NHM_UNCORE_HIT (1 << 8)
365#define NHM_OTHER_CORE_HIT_SNP (1 << 9)
366#define NHM_OTHER_CORE_HITM (1 << 10)
367 /* reserved */
368#define NHM_REMOTE_CACHE_FWD (1 << 12)
369#define NHM_REMOTE_DRAM (1 << 13)
370#define NHM_LOCAL_DRAM (1 << 14)
371#define NHM_NON_DRAM (1 << 15)
372
373#define NHM_ALL_DRAM (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM)
374
375#define NHM_DMND_READ (NHM_DMND_DATA_RD)
376#define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB)
377#define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
378
379#define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
380#define NHM_L3_MISS (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD)
381#define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS)
365 382
366static __initconst const u64 nehalem_hw_cache_extra_regs 383static __initconst const u64 nehalem_hw_cache_extra_regs
367 [PERF_COUNT_HW_CACHE_MAX] 384 [PERF_COUNT_HW_CACHE_MAX]
@@ -370,16 +387,16 @@ static __initconst const u64 nehalem_hw_cache_extra_regs
370{ 387{
371 [ C(LL ) ] = { 388 [ C(LL ) ] = {
372 [ C(OP_READ) ] = { 389 [ C(OP_READ) ] = {
373 [ C(RESULT_ACCESS) ] = DMND_DATA_RD|RESP_UNCORE_HIT, 390 [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
374 [ C(RESULT_MISS) ] = DMND_DATA_RD|RESP_MISS, 391 [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS,
375 }, 392 },
376 [ C(OP_WRITE) ] = { 393 [ C(OP_WRITE) ] = {
377 [ C(RESULT_ACCESS) ] = DMND_RFO|DMND_WB|RESP_UNCORE_HIT, 394 [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
378 [ C(RESULT_MISS) ] = DMND_RFO|DMND_WB|RESP_MISS, 395 [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS,
379 }, 396 },
380 [ C(OP_PREFETCH) ] = { 397 [ C(OP_PREFETCH) ] = {
381 [ C(RESULT_ACCESS) ] = PF_DATA_RD|PF_DATA_RFO|RESP_UNCORE_HIT, 398 [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
382 [ C(RESULT_MISS) ] = PF_DATA_RD|PF_DATA_RFO|RESP_MISS, 399 [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
383 }, 400 },
384 } 401 }
385}; 402};
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 706a9fb46a58..e90f08458e6b 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -391,7 +391,7 @@ static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
391 391
392 set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); 392 set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
393 393
394 return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr); 394 return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr);
395} 395}
396 396
397static void __init ioapic_add_ofnode(struct device_node *np) 397static void __init ioapic_add_ofnode(struct device_node *np)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 45892dc4b72a..f65e5b521dbd 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -608,6 +608,9 @@ static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
608 unsigned len, type; 608 unsigned len, type;
609 struct perf_event *bp; 609 struct perf_event *bp;
610 610
611 if (ptrace_get_breakpoints(tsk) < 0)
612 return -ESRCH;
613
611 data &= ~DR_CONTROL_RESERVED; 614 data &= ~DR_CONTROL_RESERVED;
612 old_dr7 = ptrace_get_dr7(thread->ptrace_bps); 615 old_dr7 = ptrace_get_dr7(thread->ptrace_bps);
613restore: 616restore:
@@ -655,6 +658,9 @@ restore:
655 } 658 }
656 goto restore; 659 goto restore;
657 } 660 }
661
662 ptrace_put_breakpoints(tsk);
663
658 return ((orig_ret < 0) ? orig_ret : rc); 664 return ((orig_ret < 0) ? orig_ret : rc);
659} 665}
660 666
@@ -668,10 +674,17 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
668 674
669 if (n < HBP_NUM) { 675 if (n < HBP_NUM) {
670 struct perf_event *bp; 676 struct perf_event *bp;
677
678 if (ptrace_get_breakpoints(tsk) < 0)
679 return -ESRCH;
680
671 bp = thread->ptrace_bps[n]; 681 bp = thread->ptrace_bps[n];
672 if (!bp) 682 if (!bp)
673 return 0; 683 val = 0;
674 val = bp->hw.info.address; 684 else
685 val = bp->hw.info.address;
686
687 ptrace_put_breakpoints(tsk);
675 } else if (n == 6) { 688 } else if (n == 6) {
676 val = thread->debugreg6; 689 val = thread->debugreg6;
677 } else if (n == 7) { 690 } else if (n == 7) {
@@ -686,6 +699,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
686 struct perf_event *bp; 699 struct perf_event *bp;
687 struct thread_struct *t = &tsk->thread; 700 struct thread_struct *t = &tsk->thread;
688 struct perf_event_attr attr; 701 struct perf_event_attr attr;
702 int err = 0;
703
704 if (ptrace_get_breakpoints(tsk) < 0)
705 return -ESRCH;
689 706
690 if (!t->ptrace_bps[nr]) { 707 if (!t->ptrace_bps[nr]) {
691 ptrace_breakpoint_init(&attr); 708 ptrace_breakpoint_init(&attr);
@@ -709,24 +726,23 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
709 * writing for the user. And anyway this is the previous 726 * writing for the user. And anyway this is the previous
710 * behaviour. 727 * behaviour.
711 */ 728 */
712 if (IS_ERR(bp)) 729 if (IS_ERR(bp)) {
713 return PTR_ERR(bp); 730 err = PTR_ERR(bp);
731 goto put;
732 }
714 733
715 t->ptrace_bps[nr] = bp; 734 t->ptrace_bps[nr] = bp;
716 } else { 735 } else {
717 int err;
718
719 bp = t->ptrace_bps[nr]; 736 bp = t->ptrace_bps[nr];
720 737
721 attr = bp->attr; 738 attr = bp->attr;
722 attr.bp_addr = addr; 739 attr.bp_addr = addr;
723 err = modify_user_hw_breakpoint(bp, &attr); 740 err = modify_user_hw_breakpoint(bp, &attr);
724 if (err)
725 return err;
726 } 741 }
727 742
728 743put:
729 return 0; 744 ptrace_put_breakpoints(tsk);
745 return err;
730} 746}
731 747
732/* 748/*
diff --git a/arch/x86/kernel/reboot_32.S b/arch/x86/kernel/reboot_32.S
index 29092b38d816..1d5c46df0d78 100644
--- a/arch/x86/kernel/reboot_32.S
+++ b/arch/x86/kernel/reboot_32.S
@@ -21,26 +21,26 @@ r_base = .
21 /* Get our own relocated address */ 21 /* Get our own relocated address */
22 call 1f 22 call 1f
231: popl %ebx 231: popl %ebx
24 subl $1b, %ebx 24 subl $(1b - r_base), %ebx
25 25
26 /* Compute the equivalent real-mode segment */ 26 /* Compute the equivalent real-mode segment */
27 movl %ebx, %ecx 27 movl %ebx, %ecx
28 shrl $4, %ecx 28 shrl $4, %ecx
29 29
30 /* Patch post-real-mode segment jump */ 30 /* Patch post-real-mode segment jump */
31 movw dispatch_table(%ebx,%eax,2),%ax 31 movw (dispatch_table - r_base)(%ebx,%eax,2),%ax
32 movw %ax, 101f(%ebx) 32 movw %ax, (101f - r_base)(%ebx)
33 movw %cx, 102f(%ebx) 33 movw %cx, (102f - r_base)(%ebx)
34 34
35 /* Set up the IDT for real mode. */ 35 /* Set up the IDT for real mode. */
36 lidtl machine_real_restart_idt(%ebx) 36 lidtl (machine_real_restart_idt - r_base)(%ebx)
37 37
38 /* 38 /*
39 * Set up a GDT from which we can load segment descriptors for real 39 * Set up a GDT from which we can load segment descriptors for real
40 * mode. The GDT is not used in real mode; it is just needed here to 40 * mode. The GDT is not used in real mode; it is just needed here to
41 * prepare the descriptors. 41 * prepare the descriptors.
42 */ 42 */
43 lgdtl machine_real_restart_gdt(%ebx) 43 lgdtl (machine_real_restart_gdt - r_base)(%ebx)
44 44
45 /* 45 /*
46 * Load the data segment registers with 16-bit compatible values 46 * Load the data segment registers with 16-bit compatible values
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index e8c00cc72033..85b52fc03084 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -306,7 +306,7 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
306 bi->end = min(bi->end, high); 306 bi->end = min(bi->end, high);
307 307
308 /* and there's no empty block */ 308 /* and there's no empty block */
309 if (bi->start == bi->end) { 309 if (bi->start >= bi->end) {
310 numa_remove_memblk_from(i--, mi); 310 numa_remove_memblk_from(i--, mi);
311 continue; 311 continue;
312 } 312 }
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
index 2d6d226f2b10..e70be38ce039 100644
--- a/arch/x86/platform/ce4100/falconfalls.dts
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -347,7 +347,7 @@
347 "pciclass0c03"; 347 "pciclass0c03";
348 348
349 reg = <0x16800 0x0 0x0 0x0 0x0>; 349 reg = <0x16800 0x0 0x0 0x0 0x0>;
350 interrupts = <22 3>; 350 interrupts = <22 1>;
351 }; 351 };
352 352
353 usb@d,1 { 353 usb@d,1 {
@@ -357,7 +357,7 @@
357 "pciclass0c03"; 357 "pciclass0c03";
358 358
359 reg = <0x16900 0x0 0x0 0x0 0x0>; 359 reg = <0x16900 0x0 0x0 0x0 0x0>;
360 interrupts = <22 3>; 360 interrupts = <22 1>;
361 }; 361 };
362 362
363 sata@e,0 { 363 sata@e,0 {
@@ -367,7 +367,7 @@
367 "pciclass0106"; 367 "pciclass0106";
368 368
369 reg = <0x17000 0x0 0x0 0x0 0x0>; 369 reg = <0x17000 0x0 0x0 0x0 0x0>;
370 interrupts = <23 3>; 370 interrupts = <23 1>;
371 }; 371 };
372 372
373 flash@f,0 { 373 flash@f,0 {
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index aef7af92b28b..55c965b38c27 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1463,6 +1463,119 @@ static int xen_pgd_alloc(struct mm_struct *mm)
1463 return ret; 1463 return ret;
1464} 1464}
1465 1465
1466#ifdef CONFIG_X86_64
1467static __initdata u64 __last_pgt_set_rw = 0;
1468static __initdata u64 __pgt_buf_start = 0;
1469static __initdata u64 __pgt_buf_end = 0;
1470static __initdata u64 __pgt_buf_top = 0;
1471/*
1472 * As a consequence of the commit:
1473 *
1474 * commit 4b239f458c229de044d6905c2b0f9fe16ed9e01e
1475 * Author: Yinghai Lu <yinghai@kernel.org>
1476 * Date: Fri Dec 17 16:58:28 2010 -0800
1477 *
1478 * x86-64, mm: Put early page table high
1479 *
1480 * at some point init_memory_mapping is going to reach the pagetable pages
1481 * area and map those pages too (mapping them as normal memory that falls
1482 * in the range of addresses passed to init_memory_mapping as argument).
1483 * Some of those pages are already pagetable pages (they are in the range
1484 * pgt_buf_start-pgt_buf_end) therefore they are going to be mapped RO and
1485 * everything is fine.
1486 * Some of these pages are not pagetable pages yet (they fall in the range
1487 * pgt_buf_end-pgt_buf_top; for example the page at pgt_buf_end) so they
1488 * are going to be mapped RW. When these pages become pagetable pages and
1489 * are hooked into the pagetable, xen will find that the guest has already
1490 * a RW mapping of them somewhere and fail the operation.
1491 * The reason Xen requires pagetables to be RO is that the hypervisor needs
1492 * to verify that the pagetables are valid before using them. The validation
1493 * operations are called "pinning".
1494 *
1495 * In order to fix the issue we mark all the pages in the entire range
1496 * pgt_buf_start-pgt_buf_top as RO, however when the pagetable allocation
1497 * is completed only the range pgt_buf_start-pgt_buf_end is reserved by
1498 * init_memory_mapping. Hence the kernel is going to crash as soon as one
1499 * of the pages in the range pgt_buf_end-pgt_buf_top is reused (b/c those
1500 * ranges are RO).
1501 *
1502 * For this reason, 'mark_rw_past_pgt' is introduced which is called _after_
1503 * the init_memory_mapping has completed (in a perfect world we would
1504 * call this function from init_memory_mapping, but lets ignore that).
1505 *
1506 * Because we are called _after_ init_memory_mapping the pgt_buf_[start,
1507 * end,top] have all changed to new values (b/c init_memory_mapping
1508 * is called and setting up another new page-table). Hence, the first time
1509 * we enter this function, we save away the pgt_buf_start value and update
1510 * the pgt_buf_[end,top].
1511 *
1512 * When we detect that the "old" pgt_buf_start through pgt_buf_end
1513 * PFNs have been reserved (so memblock_x86_reserve_range has been called),
1514 * we immediately set out to RW the "old" pgt_buf_end through pgt_buf_top.
1515 *
1516 * And then we update those "old" pgt_buf_[end|top] with the new ones
1517 * so that we can redo this on the next pagetable.
1518 */
1519static __init void mark_rw_past_pgt(void) {
1520
1521 if (pgt_buf_end > pgt_buf_start) {
1522 u64 addr, size;
1523
1524 /* Save it away. */
1525 if (!__pgt_buf_start) {
1526 __pgt_buf_start = pgt_buf_start;
1527 __pgt_buf_end = pgt_buf_end;
1528 __pgt_buf_top = pgt_buf_top;
1529 return;
1530 }
1531 /* If we get the range that starts at __pgt_buf_end that means
1532 * the range is reserved, and that in 'init_memory_mapping'
1533 * the 'memblock_x86_reserve_range' has been called with the
1534 * outdated __pgt_buf_start, __pgt_buf_end (the "new"
1535 * pgt_buf_[start|end|top] refer now to a new pagetable.
1536 * Note: we are called _after_ the pgt_buf_[..] have been
1537 * updated.*/
1538
1539 addr = memblock_x86_find_in_range_size(PFN_PHYS(__pgt_buf_start),
1540 &size, PAGE_SIZE);
1541
1542 /* Still not reserved, meaning 'memblock_x86_reserve_range'
1543 * hasn't been called yet. Update the _end and _top.*/
1544 if (addr == PFN_PHYS(__pgt_buf_start)) {
1545 __pgt_buf_end = pgt_buf_end;
1546 __pgt_buf_top = pgt_buf_top;
1547 return;
1548 }
1549
1550 /* OK, the area is reserved, meaning it is time for us to
1551 * set RW for the old end->top PFNs. */
1552
1553 /* ..unless we had already done this. */
1554 if (__pgt_buf_end == __last_pgt_set_rw)
1555 return;
1556
1557 addr = PFN_PHYS(__pgt_buf_end);
1558
1559 /* set as RW the rest */
1560 printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n",
1561 PFN_PHYS(__pgt_buf_end), PFN_PHYS(__pgt_buf_top));
1562
1563 while (addr < PFN_PHYS(__pgt_buf_top)) {
1564 make_lowmem_page_readwrite(__va(addr));
1565 addr += PAGE_SIZE;
1566 }
1567 /* And update everything so that we are ready for the next
1568 * pagetable (the one created for regions past 4GB) */
1569 __last_pgt_set_rw = __pgt_buf_end;
1570 __pgt_buf_start = pgt_buf_start;
1571 __pgt_buf_end = pgt_buf_end;
1572 __pgt_buf_top = pgt_buf_top;
1573 }
1574 return;
1575}
1576#else
1577static __init void mark_rw_past_pgt(void) { }
1578#endif
1466static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) 1579static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
1467{ 1580{
1468#ifdef CONFIG_X86_64 1581#ifdef CONFIG_X86_64
@@ -1489,13 +1602,21 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
1489 unsigned long pfn = pte_pfn(pte); 1602 unsigned long pfn = pte_pfn(pte);
1490 1603
1491 /* 1604 /*
1605 * A bit of optimization. We do not need to call the workaround
1606 * when xen_set_pte_init is called with a PTE with 0 as PFN.
1607 * That is b/c the pagetable at that point are just being populated
1608 * with empty values and we can save some cycles by not calling
1609 * the 'memblock' code.*/
1610 if (pfn)
1611 mark_rw_past_pgt();
1612 /*
1492 * If the new pfn is within the range of the newly allocated 1613 * If the new pfn is within the range of the newly allocated
1493 * kernel pagetable, and it isn't being mapped into an 1614 * kernel pagetable, and it isn't being mapped into an
1494 * early_ioremap fixmap slot as a freshly allocated page, make sure 1615 * early_ioremap fixmap slot as a freshly allocated page, make sure
1495 * it is RO. 1616 * it is RO.
1496 */ 1617 */
1497 if (((!is_early_ioremap_ptep(ptep) && 1618 if (((!is_early_ioremap_ptep(ptep) &&
1498 pfn >= pgt_buf_start && pfn < pgt_buf_end)) || 1619 pfn >= pgt_buf_start && pfn < pgt_buf_top)) ||
1499 (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1))) 1620 (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1)))
1500 pte = pte_wrprotect(pte); 1621 pte = pte_wrprotect(pte);
1501 1622
@@ -1997,6 +2118,8 @@ __init void xen_ident_map_ISA(void)
1997 2118
1998static __init void xen_post_allocator_init(void) 2119static __init void xen_post_allocator_init(void)
1999{ 2120{
2121 mark_rw_past_pgt();
2122
2000#ifdef CONFIG_XEN_DEBUG 2123#ifdef CONFIG_XEN_DEBUG
2001 pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); 2124 pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug);
2002#endif 2125#endif