Skip to content

Commit 2ea1e35

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
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
2 parents 9a6b871 + dbaff30 commit 2ea1e35

File tree

3 files changed

+65
-51
lines changed

3 files changed

+65
-51
lines changed

arch/x86/kvm/mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4448,7 +4448,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
44484448
* zap all shadow pages.
44494449
*/
44504450
if (unlikely(kvm_current_mmio_generation(kvm) == 0)) {
4451-
printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n");
4451+
printk_ratelimited(KERN_DEBUG "kvm: zapping shadow pages for mmio generation wraparound\n");
44524452
kvm_mmu_invalidate_zap_all_pages(kvm);
44534453
}
44544454
}

arch/x86/kvm/vmx.c

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5840,53 +5840,10 @@ static __init int hardware_setup(void)
58405840
memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
58415841
memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
58425842

5843-
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
5844-
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
5845-
vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
5846-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
5847-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
5848-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
5849-
vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
5850-
5851-
memcpy(vmx_msr_bitmap_legacy_x2apic,
5852-
vmx_msr_bitmap_legacy, PAGE_SIZE);
5853-
memcpy(vmx_msr_bitmap_longmode_x2apic,
5854-
vmx_msr_bitmap_longmode, PAGE_SIZE);
5855-
5856-
if (enable_apicv) {
5857-
for (msr = 0x800; msr <= 0x8ff; msr++)
5858-
vmx_disable_intercept_msr_read_x2apic(msr);
5859-
5860-
/* According SDM, in x2apic mode, the whole id reg is used.
5861-
* But in KVM, it only use the highest eight bits. Need to
5862-
* intercept it */
5863-
vmx_enable_intercept_msr_read_x2apic(0x802);
5864-
/* TMCCT */
5865-
vmx_enable_intercept_msr_read_x2apic(0x839);
5866-
/* TPR */
5867-
vmx_disable_intercept_msr_write_x2apic(0x808);
5868-
/* EOI */
5869-
vmx_disable_intercept_msr_write_x2apic(0x80b);
5870-
/* SELF-IPI */
5871-
vmx_disable_intercept_msr_write_x2apic(0x83f);
5872-
}
5873-
5874-
if (enable_ept) {
5875-
kvm_mmu_set_mask_ptes(0ull,
5876-
(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
5877-
(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
5878-
0ull, VMX_EPT_EXECUTABLE_MASK);
5879-
ept_set_mmio_spte_mask();
5880-
kvm_enable_tdp();
5881-
} else
5882-
kvm_disable_tdp();
5883-
5884-
update_ple_window_actual_max();
5885-
58865843
if (setup_vmcs_config(&vmcs_config) < 0) {
58875844
r = -EIO;
58885845
goto out7;
5889-
}
5846+
}
58905847

58915848
if (boot_cpu_has(X86_FEATURE_NX))
58925849
kvm_enable_efer_bits(EFER_NX);
@@ -5945,6 +5902,49 @@ static __init int hardware_setup(void)
59455902
if (nested)
59465903
nested_vmx_setup_ctls_msrs();
59475904

5905+
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
5906+
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
5907+
vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
5908+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
5909+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
5910+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
5911+
vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
5912+
5913+
memcpy(vmx_msr_bitmap_legacy_x2apic,
5914+
vmx_msr_bitmap_legacy, PAGE_SIZE);
5915+
memcpy(vmx_msr_bitmap_longmode_x2apic,
5916+
vmx_msr_bitmap_longmode, PAGE_SIZE);
5917+
5918+
if (enable_apicv) {
5919+
for (msr = 0x800; msr <= 0x8ff; msr++)
5920+
vmx_disable_intercept_msr_read_x2apic(msr);
5921+
5922+
/* According SDM, in x2apic mode, the whole id reg is used.
5923+
* But in KVM, it only use the highest eight bits. Need to
5924+
* intercept it */
5925+
vmx_enable_intercept_msr_read_x2apic(0x802);
5926+
/* TMCCT */
5927+
vmx_enable_intercept_msr_read_x2apic(0x839);
5928+
/* TPR */
5929+
vmx_disable_intercept_msr_write_x2apic(0x808);
5930+
/* EOI */
5931+
vmx_disable_intercept_msr_write_x2apic(0x80b);
5932+
/* SELF-IPI */
5933+
vmx_disable_intercept_msr_write_x2apic(0x83f);
5934+
}
5935+
5936+
if (enable_ept) {
5937+
kvm_mmu_set_mask_ptes(0ull,
5938+
(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
5939+
(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
5940+
0ull, VMX_EPT_EXECUTABLE_MASK);
5941+
ept_set_mmio_spte_mask();
5942+
kvm_enable_tdp();
5943+
} else
5944+
kvm_disable_tdp();
5945+
5946+
update_ple_window_actual_max();
5947+
59485948
return alloc_kvm_area();
59495949

59505950
out7:

virt/kvm/kvm_main.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ static void update_memslots(struct kvm_memslots *slots,
671671

672672
WARN_ON(mslots[i].id != id);
673673
if (!new->npages) {
674+
WARN_ON(!mslots[i].npages);
674675
new->base_gfn = 0;
675676
if (mslots[i].npages)
676677
slots->used_slots--;
@@ -687,12 +688,25 @@ static void update_memslots(struct kvm_memslots *slots,
687688
slots->id_to_index[mslots[i].id] = i;
688689
i++;
689690
}
690-
while (i > 0 &&
691-
new->base_gfn > mslots[i - 1].base_gfn) {
692-
mslots[i] = mslots[i - 1];
693-
slots->id_to_index[mslots[i].id] = i;
694-
i--;
695-
}
691+
692+
/*
693+
* The ">=" is needed when creating a slot with base_gfn == 0,
694+
* so that it moves before all those with base_gfn == npages == 0.
695+
*
696+
* On the other hand, if new->npages is zero, the above loop has
697+
* already left i pointing to the beginning of the empty part of
698+
* mslots, and the ">=" would move the hole backwards in this
699+
* case---which is wrong. So skip the loop when deleting a slot.
700+
*/
701+
if (new->npages) {
702+
while (i > 0 &&
703+
new->base_gfn >= mslots[i - 1].base_gfn) {
704+
mslots[i] = mslots[i - 1];
705+
slots->id_to_index[mslots[i].id] = i;
706+
i--;
707+
}
708+
} else
709+
WARN_ON_ONCE(i != slots->used_slots);
696710

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

0 commit comments

Comments
 (0)