aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/setup.c29
-rw-r--r--arch/arm/kernel/swp_emulate.c4
-rw-r--r--arch/arm/mm/Kconfig2
3 files changed, 27 insertions, 8 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8a16ee5d8a95..84db893dedc2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -393,19 +393,34 @@ static void __init cpuid_init_hwcaps(void)
393 elf_hwcap |= HWCAP_LPAE; 393 elf_hwcap |= HWCAP_LPAE;
394} 394}
395 395
396static void __init feat_v6_fixup(void) 396static void __init elf_hwcap_fixup(void)
397{ 397{
398 int id = read_cpuid_id(); 398 unsigned id = read_cpuid_id();
399 399 unsigned sync_prim;
400 if ((id & 0xff0f0000) != 0x41070000)
401 return;
402 400
403 /* 401 /*
404 * HWCAP_TLS is available only on 1136 r1p0 and later, 402 * HWCAP_TLS is available only on 1136 r1p0 and later,
405 * see also kuser_get_tls_init. 403 * see also kuser_get_tls_init.
406 */ 404 */
407 if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) 405 if (read_cpuid_part() == ARM_CPU_PART_ARM1136 &&
406 ((id >> 20) & 3) == 0) {
408 elf_hwcap &= ~HWCAP_TLS; 407 elf_hwcap &= ~HWCAP_TLS;
408 return;
409 }
410
411 /* Verify if CPUID scheme is implemented */
412 if ((id & 0x000f0000) != 0x000f0000)
413 return;
414
415 /*
416 * If the CPU supports LDREX/STREX and LDREXB/STREXB,
417 * avoid advertising SWP; it may not be atomic with
418 * multiprocessing cores.
419 */
420 sync_prim = ((read_cpuid_ext(CPUID_EXT_ISAR3) >> 8) & 0xf0) |
421 ((read_cpuid_ext(CPUID_EXT_ISAR4) >> 20) & 0x0f);
422 if (sync_prim >= 0x13)
423 elf_hwcap &= ~HWCAP_SWP;
409} 424}
410 425
411/* 426/*
@@ -609,7 +624,7 @@ static void __init setup_processor(void)
609#endif 624#endif
610 erratum_a15_798181_init(); 625 erratum_a15_798181_init();
611 626
612 feat_v6_fixup(); 627 elf_hwcap_fixup();
613 628
614 cacheid_init(); 629 cacheid_init();
615 cpu_init(); 630 cpu_init();
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index b1b89882b113..67ca8578c6d8 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -27,6 +27,7 @@
27#include <linux/perf_event.h> 27#include <linux/perf_event.h>
28 28
29#include <asm/opcodes.h> 29#include <asm/opcodes.h>
30#include <asm/system_info.h>
30#include <asm/traps.h> 31#include <asm/traps.h>
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32 33
@@ -266,6 +267,9 @@ static struct undef_hook swp_hook = {
266 */ 267 */
267static int __init swp_emulation_init(void) 268static int __init swp_emulation_init(void)
268{ 269{
270 if (cpu_architecture() < CPU_ARCH_ARMv7)
271 return 0;
272
269#ifdef CONFIG_PROC_FS 273#ifdef CONFIG_PROC_FS
270 if (!proc_create("cpu/swp_emulation", S_IRUGO, NULL, &proc_status_fops)) 274 if (!proc_create("cpu/swp_emulation", S_IRUGO, NULL, &proc_status_fops))
271 return -ENOMEM; 275 return -ENOMEM;
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index df46620206af..577039a3f6e5 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -669,7 +669,7 @@ config ARM_VIRT_EXT
669 details. 669 details.
670 670
671config SWP_EMULATE 671config SWP_EMULATE
672 bool "Emulate SWP/SWPB instructions" 672 bool "Emulate SWP/SWPB instructions" if !SMP
673 depends on CPU_V7 673 depends on CPU_V7
674 default y if SMP 674 default y if SMP
675 select HAVE_PROC_CPU if PROC_FS 675 select HAVE_PROC_CPU if PROC_FS