@@ -207,6 +207,7 @@ extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
#define SCOPE_SYSTEM ARM64_CPUCAP_SCOPE_SYSTEM
#define SCOPE_LOCAL_CPU ARM64_CPUCAP_SCOPE_LOCAL_CPU
+#define SCOPE_ALL ARM64_CPUCAP_SCOPE_MASK
/*
* Is it permitted for a late CPU to have this capability when system
@@ -1164,10 +1164,12 @@ static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
}
static void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
- const char *info)
+ u16 scope_mask, const char *info)
{
+ scope_mask &= ARM64_CPUCAP_SCOPE_MASK;
for (; caps->matches; caps++) {
- if (!caps->matches(caps, cpucap_default_scope(caps)))
+ if (!(caps->type & scope_mask) ||
+ !caps->matches(caps, cpucap_default_scope(caps)))
continue;
if (!cpus_have_cap(caps->capability) && caps->desc)
@@ -1189,12 +1191,14 @@ static int __enable_cpu_capability(void *arg)
* CPUs
*/
static void __init
-enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
+enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
+ u16 scope_mask)
{
+ scope_mask &= ARM64_CPUCAP_SCOPE_MASK;
for (; caps->matches; caps++) {
unsigned int num = caps->capability;
- if (!cpus_have_cap(num))
+ if (!(caps->type & scope_mask) || !cpus_have_cap(num))
continue;
/* Ensure cpus_have_const_cap(num) works */
@@ -1236,12 +1240,18 @@ static inline void set_sys_caps_initialised(void)
* Returns "false" on conflicts.
*/
static bool
-__verify_local_cpu_caps(const struct arm64_cpu_capabilities *caps_list)
+__verify_local_cpu_caps(const struct arm64_cpu_capabilities *caps_list,
+ u16 scope_mask)
{
bool cpu_has_cap, system_has_cap;
const struct arm64_cpu_capabilities *caps;
+ scope_mask &= ARM64_CPUCAP_SCOPE_MASK;
+
for (caps = caps_list; caps->matches; caps++) {
+ if (!(caps->type & scope_mask))
+ continue;
+
cpu_has_cap = __this_cpu_has_cap(caps_list, caps->capability);
system_has_cap = cpus_have_cap(caps->capability);
@@ -1304,7 +1314,7 @@ verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps)
static void verify_local_cpu_features(void)
{
- if (!__verify_local_cpu_caps(arm64_features))
+ if (!__verify_local_cpu_caps(arm64_features, SCOPE_ALL))
cpu_die_early();
}
@@ -1315,18 +1325,19 @@ static void verify_local_cpu_features(void)
*/
static void verify_local_cpu_errata_workarounds(void)
{
- if (!__verify_local_cpu_caps(arm64_errata))
+ if (!__verify_local_cpu_caps(arm64_errata, SCOPE_ALL))
cpu_die_early();
}
static void update_cpu_errata_workarounds(void)
{
- update_cpu_capabilities(arm64_errata, "enabling workaround for");
+ update_cpu_capabilities(arm64_errata, SCOPE_ALL,
+ "enabling workaround for");
}
static void __init enable_errata_workarounds(void)
{
- enable_cpu_capabilities(arm64_errata);
+ enable_cpu_capabilities(arm64_errata, SCOPE_ALL);
}
/*
@@ -1368,8 +1379,8 @@ void check_local_cpu_capabilities(void)
static void __init setup_feature_capabilities(void)
{
- update_cpu_capabilities(arm64_features, "detected feature:");
- enable_cpu_capabilities(arm64_features);
+ update_cpu_capabilities(arm64_features, SCOPE_ALL, "detected:");
+ enable_cpu_capabilities(arm64_features, SCOPE_ALL);
}
DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready);