KVM: arm64: Convert ARCH_WORKAROUND_2 to arm64_get_spectre_v4_state()
authorMarc Zyngier <maz@kernel.org>
Fri, 18 Sep 2020 13:08:54 +0000 (14:08 +0100)
committerWill Deacon <will@kernel.org>
Tue, 29 Sep 2020 15:08:17 +0000 (16:08 +0100)
Convert the KVM WA2 code to using the Spectre infrastructure,
making the code much more readable. It also allows us to
take SSBS into account for the mitigation.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kvm/arm.c
arch/arm64/kvm/hypercalls.c
arch/arm64/kvm/psci.c

index b1bd2f4cd3e068bd9ce8a3278b42775edc48d99d..9b90a701462c213e1d2cc3943e874e8429dfa6d3 100644 (file)
@@ -1292,7 +1292,7 @@ static void cpu_init_hyp_mode(void)
         * at EL2.
         */
        if (this_cpu_has_cap(ARM64_SSBS) &&
-           arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) {
+           arm64_get_spectre_v4_state() == SPECTRE_VULNERABLE) {
                kvm_call_hyp_nvhe(__kvm_enable_ssbs);
        }
 }
index 69e023dfafce1cbc38b1dbdd237b14fab70e79f4..9824025ccc5c047067f9456c1860606a1afaeb7c 100644 (file)
@@ -36,13 +36,24 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
                        }
                        break;
                case ARM_SMCCC_ARCH_WORKAROUND_2:
-                       switch (arm64_get_ssbd_state()) {
-                       case ARM64_SSBD_FORCE_DISABLE:
-                       case ARM64_SSBD_UNKNOWN:
+                       switch (arm64_get_spectre_v4_state()) {
+                       case SPECTRE_VULNERABLE:
                                break;
-                       case ARM64_SSBD_KERNEL:
-                       case ARM64_SSBD_FORCE_ENABLE:
-                       case ARM64_SSBD_MITIGATED:
+                       case SPECTRE_MITIGATED:
+                               /*
+                                * SSBS everywhere: Indicate no firmware
+                                * support, as the SSBS support will be
+                                * indicated to the guest and the default is
+                                * safe.
+                                *
+                                * Otherwise, expose a permanent mitigation
+                                * to the guest, and hide SSBS so that the
+                                * guest stays protected.
+                                */
+                               if (cpus_have_final_cap(ARM64_SSBS))
+                                       break;
+                               fallthrough;
+                       case SPECTRE_UNAFFECTED:
                                val = SMCCC_RET_NOT_REQUIRED;
                                break;
                        }
index 87e6e3818fb5846ce1c3f567b974ab0536d1c064..db4056ecccfda9319233e7be71c27d8d9db16c84 100644 (file)
@@ -435,14 +435,19 @@ static int get_kernel_wa_level(u64 regid)
                }
                return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
-               switch (arm64_get_ssbd_state()) {
-               case ARM64_SSBD_FORCE_ENABLE:
-               case ARM64_SSBD_MITIGATED:
-               case ARM64_SSBD_KERNEL:
+               switch (arm64_get_spectre_v4_state()) {
+               case SPECTRE_MITIGATED:
+                       /*
+                        * As for the hypercall discovery, we pretend we
+                        * don't have any FW mitigation if SSBS is there at
+                        * all times.
+                        */
+                       if (cpus_have_final_cap(ARM64_SSBS))
+                               return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
+                       fallthrough;
+               case SPECTRE_UNAFFECTED:
                        return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
-               case ARM64_SSBD_UNKNOWN:
-               case ARM64_SSBD_FORCE_DISABLE:
-               default:
+               case SPECTRE_VULNERABLE:
                        return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
                }
        }