Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ea1e35a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull KVM fixes from Paolo Bonzini:
 "The important fixes are for two bugs introduced by the merge window.

  On top of this, add a couple of WARN_ONs and stop spamming dmesg on
  pretty much every boot of a virtual machine"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  kvm: warn on more invariant breakage
  kvm: fix sorting of memslots with base_gfn == 0
  kvm: x86: drop severity of "generation wraparound" message
  kvm: x86: vmx: reorder some msr writing
parents 9a6b871d dbaff309
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -4448,7 +4448,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
	 * zap all shadow pages.
	 * zap all shadow pages.
	 */
	 */
	if (unlikely(kvm_current_mmio_generation(kvm) == 0)) {
	if (unlikely(kvm_current_mmio_generation(kvm) == 0)) {
		printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n");
		printk_ratelimited(KERN_DEBUG "kvm: zapping shadow pages for mmio generation wraparound\n");
		kvm_mmu_invalidate_zap_all_pages(kvm);
		kvm_mmu_invalidate_zap_all_pages(kvm);
	}
	}
}
}
+44 −44
Original line number Original line Diff line number Diff line
@@ -5840,49 +5840,6 @@ static __init int hardware_setup(void)
	memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
	memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
	memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
	memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);


	vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
	vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
	vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
	vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);

	memcpy(vmx_msr_bitmap_legacy_x2apic,
			vmx_msr_bitmap_legacy, PAGE_SIZE);
	memcpy(vmx_msr_bitmap_longmode_x2apic,
			vmx_msr_bitmap_longmode, PAGE_SIZE);

	if (enable_apicv) {
		for (msr = 0x800; msr <= 0x8ff; msr++)
			vmx_disable_intercept_msr_read_x2apic(msr);

		/* According SDM, in x2apic mode, the whole id reg is used.
		 * But in KVM, it only use the highest eight bits. Need to
		 * intercept it */
		vmx_enable_intercept_msr_read_x2apic(0x802);
		/* TMCCT */
		vmx_enable_intercept_msr_read_x2apic(0x839);
		/* TPR */
		vmx_disable_intercept_msr_write_x2apic(0x808);
		/* EOI */
		vmx_disable_intercept_msr_write_x2apic(0x80b);
		/* SELF-IPI */
		vmx_disable_intercept_msr_write_x2apic(0x83f);
	}

	if (enable_ept) {
		kvm_mmu_set_mask_ptes(0ull,
			(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
			(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
			0ull, VMX_EPT_EXECUTABLE_MASK);
		ept_set_mmio_spte_mask();
		kvm_enable_tdp();
	} else
		kvm_disable_tdp();

	update_ple_window_actual_max();

	if (setup_vmcs_config(&vmcs_config) < 0) {
	if (setup_vmcs_config(&vmcs_config) < 0) {
		r = -EIO;
		r = -EIO;
		goto out7;
		goto out7;
@@ -5945,6 +5902,49 @@ static __init int hardware_setup(void)
	if (nested)
	if (nested)
		nested_vmx_setup_ctls_msrs();
		nested_vmx_setup_ctls_msrs();


	vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
	vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
	vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
	vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);

	memcpy(vmx_msr_bitmap_legacy_x2apic,
			vmx_msr_bitmap_legacy, PAGE_SIZE);
	memcpy(vmx_msr_bitmap_longmode_x2apic,
			vmx_msr_bitmap_longmode, PAGE_SIZE);

	if (enable_apicv) {
		for (msr = 0x800; msr <= 0x8ff; msr++)
			vmx_disable_intercept_msr_read_x2apic(msr);

		/* According SDM, in x2apic mode, the whole id reg is used.
		 * But in KVM, it only use the highest eight bits. Need to
		 * intercept it */
		vmx_enable_intercept_msr_read_x2apic(0x802);
		/* TMCCT */
		vmx_enable_intercept_msr_read_x2apic(0x839);
		/* TPR */
		vmx_disable_intercept_msr_write_x2apic(0x808);
		/* EOI */
		vmx_disable_intercept_msr_write_x2apic(0x80b);
		/* SELF-IPI */
		vmx_disable_intercept_msr_write_x2apic(0x83f);
	}

	if (enable_ept) {
		kvm_mmu_set_mask_ptes(0ull,
			(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
			(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
			0ull, VMX_EPT_EXECUTABLE_MASK);
		ept_set_mmio_spte_mask();
		kvm_enable_tdp();
	} else
		kvm_disable_tdp();

	update_ple_window_actual_max();

	return alloc_kvm_area();
	return alloc_kvm_area();


out7:
out7:
+20 −6
Original line number Original line Diff line number Diff line
@@ -671,6 +671,7 @@ static void update_memslots(struct kvm_memslots *slots,


	WARN_ON(mslots[i].id != id);
	WARN_ON(mslots[i].id != id);
	if (!new->npages) {
	if (!new->npages) {
		WARN_ON(!mslots[i].npages);
		new->base_gfn = 0;
		new->base_gfn = 0;
		if (mslots[i].npages)
		if (mslots[i].npages)
			slots->used_slots--;
			slots->used_slots--;
@@ -687,12 +688,25 @@ static void update_memslots(struct kvm_memslots *slots,
		slots->id_to_index[mslots[i].id] = i;
		slots->id_to_index[mslots[i].id] = i;
		i++;
		i++;
	}
	}

	/*
	 * The ">=" is needed when creating a slot with base_gfn == 0,
	 * so that it moves before all those with base_gfn == npages == 0.
	 *
	 * On the other hand, if new->npages is zero, the above loop has
	 * already left i pointing to the beginning of the empty part of
	 * mslots, and the ">=" would move the hole backwards in this
	 * case---which is wrong.  So skip the loop when deleting a slot.
	 */
	if (new->npages) {
		while (i > 0 &&
		while (i > 0 &&
	       new->base_gfn > mslots[i - 1].base_gfn) {
		       new->base_gfn >= mslots[i - 1].base_gfn) {
			mslots[i] = mslots[i - 1];
			mslots[i] = mslots[i - 1];
			slots->id_to_index[mslots[i].id] = i;
			slots->id_to_index[mslots[i].id] = i;
			i--;
			i--;
		}
		}
	} else
		WARN_ON_ONCE(i != slots->used_slots);


	mslots[i] = *new;
	mslots[i] = *new;
	slots->id_to_index[mslots[i].id] = i;
	slots->id_to_index[mslots[i].id] = i;