arm64: Allow a capability to be checked on a single CPU
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 22 Apr 2016 11:25:32 +0000 (12:25 +0100)
committerWill Deacon <will.deacon@arm.com>
Mon, 25 Apr 2016 14:13:05 +0000 (15:13 +0100)
Now that the capabilities are only available once all the CPUs
have booted, we're unable to check for a particular feature
in any subsystem that gets initialized before then.

In order to support this, introduce a local_cpu_has_cap() function
that tests for the presence of a given capability independently
of the whole framework.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[ Added preemptible() check ]
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
[will: remove duplicate initialisation of caps in this_cpu_has_cap]
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/cpufeature.h
arch/arm64/kernel/cpufeature.c

index e501e4af2ebd3a1e31224b6888d3579be1fc8525..d39db638774673a2b2efe1bff2365118f0594ea5 100644 (file)
@@ -109,6 +109,8 @@ struct arm64_cpu_capabilities {
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 
+bool this_cpu_has_cap(unsigned int cap);
+
 static inline bool cpu_have_feature(unsigned int num)
 {
        return elf_hwcap & (1UL << num);
index 54abd9bd5c95f719683847feb079d62027fecc88..2b09dc47717895c255d4a6e541254d57cd39f232 100644 (file)
@@ -1010,6 +1010,24 @@ static void __init setup_feature_capabilities(void)
        enable_cpu_capabilities(arm64_features);
 }
 
+/*
+ * Check if the current CPU has a given feature capability.
+ * Should be called from non-preemptible context.
+ */
+bool this_cpu_has_cap(unsigned int cap)
+{
+       const struct arm64_cpu_capabilities *caps;
+
+       if (WARN_ON(preemptible()))
+               return false;
+
+       for (caps = arm64_features; caps->desc; caps++)
+               if (caps->capability == cap && caps->matches)
+                       return caps->matches(caps, SCOPE_LOCAL_CPU);
+
+       return false;
+}
+
 void __init setup_cpu_features(void)
 {
        u32 cwg;