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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJUn8hXAAoJEL/70l94x66Dme4H/R/HA+Aswgzse8nx3pNiqStv e0BBeUHVJtxlOfnOlJGCWc1ef7uzKdvVWuqCmJwMDJDoLd/I8kF84E3AQS+zTJ/u Dlb+yjwjoFPbQwr8xfclcvYXZxJgleKQJcyBWKBxgMTnFdjgRfX7U0MzXZJ/gFzH mdHhLlNBU/On0l3A+dsKVgjtiuHZIQD0FraYs4qa2QajRGgDoHypzTmwh20XBmdx 3l/zFnSFSbaCTckbKb0xYv22pZTMd/5qrxer05sl98nzrrrXIDhVSo0hbrNVqorv pDr+908XGvTOgVR1cvgkFn74INudiYjNyICGsue/ksmUPh9jz6hWic7sNeqYfcI= =ehkB -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2ea1e35ab1
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5840,53 +5840,10 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot_cpu_has(X86_FEATURE_NX))
|
if (boot_cpu_has(X86_FEATURE_NX))
|
||||||
kvm_enable_efer_bits(EFER_NX);
|
kvm_enable_efer_bits(EFER_NX);
|
||||||
|
@ -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:
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
while (i > 0 &&
|
|
||||||
new->base_gfn > mslots[i - 1].base_gfn) {
|
/*
|
||||||
mslots[i] = mslots[i - 1];
|
* The ">=" is needed when creating a slot with base_gfn == 0,
|
||||||
slots->id_to_index[mslots[i].id] = i;
|
* so that it moves before all those with base_gfn == npages == 0.
|
||||||
i--;
|
*
|
||||||
}
|
* 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 &&
|
||||||
|
new->base_gfn >= mslots[i - 1].base_gfn) {
|
||||||
|
mslots[i] = mslots[i - 1];
|
||||||
|
slots->id_to_index[mslots[i].id] = 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;
|
||||||
|
|
Loading…
Reference in New Issue