[Devel] [PATCH RHEL9 COMMIT] ms/KVM: VMX: Reset eVMCS controls in VP assist page during hardware disabling

Konstantin Khorenko khorenko at virtuozzo.com
Wed Nov 1 16:42:52 MSK 2023


The commit is pushed to "branch-rh9-5.14.0-284.25.1.vz9.30.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-284.25.1.vz9.30.6
------>
commit f89a8ad38faf4eec2e6cd0888bb42cdde1dd676e
Author: Maxim Levitsky <mlevitsk at redhat.com>
Date:   Tue Apr 25 08:56:47 2023 +0300

    ms/KVM: VMX: Reset eVMCS controls in VP assist page during hardware disabling
    
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2177720
    
    commit 2916b70fc342719f570640de07251b7f91feebdb
    Author: Sean Christopherson <seanjc at google.com>
    Date:   Wed Nov 30 23:08:54 2022 +0000
    
        KVM: VMX: Reset eVMCS controls in VP assist page during hardware disabling
    
        Reset the eVMCS controls in the per-CPU VP assist page during hardware
        disabling instead of waiting until kvm-intel's module exit.  The controls
        are activated if and only if KVM creates a VM, i.e. don't need to be
        reset if hardware is never enabled.
    
        Doing the reset during hardware disabling will naturally fix a potential
        NULL pointer deref bug once KVM disables CPU hotplug while enabling and
        disabling hardware (which is necessary to fix a variety of bugs).  If the
        kernel is running as the root partition, the VP assist page is unmapped
        during CPU hot unplug, and so KVM's clearing of the eVMCS controls needs
        to occur with CPU hot(un)plug disabled, otherwise KVM could attempt to
        write to a CPU's VP assist page after it's unmapped.
    
        Reported-by: Vitaly Kuznetsov <vkuznets at redhat.com>
        Signed-off-by: Sean Christopherson <seanjc at google.com>
        Reviewed-by: Vitaly Kuznetsov <vkuznets at redhat.com>
        Message-Id: <20221130230934.1014142-11-seanjc at google.com>
        Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    
    Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
    
    (cherry picked from CentOS 9 Stream commit 9828ea8dc4fb)
    https://pmc.acronis.work/browse/VSTOR-76102
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
    
    Feature: fix ms/KVM
---
 arch/x86/kvm/vmx/vmx.c | 50 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 2f792d84226c..e0c507fcd09e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -552,6 +552,33 @@ static int hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static void hv_reset_evmcs(void)
+{
+	struct hv_vp_assist_page *vp_ap;
+
+	if (!static_branch_unlikely(&enable_evmcs))
+		return;
+
+	/*
+	 * KVM should enable eVMCS if and only if all CPUs have a VP assist
+	 * page, and should reject CPU onlining if eVMCS is enabled the CPU
+	 * doesn't have a VP assist page allocated.
+	 */
+	vp_ap = hv_get_vp_assist_page(smp_processor_id());
+	if (WARN_ON_ONCE(!vp_ap))
+		return;
+
+	/*
+	 * Reset everything to support using non-enlightened VMCS access later
+	 * (e.g. when we reload the module with enlightened_vmcs=0)
+	 */
+	vp_ap->nested_control.features.directhypercall = 0;
+	vp_ap->current_nested_vmcs = 0;
+	vp_ap->enlighten_vmentry = 0;
+}
+
+#else /* IS_ENABLED(CONFIG_HYPERV) */
+static void hv_reset_evmcs(void) {}
 #endif /* IS_ENABLED(CONFIG_HYPERV) */
 
 /*
@@ -2483,6 +2510,8 @@ static void vmx_hardware_disable(void)
 	if (cpu_vmxoff())
 		kvm_spurious_fault();
 
+	hv_reset_evmcs();
+
 	intel_pt_handle_vmx(0);
 }
 
@@ -8410,27 +8439,8 @@ static void vmx_exit(void)
 	kvm_exit();
 
 #if IS_ENABLED(CONFIG_HYPERV)
-	if (static_branch_unlikely(&enable_evmcs)) {
-		int cpu;
-		struct hv_vp_assist_page *vp_ap;
-		/*
-		 * Reset everything to support using non-enlightened VMCS
-		 * access later (e.g. when we reload the module with
-		 * enlightened_vmcs=0)
-		 */
-		for_each_online_cpu(cpu) {
-			vp_ap =	hv_get_vp_assist_page(cpu);
-
-			if (!vp_ap)
-				continue;
-
-			vp_ap->nested_control.features.directhypercall = 0;
-			vp_ap->current_nested_vmcs = 0;
-			vp_ap->enlighten_vmentry = 0;
-		}
-
+	if (static_branch_unlikely(&enable_evmcs))
 		static_branch_disable(&enable_evmcs);
-	}
 #endif
 	vmx_cleanup_l1d_flush();
 


More information about the Devel mailing list