KVM: arm64: Allow indirect vectors to be used without SPECTRE_V3A
authorJames Morse <james.morse@arm.com>
Tue, 16 Nov 2021 15:06:19 +0000 (15:06 +0000)
committerJames Morse <james.morse@arm.com>
Tue, 15 Feb 2022 17:38:25 +0000 (17:38 +0000)
CPUs vulnerable to Spectre-BHB either need to make an SMC-CC firmware
call from the vectors, or run a sequence of branches. This gets added
to the hyp vectors. If there is no support for arch-workaround-1 in
firmware, the indirect vector will be used.

kvm_init_vector_slots() only initialises the two indirect slots if
the platform is vulnerable to Spectre-v3a. pKVM's hyp_map_vectors()
only initialises __hyp_bp_vect_base if the platform is vulnerable to
Spectre-v3a.

As there are about to more users of the indirect vectors, ensure
their entries in hyp_spectre_vector_selector[] are always initialised,
and __hyp_bp_vect_base defaults to the regular VA mapping.

The Spectre-v3a check is moved to a helper
kvm_system_needs_idmapped_vectors(), and merged with the code
that creates the hyp mappings.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/nvhe/mm.c

index 5bc01e62c08a03d55f12d1bafa9f6fc9ead49f10..031e3a2537fc8632bf23325a5c13f6d8f7a79644 100644 (file)
@@ -714,6 +714,11 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
        ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr();
 }
 
+static inline bool kvm_system_needs_idmapped_vectors(void)
+{
+       return cpus_have_const_cap(ARM64_SPECTRE_V3A);
+}
+
 void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu);
 
 static inline void kvm_arch_hardware_unsetup(void) {}
index ecc5958e27fe2b3fc69b9b1121a626495cb13c46..4dca6ffd03d42a4510c68c29832a008fe7c8cb6e 100644 (file)
@@ -1491,10 +1491,7 @@ static int kvm_init_vector_slots(void)
        base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs));
        kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT);
 
-       if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
-               return 0;
-
-       if (!has_vhe()) {
+       if (kvm_system_needs_idmapped_vectors() && !has_vhe()) {
                err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs),
                                               __BP_HARDEN_HYP_VECS_SZ, &base);
                if (err)
index 526a7d6fa86fbb70cd2ce5a1707fbf7a8791bf4a..cdbe8e24641838401820027b0d8e521cf216d9d8 100644 (file)
@@ -148,8 +148,10 @@ int hyp_map_vectors(void)
        phys_addr_t phys;
        void *bp_base;
 
-       if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
+       if (!kvm_system_needs_idmapped_vectors()) {
+               __hyp_bp_vect_base = __bp_harden_hyp_vecs;
                return 0;
+       }
 
        phys = __hyp_pa(__bp_harden_hyp_vecs);
        bp_base = (void *)__pkvm_create_private_mapping(phys,