Skip to content

Commit 4e59516

Browse files
peterfeinerbonzini
authored andcommitted
kvm: vmx: ensure VMCS is current while enabling PML
Between loading the new VMCS and enabling PML, the CPU was unpinned. If the vCPU thread were migrated to another CPU in the interim (e.g., due to preemption or sleeping alloc_page), then the VMWRITEs to enable PML would target the wrong VMCS -- or no VMCS at all: [ 2087.266950] vmwrite error: reg 200e value 3fe1d52000 (err -506126336) [ 2087.267062] vmwrite error: reg 812 value 1ff (err 511) [ 2087.267125] vmwrite error: reg 401e value 12229c00 (err 304258048) This patch ensures that the VMCS remains current while enabling PML by doing the VMWRITEs while the CPU is pinned. Allocation of the PML buffer is hoisted out of the critical section. Signed-off-by: Peter Feiner <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 9770404 commit 4e59516

File tree

1 file changed

+24
-32
lines changed

1 file changed

+24
-32
lines changed

arch/x86/kvm/vmx.c

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4979,6 +4979,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
49794979
if (vmx_xsaves_supported())
49804980
vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP);
49814981

4982+
if (enable_pml) {
4983+
ASSERT(vmx->pml_pg);
4984+
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
4985+
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
4986+
}
4987+
49824988
return 0;
49834989
}
49844990

@@ -7937,22 +7943,6 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
79377943
*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
79387944
}
79397945

7940-
static int vmx_create_pml_buffer(struct vcpu_vmx *vmx)
7941-
{
7942-
struct page *pml_pg;
7943-
7944-
pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
7945-
if (!pml_pg)
7946-
return -ENOMEM;
7947-
7948-
vmx->pml_pg = pml_pg;
7949-
7950-
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
7951-
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
7952-
7953-
return 0;
7954-
}
7955-
79567946
static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
79577947
{
79587948
if (vmx->pml_pg) {
@@ -8885,14 +8875,26 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
88858875
if (err)
88868876
goto free_vcpu;
88878877

8878+
err = -ENOMEM;
8879+
8880+
/*
8881+
* If PML is turned on, failure on enabling PML just results in failure
8882+
* of creating the vcpu, therefore we can simplify PML logic (by
8883+
* avoiding dealing with cases, such as enabling PML partially on vcpus
8884+
* for the guest, etc.
8885+
*/
8886+
if (enable_pml) {
8887+
vmx->pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
8888+
if (!vmx->pml_pg)
8889+
goto uninit_vcpu;
8890+
}
8891+
88888892
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
88898893
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
88908894
> PAGE_SIZE);
88918895

8892-
err = -ENOMEM;
8893-
if (!vmx->guest_msrs) {
8894-
goto uninit_vcpu;
8895-
}
8896+
if (!vmx->guest_msrs)
8897+
goto free_pml;
88968898

88978899
vmx->loaded_vmcs = &vmx->vmcs01;
88988900
vmx->loaded_vmcs->vmcs = alloc_vmcs();
@@ -8936,25 +8938,15 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
89368938
vmx->nested.current_vmptr = -1ull;
89378939
vmx->nested.current_vmcs12 = NULL;
89388940

8939-
/*
8940-
* If PML is turned on, failure on enabling PML just results in failure
8941-
* of creating the vcpu, therefore we can simplify PML logic (by
8942-
* avoiding dealing with cases, such as enabling PML partially on vcpus
8943-
* for the guest, etc.
8944-
*/
8945-
if (enable_pml) {
8946-
err = vmx_create_pml_buffer(vmx);
8947-
if (err)
8948-
goto free_vmcs;
8949-
}
8950-
89518941
return &vmx->vcpu;
89528942

89538943
free_vmcs:
89548944
free_vpid(vmx->nested.vpid02);
89558945
free_loaded_vmcs(vmx->loaded_vmcs);
89568946
free_msrs:
89578947
kfree(vmx->guest_msrs);
8948+
free_pml:
8949+
vmx_destroy_pml_buffer(vmx);
89588950
uninit_vcpu:
89598951
kvm_vcpu_uninit(&vmx->vcpu);
89608952
free_vcpu:

0 commit comments

Comments
 (0)