aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2013-04-08 12:13:12 -0400
committerWill Deacon <will.deacon@arm.com>2013-05-30 11:02:34 -0400
commita469abd0f868c902b75532579bf87553dcf1b360 (patch)
tree45b8497556dff1a90311bbd087f34ff4791be9d6 /arch/arm
parente38a517578d6c0f764b0d0f6e26dcdf9f70c69d7 (diff)
ARM: elf: add new hwcap for identifying atomic ldrd/strd instructions
CPUs implementing LPAE have atomic ldrd/strd instructions, meaning that userspace software can avoid having to use the exclusive variants of these instructions if they wish. This patch advertises the atomicity of these instructions via the hwcaps, so userspace can detect this CPU feature. Reported-by: Vladimir Danushevsky <vladimir.danushevsky@oracle.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/uapi/asm/hwcap.h2
-rw-r--r--arch/arm/kernel/setup.c8
2 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
index 3688fd15a32d..6d34d080372a 100644
--- a/arch/arm/include/uapi/asm/hwcap.h
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -25,6 +25,6 @@
25#define HWCAP_IDIVT (1 << 18) 25#define HWCAP_IDIVT (1 << 18)
26#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ 26#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
27#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) 27#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
28 28#define HWCAP_LPAE (1 << 20)
29 29
30#endif /* _UAPI__ASMARM_HWCAP_H */ 30#endif /* _UAPI__ASMARM_HWCAP_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1522c7ae31b0..bdcd4dd13230 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -355,7 +355,7 @@ void __init early_print(const char *str, ...)
355 355
356static void __init cpuid_init_hwcaps(void) 356static void __init cpuid_init_hwcaps(void)
357{ 357{
358 unsigned int divide_instrs; 358 unsigned int divide_instrs, vmsa;
359 359
360 if (cpu_architecture() < CPU_ARCH_ARMv7) 360 if (cpu_architecture() < CPU_ARCH_ARMv7)
361 return; 361 return;
@@ -368,6 +368,11 @@ static void __init cpuid_init_hwcaps(void)
368 case 1: 368 case 1:
369 elf_hwcap |= HWCAP_IDIVT; 369 elf_hwcap |= HWCAP_IDIVT;
370 } 370 }
371
372 /* LPAE implies atomic ldrd/strd instructions */
373 vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0;
374 if (vmsa >= 5)
375 elf_hwcap |= HWCAP_LPAE;
371} 376}
372 377
373static void __init feat_v6_fixup(void) 378static void __init feat_v6_fixup(void)
@@ -872,6 +877,7 @@ static const char *hwcap_str[] = {
872 "vfpv4", 877 "vfpv4",
873 "idiva", 878 "idiva",
874 "idivt", 879 "idivt",
880 "lpae",
875 NULL 881 NULL
876}; 882};
877 883