mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
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
3 changed files with 65 additions and 51 deletions
|
@ -4448,7 +4448,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
|
|||
* zap all shadow pages.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5840,53 +5840,10 @@ static __init int hardware_setup(void)
|
|||
memset(vmx_msr_bitmap_legacy, 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) {
|
||||
r = -EIO;
|
||||
goto out7;
|
||||
}
|
||||
}
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_NX))
|
||||
kvm_enable_efer_bits(EFER_NX);
|
||||
|
@ -5945,6 +5902,49 @@ static __init int hardware_setup(void)
|
|||
if (nested)
|
||||
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();
|
||||
|
||||
out7:
|
||||
|
|
|
@ -671,6 +671,7 @@ static void update_memslots(struct kvm_memslots *slots,
|
|||
|
||||
WARN_ON(mslots[i].id != id);
|
||||
if (!new->npages) {
|
||||
WARN_ON(!mslots[i].npages);
|
||||
new->base_gfn = 0;
|
||||
if (mslots[i].npages)
|
||||
slots->used_slots--;
|
||||
|
@ -687,12 +688,25 @@ static void update_memslots(struct kvm_memslots *slots,
|
|||
slots->id_to_index[mslots[i].id] = i;
|
||||
i++;
|
||||
}
|
||||
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--;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 &&
|
||||
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;
|
||||
slots->id_to_index[mslots[i].id] = i;
|
||||
|
|
Loading…
Reference in a new issue