KVM: SVM: Move GHCB unmapping to fix RCU warning
authorTom Lendacky <thomas.lendacky@amd.com>
Thu, 6 May 2021 20:14:41 +0000 (15:14 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 7 May 2021 10:06:23 +0000 (06:06 -0400)
When an SEV-ES guest is running, the GHCB is unmapped as part of the
vCPU run support. However, kvm_vcpu_unmap() triggers an RCU dereference
warning with CONFIG_PROVE_LOCKING=y because the SRCU lock is released
before invoking the vCPU run support.

Move the GHCB unmapping into the prepare_guest_switch callback, which is
invoked while still holding the SRCU lock, eliminating the RCU dereference
warning.

Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT")
Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <b2f9b79d15166f2c3e4375c0d9bc3268b7696455.1620332081.git.thomas.lendacky@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index eb241c1a4add3ae45d0f6eba61a081d17b71619d..5bc887e9a9860ea73ed6bd798d93e855f2c45be8 100644 (file)
@@ -2197,7 +2197,7 @@ vmgexit_err:
        return -EINVAL;
 }
 
-static void pre_sev_es_run(struct vcpu_svm *svm)
+void sev_es_unmap_ghcb(struct vcpu_svm *svm)
 {
        if (!svm->ghcb)
                return;
@@ -2233,9 +2233,6 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu)
        struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
        int asid = sev_get_asid(svm->vcpu.kvm);
 
-       /* Perform any SEV-ES pre-run actions */
-       pre_sev_es_run(svm);
-
        /* Assign the asid allocated with this SEV guest */
        svm->asid = asid;
 
index 8124f51e9488f3b5e9d7972981352b4bfce2536d..4dd9b7856e5b125b3ae59a6d27e4b1d45f1dd4d7 100644 (file)
@@ -1437,6 +1437,9 @@ static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
        struct vcpu_svm *svm = to_svm(vcpu);
        struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
 
+       if (sev_es_guest(vcpu->kvm))
+               sev_es_unmap_ghcb(svm);
+
        if (svm->guest_state_loaded)
                return;
 
index 84b3133c2251d1c2abcb4f99dd8d0dd1e6e0351e..e44567ceb8655aa9d214383460bca421ddfa141e 100644 (file)
@@ -581,6 +581,7 @@ void sev_es_init_vmcb(struct vcpu_svm *svm);
 void sev_es_create_vcpu(struct vcpu_svm *svm);
 void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);
 void sev_es_prepare_guest_switch(struct vcpu_svm *svm, unsigned int cpu);
+void sev_es_unmap_ghcb(struct vcpu_svm *svm);
 
 /* vmenter.S */