Commit 072c0b4f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull x86 kvm fixes from Paolo Bonzini:
 "x86 fixes.  Everyone else is already in holiday mood apparently.

   - Add a missing 'break' to fix param parsing in the rseq selftest

   - Apply runtime updates to the _current_ CPUID when userspace is
     setting CPUID, e.g. as part of vCPU hotplug, to fix a false
     positive and to avoid dropping the pending update

   - Disallow toggling KVM_MEM_GUEST_MEMFD on an existing memslot, as
     it's not supported by KVM and leads to a use-after-free due to KVM
     failing to unbind the memslot from the previously-associated
     guest_memfd instance

   - Harden against similar KVM_MEM_GUEST_MEMFD goofs, and prepare for
     supporting flags-only changes on KVM_MEM_GUEST_MEMFD memlslots,
     e.g. for dirty logging

   - Set exit_code[63:32] to -1 (all 0xffs) when synthesizing a nested
     SVM_EXIT_ERR (a.k.a. VMEXIT_INVALID) #VMEXIT, as VMEXIT_INVALID is
     defined as -1ull (a 64-bit value)

   - Update SVI when activating APICv to fix a bug where a
     post-activation EOI for an in-service IRQ would effective be lost
     due to SVI being stale

   - Immediately refresh APICv controls (if necessary) on a nested
     VM-Exit instead of deferring the update via KVM_REQ_APICV_UPDATE,
     as the request is effectively ignored because KVM thinks the vCPU
     already has the correct APICv settings"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: nVMX: Immediately refresh APICv controls as needed on nested VM-Exit
  KVM: VMX: Update SVI during runtime APICv activation
  KVM: nSVM: Set exit_code_hi to -1 when synthesizing SVM_EXIT_ERR (failed VMRUN)
  KVM: nSVM: Clear exit_code_hi in VMCB when synthesizing nested VM-Exits
  KVM: Harden and prepare for modifying existing guest_memfd memslots
  KVM: Disallow toggling KVM_MEM_GUEST_MEMFD on an existing memslot
  KVM: selftests: Add a CPUID testcase for KVM_SET_CPUID2 with runtime updates
  KVM: x86: Apply runtime updates to current CPUID during KVM_SET_CPUID{,2}
  KVM: selftests: Add missing "break" in rseq_test's param parsing
parents 255a918a 0499add8
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -509,11 +509,18 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
	u32 vcpu_caps[NR_KVM_CPU_CAPS];
	int r;

	/*
	 * Apply pending runtime CPUID updates to the current CPUID entries to
	 * avoid false positives due to mismatches on KVM-owned feature flags.
	 */
	if (vcpu->arch.cpuid_dynamic_bits_dirty)
		kvm_update_cpuid_runtime(vcpu);

	/*
	 * Swap the existing (old) entries with the incoming (new) entries in
	 * order to massage the new entries, e.g. to account for dynamic bits
	 * that KVM controls, without clobbering the current guest CPUID, which
	 * KVM needs to preserve in order to unwind on failure.
	 * that KVM controls, without losing the current guest CPUID, which KVM
	 * needs to preserve in order to unwind on failure.
	 *
	 * Similarly, save the vCPU's current cpu_caps so that the capabilities
	 * can be updated alongside the CPUID entries when performing runtime
+2 −2
Original line number Diff line number Diff line
@@ -985,7 +985,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
	if (!nested_vmcb_check_save(vcpu) ||
	    !nested_vmcb_check_controls(vcpu)) {
		vmcb12->control.exit_code    = SVM_EXIT_ERR;
		vmcb12->control.exit_code_hi = 0;
		vmcb12->control.exit_code_hi = -1u;
		vmcb12->control.exit_info_1  = 0;
		vmcb12->control.exit_info_2  = 0;
		goto out;
@@ -1018,7 +1018,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
	svm->soft_int_injected = false;

	svm->vmcb->control.exit_code    = SVM_EXIT_ERR;
	svm->vmcb->control.exit_code_hi = 0;
	svm->vmcb->control.exit_code_hi = -1u;
	svm->vmcb->control.exit_info_1  = 0;
	svm->vmcb->control.exit_info_2  = 0;

+2 −0
Original line number Diff line number Diff line
@@ -2443,6 +2443,7 @@ static bool check_selective_cr0_intercepted(struct kvm_vcpu *vcpu,

	if (cr0 ^ val) {
		svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
		svm->vmcb->control.exit_code_hi = 0;
		ret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE);
	}

@@ -4617,6 +4618,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
	if (static_cpu_has(X86_FEATURE_NRIPS))
		vmcb->control.next_rip  = info->next_rip;
	vmcb->control.exit_code = icpt_info.exit_code;
	vmcb->control.exit_code_hi = 0;
	vmexit = nested_svm_exit_handled(svm);

	ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED
+4 −3
Original line number Diff line number Diff line
@@ -762,6 +762,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm);
static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)
{
	svm->vmcb->control.exit_code	= exit_code;
	svm->vmcb->control.exit_code_hi	= 0;
	svm->vmcb->control.exit_info_1	= 0;
	svm->vmcb->control.exit_info_2	= 0;
	return nested_svm_vmexit(svm);
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "trace.h"
#include "vmx.h"
#include "smm.h"
#include "x86_ops.h"

static bool __read_mostly enable_shadow_vmcs = 1;
module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO);
@@ -5165,7 +5166,7 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,

	if (vmx->nested.update_vmcs01_apicv_status) {
		vmx->nested.update_vmcs01_apicv_status = false;
		kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
		vmx_refresh_apicv_exec_ctrl(vcpu);
	}

	if (vmx->nested.update_vmcs01_hwapic_isr) {
Loading