Commit 830dcc9f authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Will Deacon

arm64: capabilities: Change scope of VHE to Boot CPU feature

We expect all CPUs to be running at the same EL inside the kernel
with or without VHE enabled and we have strict checks to ensure
that any mismatch triggers a kernel panic. If VHE is enabled,
we use the feature based on the boot CPU and all other CPUs
should follow. This makes it a perfect candidate for a capability
based on the boot CPU,  which should be matched by all the CPUs
(both when is ON and OFF). This saves us some not-so-pretty
hooks and special code, just for verifying the conflict.

The patch also makes the VHE capability entry depend on
CONFIG_ARM64_VHE.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: default avatarDave Martin <dave.martin@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent fd9d63da
...@@ -287,6 +287,12 @@ extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0; ...@@ -287,6 +287,12 @@ extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
(ARM64_CPUCAP_SCOPE_LOCAL_CPU | \ (ARM64_CPUCAP_SCOPE_LOCAL_CPU | \
ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU) ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU)
/*
* CPU feature used early in the boot based on the boot CPU. All secondary
* CPUs must match the state of the capability as detected by the boot CPU.
*/
#define ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE ARM64_CPUCAP_SCOPE_BOOT_CPU
struct arm64_cpu_capabilities { struct arm64_cpu_capabilities {
const char *desc; const char *desc;
u16 capability; u16 capability;
......
...@@ -102,12 +102,6 @@ static inline bool has_vhe(void) ...@@ -102,12 +102,6 @@ static inline bool has_vhe(void)
return false; return false;
} }
#ifdef CONFIG_ARM64_VHE
extern void verify_cpu_run_el(void);
#else
static inline void verify_cpu_run_el(void) {}
#endif
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* ! __ASM__VIRT_H */ #endif /* ! __ASM__VIRT_H */
...@@ -1033,13 +1033,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = { ...@@ -1033,13 +1033,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = cpufeature_pan_not_uao, .matches = cpufeature_pan_not_uao,
}, },
#endif /* CONFIG_ARM64_PAN */ #endif /* CONFIG_ARM64_PAN */
#ifdef CONFIG_ARM64_VHE
{ {
.desc = "Virtualization Host Extensions", .desc = "Virtualization Host Extensions",
.capability = ARM64_HAS_VIRT_HOST_EXTN, .capability = ARM64_HAS_VIRT_HOST_EXTN,
.type = ARM64_CPUCAP_SYSTEM_FEATURE, .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE,
.matches = runs_at_el2, .matches = runs_at_el2,
.cpu_enable = cpu_copy_el2regs, .cpu_enable = cpu_copy_el2regs,
}, },
#endif /* CONFIG_ARM64_VHE */
{ {
.desc = "32-bit EL0 Support", .desc = "32-bit EL0 Support",
.capability = ARM64_HAS_32BIT_EL0, .capability = ARM64_HAS_32BIT_EL0,
...@@ -1409,7 +1411,6 @@ static bool verify_local_cpu_caps(u16 scope_mask) ...@@ -1409,7 +1411,6 @@ static bool verify_local_cpu_caps(u16 scope_mask)
*/ */
static void check_early_cpu_features(void) static void check_early_cpu_features(void)
{ {
verify_cpu_run_el();
verify_cpu_asid_bits(); verify_cpu_asid_bits();
/* /*
* Early features are used by the kernel already. If there * Early features are used by the kernel already. If there
......
...@@ -85,43 +85,6 @@ enum ipi_msg_type { ...@@ -85,43 +85,6 @@ enum ipi_msg_type {
IPI_WAKEUP IPI_WAKEUP
}; };
#ifdef CONFIG_ARM64_VHE
/* Whether the boot CPU is running in HYP mode or not*/
static bool boot_cpu_hyp_mode;
static inline void save_boot_cpu_run_el(void)
{
boot_cpu_hyp_mode = is_kernel_in_hyp_mode();
}
static inline bool is_boot_cpu_in_hyp_mode(void)
{
return boot_cpu_hyp_mode;
}
/*
* Verify that a secondary CPU is running the kernel at the same
* EL as that of the boot CPU.
*/
void verify_cpu_run_el(void)
{
bool in_el2 = is_kernel_in_hyp_mode();
bool boot_cpu_el2 = is_boot_cpu_in_hyp_mode();
if (in_el2 ^ boot_cpu_el2) {
pr_crit("CPU%d: mismatched Exception Level(EL%d) with boot CPU(EL%d)\n",
smp_processor_id(),
in_el2 ? 2 : 1,
boot_cpu_el2 ? 2 : 1);
cpu_panic_kernel();
}
}
#else
static inline void save_boot_cpu_run_el(void) {}
#endif
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
static int op_cpu_kill(unsigned int cpu); static int op_cpu_kill(unsigned int cpu);
#else #else
...@@ -447,7 +410,6 @@ void __init smp_prepare_boot_cpu(void) ...@@ -447,7 +410,6 @@ void __init smp_prepare_boot_cpu(void)
*/ */
jump_label_init(); jump_label_init();
cpuinfo_store_boot_cpu(); cpuinfo_store_boot_cpu();
save_boot_cpu_run_el();
} }
static u64 __init of_get_cpu_mpidr(struct device_node *dn) static u64 __init of_get_cpu_mpidr(struct device_node *dn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment