diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 15:54:53 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 16:01:40 -0400 |
commit | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (patch) | |
tree | 3c2086ab67398a019089a47ca3f362a4bc6db74f /arch/arm/kernel | |
parent | 34e84f39a27d059a3e6ec6e8b94aafa702e6f220 (diff) | |
parent | 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 (diff) |
Merge branch 'master' into for-linus
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 19 | ||||
-rw-r--r-- | arch/arm/kernel/entry-header.S | 14 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes.c | 19 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 1 |
4 files changed, 43 insertions, 10 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3d727a8a23bc..0a2ba51cf35d 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -272,7 +272,15 @@ __und_svc: | |||
272 | @ | 272 | @ |
273 | @ r0 - instruction | 273 | @ r0 - instruction |
274 | @ | 274 | @ |
275 | #ifndef CONFIG_THUMB2_KERNEL | ||
275 | ldr r0, [r2, #-4] | 276 | ldr r0, [r2, #-4] |
277 | #else | ||
278 | ldrh r0, [r2, #-2] @ Thumb instruction at LR - 2 | ||
279 | and r9, r0, #0xf800 | ||
280 | cmp r9, #0xe800 @ 32-bit instruction if xx >= 0 | ||
281 | ldrhhs r9, [r2] @ bottom 16 bits | ||
282 | orrhs r0, r9, r0, lsl #16 | ||
283 | #endif | ||
276 | adr r9, BSYM(1f) | 284 | adr r9, BSYM(1f) |
277 | bl call_fpe | 285 | bl call_fpe |
278 | 286 | ||
@@ -678,7 +686,9 @@ ENTRY(fp_enter) | |||
678 | .word no_fp | 686 | .word no_fp |
679 | .previous | 687 | .previous |
680 | 688 | ||
681 | no_fp: mov pc, lr | 689 | ENTRY(no_fp) |
690 | mov pc, lr | ||
691 | ENDPROC(no_fp) | ||
682 | 692 | ||
683 | __und_usr_unknown: | 693 | __und_usr_unknown: |
684 | enable_irq | 694 | enable_irq |
@@ -734,13 +744,6 @@ ENTRY(__switch_to) | |||
734 | #ifdef CONFIG_MMU | 744 | #ifdef CONFIG_MMU |
735 | ldr r6, [r2, #TI_CPU_DOMAIN] | 745 | ldr r6, [r2, #TI_CPU_DOMAIN] |
736 | #endif | 746 | #endif |
737 | #if __LINUX_ARM_ARCH__ >= 6 | ||
738 | #ifdef CONFIG_CPU_32v6K | ||
739 | clrex | ||
740 | #else | ||
741 | strex r5, r4, [ip] @ Clear exclusive monitor | ||
742 | #endif | ||
743 | #endif | ||
744 | #if defined(CONFIG_HAS_TLS_REG) | 747 | #if defined(CONFIG_HAS_TLS_REG) |
745 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | 748 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register |
746 | #elif !defined(CONFIG_TLS_REG_EMUL) | 749 | #elif !defined(CONFIG_TLS_REG_EMUL) |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index a4eaf4f920c5..e17e3c30d957 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
@@ -76,13 +76,25 @@ | |||
76 | #ifndef CONFIG_THUMB2_KERNEL | 76 | #ifndef CONFIG_THUMB2_KERNEL |
77 | .macro svc_exit, rpsr | 77 | .macro svc_exit, rpsr |
78 | msr spsr_cxsf, \rpsr | 78 | msr spsr_cxsf, \rpsr |
79 | #if defined(CONFIG_CPU_32v6K) | ||
80 | clrex @ clear the exclusive monitor | ||
79 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | 81 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr |
82 | #elif defined (CONFIG_CPU_V6) | ||
83 | ldr r0, [sp] | ||
84 | strex r1, r2, [sp] @ clear the exclusive monitor | ||
85 | ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr | ||
86 | #endif | ||
80 | .endm | 87 | .endm |
81 | 88 | ||
82 | .macro restore_user_regs, fast = 0, offset = 0 | 89 | .macro restore_user_regs, fast = 0, offset = 0 |
83 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr | 90 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr |
84 | ldr lr, [sp, #\offset + S_PC]! @ get pc | 91 | ldr lr, [sp, #\offset + S_PC]! @ get pc |
85 | msr spsr_cxsf, r1 @ save in spsr_svc | 92 | msr spsr_cxsf, r1 @ save in spsr_svc |
93 | #if defined(CONFIG_CPU_32v6K) | ||
94 | clrex @ clear the exclusive monitor | ||
95 | #elif defined (CONFIG_CPU_V6) | ||
96 | strex r1, r2, [sp] @ clear the exclusive monitor | ||
97 | #endif | ||
86 | .if \fast | 98 | .if \fast |
87 | ldmdb sp, {r1 - lr}^ @ get calling r1 - lr | 99 | ldmdb sp, {r1 - lr}^ @ get calling r1 - lr |
88 | .else | 100 | .else |
@@ -98,6 +110,7 @@ | |||
98 | .endm | 110 | .endm |
99 | #else /* CONFIG_THUMB2_KERNEL */ | 111 | #else /* CONFIG_THUMB2_KERNEL */ |
100 | .macro svc_exit, rpsr | 112 | .macro svc_exit, rpsr |
113 | clrex @ clear the exclusive monitor | ||
101 | ldr r0, [sp, #S_SP] @ top of the stack | 114 | ldr r0, [sp, #S_SP] @ top of the stack |
102 | ldr r1, [sp, #S_PC] @ return address | 115 | ldr r1, [sp, #S_PC] @ return address |
103 | tst r0, #4 @ orig stack 8-byte aligned? | 116 | tst r0, #4 @ orig stack 8-byte aligned? |
@@ -110,6 +123,7 @@ | |||
110 | .endm | 123 | .endm |
111 | 124 | ||
112 | .macro restore_user_regs, fast = 0, offset = 0 | 125 | .macro restore_user_regs, fast = 0, offset = 0 |
126 | clrex @ clear the exclusive monitor | ||
113 | mov r2, sp | 127 | mov r2, sp |
114 | load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr | 128 | load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr |
115 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr | 129 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr |
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index f692efddd449..60c62c377fa9 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/kprobes.h> | 23 | #include <linux/kprobes.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/stop_machine.h> | ||
25 | #include <linux/stringify.h> | 26 | #include <linux/stringify.h> |
26 | #include <asm/traps.h> | 27 | #include <asm/traps.h> |
27 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
@@ -83,10 +84,24 @@ void __kprobes arch_arm_kprobe(struct kprobe *p) | |||
83 | flush_insns(p->addr, 1); | 84 | flush_insns(p->addr, 1); |
84 | } | 85 | } |
85 | 86 | ||
87 | /* | ||
88 | * The actual disarming is done here on each CPU and synchronized using | ||
89 | * stop_machine. This synchronization is necessary on SMP to avoid removing | ||
90 | * a probe between the moment the 'Undefined Instruction' exception is raised | ||
91 | * and the moment the exception handler reads the faulting instruction from | ||
92 | * memory. | ||
93 | */ | ||
94 | int __kprobes __arch_disarm_kprobe(void *p) | ||
95 | { | ||
96 | struct kprobe *kp = p; | ||
97 | *kp->addr = kp->opcode; | ||
98 | flush_insns(kp->addr, 1); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
86 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | 102 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
87 | { | 103 | { |
88 | *p->addr = p->opcode; | 104 | stop_machine(__arch_disarm_kprobe, p, &cpu_online_map); |
89 | flush_insns(p->addr, 1); | ||
90 | } | 105 | } |
91 | 106 | ||
92 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 107 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 39d3ffb9ff2b..aecf87dfbaec 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -83,6 +83,7 @@ SECTIONS | |||
83 | EXIT_TEXT | 83 | EXIT_TEXT |
84 | EXIT_DATA | 84 | EXIT_DATA |
85 | *(.exitcall.exit) | 85 | *(.exitcall.exit) |
86 | *(.discard) | ||
86 | *(.ARM.exidx.exit.text) | 87 | *(.ARM.exidx.exit.text) |
87 | *(.ARM.extab.exit.text) | 88 | *(.ARM.extab.exit.text) |
88 | #ifndef CONFIG_HOTPLUG_CPU | 89 | #ifndef CONFIG_HOTPLUG_CPU |