diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 38 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 44 | ||||
-rw-r--r-- | arch/arm/kernel/module.c | 22 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/collie.c | 3 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/oprofile/common.c | 2 |
8 files changed, 82 insertions, 37 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5cff165b7eb0..26d45e5b636b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1391,7 +1391,7 @@ config AEABI | |||
1391 | 1391 | ||
1392 | config OABI_COMPAT | 1392 | config OABI_COMPAT |
1393 | bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" | 1393 | bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" |
1394 | depends on AEABI && EXPERIMENTAL | 1394 | depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL |
1395 | default y | 1395 | default y |
1396 | help | 1396 | help |
1397 | This option preserves the old syscall interface along with the | 1397 | This option preserves the old syscall interface along with the |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index c0225da3fb21..f06ff9feb0db 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -391,6 +391,7 @@ ENDPROC(__turn_mmu_on) | |||
391 | 391 | ||
392 | 392 | ||
393 | #ifdef CONFIG_SMP_ON_UP | 393 | #ifdef CONFIG_SMP_ON_UP |
394 | __INIT | ||
394 | __fixup_smp: | 395 | __fixup_smp: |
395 | and r3, r9, #0x000f0000 @ architecture version | 396 | and r3, r9, #0x000f0000 @ architecture version |
396 | teq r3, #0x000f0000 @ CPU ID supported? | 397 | teq r3, #0x000f0000 @ CPU ID supported? |
@@ -415,18 +416,7 @@ __fixup_smp_on_up: | |||
415 | sub r3, r0, r3 | 416 | sub r3, r0, r3 |
416 | add r4, r4, r3 | 417 | add r4, r4, r3 |
417 | add r5, r5, r3 | 418 | add r5, r5, r3 |
418 | 2: cmp r4, r5 | 419 | b __do_fixup_smp_on_up |
419 | movhs pc, lr | ||
420 | ldmia r4!, {r0, r6} | ||
421 | ARM( str r6, [r0, r3] ) | ||
422 | THUMB( add r0, r0, r3 ) | ||
423 | #ifdef __ARMEB__ | ||
424 | THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. | ||
425 | #endif | ||
426 | THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords | ||
427 | THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. | ||
428 | THUMB( strh r6, [r0] ) | ||
429 | b 2b | ||
430 | ENDPROC(__fixup_smp) | 420 | ENDPROC(__fixup_smp) |
431 | 421 | ||
432 | .align | 422 | .align |
@@ -440,7 +430,31 @@ smp_on_up: | |||
440 | ALT_SMP(.long 1) | 430 | ALT_SMP(.long 1) |
441 | ALT_UP(.long 0) | 431 | ALT_UP(.long 0) |
442 | .popsection | 432 | .popsection |
433 | #endif | ||
443 | 434 | ||
435 | .text | ||
436 | __do_fixup_smp_on_up: | ||
437 | cmp r4, r5 | ||
438 | movhs pc, lr | ||
439 | ldmia r4!, {r0, r6} | ||
440 | ARM( str r6, [r0, r3] ) | ||
441 | THUMB( add r0, r0, r3 ) | ||
442 | #ifdef __ARMEB__ | ||
443 | THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. | ||
444 | #endif | 444 | #endif |
445 | THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords | ||
446 | THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. | ||
447 | THUMB( strh r6, [r0] ) | ||
448 | b __do_fixup_smp_on_up | ||
449 | ENDPROC(__do_fixup_smp_on_up) | ||
450 | |||
451 | ENTRY(fixup_smp) | ||
452 | stmfd sp!, {r4 - r6, lr} | ||
453 | mov r4, r0 | ||
454 | add r5, r0, r1 | ||
455 | mov r3, #0 | ||
456 | bl __do_fixup_smp_on_up | ||
457 | ldmfd sp!, {r4 - r6, pc} | ||
458 | ENDPROC(fixup_smp) | ||
445 | 459 | ||
446 | #include "head-common.S" | 460 | #include "head-common.S" |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index c9f3f0467570..d600bd350704 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -137,11 +137,10 @@ static u8 get_debug_arch(void) | |||
137 | u32 didr; | 137 | u32 didr; |
138 | 138 | ||
139 | /* Do we implement the extended CPUID interface? */ | 139 | /* Do we implement the extended CPUID interface? */ |
140 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | 140 | if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), |
141 | pr_warning("CPUID feature registers not supported. " | 141 | "CPUID feature registers not supported. " |
142 | "Assuming v6 debug is present.\n"); | 142 | "Assuming v6 debug is present.\n")) |
143 | return ARM_DEBUG_ARCH_V6; | 143 | return ARM_DEBUG_ARCH_V6; |
144 | } | ||
145 | 144 | ||
146 | ARM_DBG_READ(c0, 0, didr); | 145 | ARM_DBG_READ(c0, 0, didr); |
147 | return (didr >> 16) & 0xf; | 146 | return (didr >> 16) & 0xf; |
@@ -152,6 +151,12 @@ u8 arch_get_debug_arch(void) | |||
152 | return debug_arch; | 151 | return debug_arch; |
153 | } | 152 | } |
154 | 153 | ||
154 | static int debug_arch_supported(void) | ||
155 | { | ||
156 | u8 arch = get_debug_arch(); | ||
157 | return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; | ||
158 | } | ||
159 | |||
155 | /* Determine number of BRP register available. */ | 160 | /* Determine number of BRP register available. */ |
156 | static int get_num_brp_resources(void) | 161 | static int get_num_brp_resources(void) |
157 | { | 162 | { |
@@ -268,6 +273,9 @@ out: | |||
268 | 273 | ||
269 | int hw_breakpoint_slots(int type) | 274 | int hw_breakpoint_slots(int type) |
270 | { | 275 | { |
276 | if (!debug_arch_supported()) | ||
277 | return 0; | ||
278 | |||
271 | /* | 279 | /* |
272 | * We can be called early, so don't rely on | 280 | * We can be called early, so don't rely on |
273 | * our static variables being initialised. | 281 | * our static variables being initialised. |
@@ -834,11 +842,11 @@ static void reset_ctrl_regs(void *unused) | |||
834 | 842 | ||
835 | /* | 843 | /* |
836 | * v7 debug contains save and restore registers so that debug state | 844 | * v7 debug contains save and restore registers so that debug state |
837 | * can be maintained across low-power modes without leaving | 845 | * can be maintained across low-power modes without leaving the debug |
838 | * the debug logic powered up. It is IMPLEMENTATION DEFINED whether | 846 | * logic powered up. It is IMPLEMENTATION DEFINED whether we can access |
839 | * we can write to the debug registers out of reset, so we must | 847 | * the debug registers out of reset, so we must unlock the OS Lock |
840 | * unlock the OS Lock Access Register to avoid taking undefined | 848 | * Access Register to avoid taking undefined instruction exceptions |
841 | * instruction exceptions later on. | 849 | * later on. |
842 | */ | 850 | */ |
843 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | 851 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { |
844 | /* | 852 | /* |
@@ -882,7 +890,7 @@ static int __init arch_hw_breakpoint_init(void) | |||
882 | 890 | ||
883 | debug_arch = get_debug_arch(); | 891 | debug_arch = get_debug_arch(); |
884 | 892 | ||
885 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | 893 | if (!debug_arch_supported()) { |
886 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | 894 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); |
887 | return 0; | 895 | return 0; |
888 | } | 896 | } |
@@ -899,18 +907,18 @@ static int __init arch_hw_breakpoint_init(void) | |||
899 | pr_info("%d breakpoint(s) reserved for watchpoint " | 907 | pr_info("%d breakpoint(s) reserved for watchpoint " |
900 | "single-step.\n", core_num_reserved_brps); | 908 | "single-step.\n", core_num_reserved_brps); |
901 | 909 | ||
910 | /* | ||
911 | * Reset the breakpoint resources. We assume that a halting | ||
912 | * debugger will leave the world in a nice state for us. | ||
913 | */ | ||
914 | on_each_cpu(reset_ctrl_regs, NULL, 1); | ||
915 | |||
902 | ARM_DBG_READ(c1, 0, dscr); | 916 | ARM_DBG_READ(c1, 0, dscr); |
903 | if (dscr & ARM_DSCR_HDBGEN) { | 917 | if (dscr & ARM_DSCR_HDBGEN) { |
918 | max_watchpoint_len = 4; | ||
904 | pr_warning("halting debug mode enabled. Assuming maximum " | 919 | pr_warning("halting debug mode enabled. Assuming maximum " |
905 | "watchpoint size of 4 bytes."); | 920 | "watchpoint size of %u bytes.", max_watchpoint_len); |
906 | } else { | 921 | } else { |
907 | /* | ||
908 | * Reset the breakpoint resources. We assume that a halting | ||
909 | * debugger will leave the world in a nice state for us. | ||
910 | */ | ||
911 | smp_call_function(reset_ctrl_regs, NULL, 1); | ||
912 | reset_ctrl_regs(NULL); | ||
913 | |||
914 | /* Work out the maximum supported watchpoint length. */ | 922 | /* Work out the maximum supported watchpoint length. */ |
915 | max_watchpoint_len = get_max_wp_len(); | 923 | max_watchpoint_len = get_max_wp_len(); |
916 | pr_info("maximum watchpoint size is %u bytes.\n", | 924 | pr_info("maximum watchpoint size is %u bytes.\n", |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 2cfe8161b478..6d4105e6872f 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/sections.h> | 24 | #include <asm/sections.h> |
25 | #include <asm/smp_plat.h> | ||
25 | #include <asm/unwind.h> | 26 | #include <asm/unwind.h> |
26 | 27 | ||
27 | #ifdef CONFIG_XIP_KERNEL | 28 | #ifdef CONFIG_XIP_KERNEL |
@@ -268,12 +269,28 @@ struct mod_unwind_map { | |||
268 | const Elf_Shdr *txt_sec; | 269 | const Elf_Shdr *txt_sec; |
269 | }; | 270 | }; |
270 | 271 | ||
272 | static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr, | ||
273 | const Elf_Shdr *sechdrs, const char *name) | ||
274 | { | ||
275 | const Elf_Shdr *s, *se; | ||
276 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
277 | |||
278 | for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) | ||
279 | if (strcmp(name, secstrs + s->sh_name) == 0) | ||
280 | return s; | ||
281 | |||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | extern void fixup_smp(const void *, unsigned long); | ||
286 | |||
271 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | 287 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, |
272 | struct module *mod) | 288 | struct module *mod) |
273 | { | 289 | { |
290 | const Elf_Shdr * __maybe_unused s = NULL; | ||
274 | #ifdef CONFIG_ARM_UNWIND | 291 | #ifdef CONFIG_ARM_UNWIND |
275 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 292 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
276 | const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | 293 | const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; |
277 | struct mod_unwind_map maps[ARM_SEC_MAX]; | 294 | struct mod_unwind_map maps[ARM_SEC_MAX]; |
278 | int i; | 295 | int i; |
279 | 296 | ||
@@ -315,6 +332,9 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
315 | maps[i].txt_sec->sh_addr, | 332 | maps[i].txt_sec->sh_addr, |
316 | maps[i].txt_sec->sh_size); | 333 | maps[i].txt_sec->sh_size); |
317 | #endif | 334 | #endif |
335 | s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); | ||
336 | if (s && !is_smp()) | ||
337 | fixup_smp((void *)s->sh_addr, s->sh_size); | ||
318 | return 0; | 338 | return 0; |
319 | } | 339 | } |
320 | 340 | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 5efa2647a2fb..d150ad1ccb5d 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -700,7 +700,7 @@ user_backtrace(struct frame_tail __user *tail, | |||
700 | * Frame pointers should strictly progress back up the stack | 700 | * Frame pointers should strictly progress back up the stack |
701 | * (towards higher addresses). | 701 | * (towards higher addresses). |
702 | */ | 702 | */ |
703 | if (tail >= buftail.fp) | 703 | if (tail + 1 >= buftail.fp) |
704 | return NULL; | 704 | return NULL; |
705 | 705 | ||
706 | return buftail.fp - 1; | 706 | return buftail.fp - 1; |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index d43c5ef58eb6..bd3e1bfdd6aa 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
@@ -241,6 +241,9 @@ static struct locomo_platform_data locomo_info = { | |||
241 | struct platform_device collie_locomo_device = { | 241 | struct platform_device collie_locomo_device = { |
242 | .name = "locomo", | 242 | .name = "locomo", |
243 | .id = 0, | 243 | .id = 0, |
244 | .dev = { | ||
245 | .platform_data = &locomo_info, | ||
246 | }, | ||
244 | .num_resources = ARRAY_SIZE(locomo_resources), | 247 | .num_resources = ARRAY_SIZE(locomo_resources), |
245 | .resource = locomo_resources, | 248 | .resource = locomo_resources, |
246 | }; | 249 | }; |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 9d30c6f804b9..e4509bae8fc4 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -405,7 +405,7 @@ config CPU_V6 | |||
405 | config CPU_32v6K | 405 | config CPU_32v6K |
406 | bool "Support ARM V6K processor extensions" if !SMP | 406 | bool "Support ARM V6K processor extensions" if !SMP |
407 | depends on CPU_V6 || CPU_V7 | 407 | depends on CPU_V6 || CPU_V7 |
408 | default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) | 408 | default y if SMP |
409 | help | 409 | help |
410 | Say Y here if your ARMv6 processor supports the 'K' extension. | 410 | Say Y here if your ARMv6 processor supports the 'K' extension. |
411 | This enables the kernel to use some instructions not present | 411 | This enables the kernel to use some instructions not present |
@@ -416,7 +416,7 @@ config CPU_32v6K | |||
416 | # ARMv7 | 416 | # ARMv7 |
417 | config CPU_V7 | 417 | config CPU_V7 |
418 | bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX | 418 | bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX |
419 | select CPU_32v6K if !ARCH_OMAP2 | 419 | select CPU_32v6K |
420 | select CPU_32v7 | 420 | select CPU_32v7 |
421 | select CPU_ABRT_EV7 | 421 | select CPU_ABRT_EV7 |
422 | select CPU_PABRT_V7 | 422 | select CPU_PABRT_V7 |
@@ -644,7 +644,7 @@ config ARM_THUMBEE | |||
644 | 644 | ||
645 | config SWP_EMULATE | 645 | config SWP_EMULATE |
646 | bool "Emulate SWP/SWPB instructions" | 646 | bool "Emulate SWP/SWPB instructions" |
647 | depends on CPU_V7 && !CPU_V6 | 647 | depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6 |
648 | select HAVE_PROC_CPU if PROC_FS | 648 | select HAVE_PROC_CPU if PROC_FS |
649 | default y if SMP | 649 | default y if SMP |
650 | help | 650 | help |
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 8aa974491dfc..6adda2b5fa31 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
@@ -85,7 +85,7 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail) | |||
85 | 85 | ||
86 | /* frame pointers should strictly progress back up the stack | 86 | /* frame pointers should strictly progress back up the stack |
87 | * (towards higher addresses) */ | 87 | * (towards higher addresses) */ |
88 | if (tail >= buftail[0].fp) | 88 | if (tail + 1 >= buftail[0].fp) |
89 | return NULL; | 89 | return NULL; |
90 | 90 | ||
91 | return buftail[0].fp-1; | 91 | return buftail[0].fp-1; |