[RFC PATCH part-2 07/17] pkvm: x86: Allocate vmcs and msr bitmap pages for host vcpu

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



VMCS page is key control structure to do VMX operations, and allocate it
with revision id (setup by __setup_vmcs_config) for host vcpu during its
VMX initialization. Later VMX ops VMPTRLD makes it as current VMCS pointer
to do VMCS fields setup through VMWRITE then run host VM through
VMLAUNCH.

pKVM enables "use MSR bitmaps" VM-execution control to intercept and
emulate necessary MSR (e,g, VMX MSR). It needs to setup a MSR bitmaps
page in VMCS field, and such page is allocated during host vcpu VMX
initialization in this patch as well.

Make use of vcpu_vmx->vmcs01 to record this information for host vcpu.

Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx>
Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx>
---
 arch/x86/kvm/vmx/pkvm/pkvm_host.c | 54 ++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
index 6b937192e901..272205977e1e 100644
--- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c
+++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
@@ -39,6 +39,28 @@ static void pkvm_early_free(void *ptr, int pages)
 	free_pages_exact(ptr, pages << PAGE_SHIFT);
 }
 
+static struct vmcs *pkvm_alloc_vmcs(struct vmcs_config *vmcs_config_ptr)
+{
+	struct vmcs *vmcs;
+	int pages = ALIGN(vmcs_config_ptr->size, PAGE_SIZE) >> PAGE_SHIFT;
+
+	vmcs = pkvm_early_alloc_contig(pages);
+	if (!vmcs)
+		return NULL;
+
+	memset(vmcs, 0, vmcs_config_ptr->size);
+	vmcs->hdr.revision_id = vmcs_config_ptr->revision_id; /* vmcs revision id */
+
+	return vmcs;
+}
+
+static void pkvm_free_vmcs(void *vmcs, struct vmcs_config *vmcs_config_ptr)
+{
+	int pages = ALIGN(vmcs_config_ptr->size, PAGE_SIZE) >> PAGE_SHIFT;
+
+	pkvm_early_free(vmcs, pages);
+}
+
 static inline void vmxon_setup_revid(void *vmxon_region)
 {
 	u32 rev_id = 0;
@@ -116,12 +138,42 @@ static __init int pkvm_enable_vmx(struct pkvm_host_vcpu *vcpu)
 
 static __init int pkvm_host_init_vmx(struct pkvm_host_vcpu *vcpu)
 {
-	return pkvm_enable_vmx(vcpu);
+	struct vcpu_vmx *vmx = &vcpu->vmx;
+	int ret;
+
+	ret = pkvm_enable_vmx(vcpu);
+	if (ret)
+		return ret;
+
+	/* vmcs01: host vmcs in pKVM */
+	vmx->vmcs01.vmcs = pkvm_alloc_vmcs(&pkvm->vmcs_config);
+	if (!vmx->vmcs01.vmcs)
+		return -ENOMEM;
+
+	vmx->vmcs01.msr_bitmap = pkvm_early_alloc_contig(1);
+	if (!vmx->vmcs01.msr_bitmap) {
+		pr_err("%s: No page for msr_bitmap\n", __func__);
+		return -ENOMEM;
+	}
+
+	return ret;
 }
 
 static __init void pkvm_host_deinit_vmx(struct pkvm_host_vcpu *vcpu)
 {
+	struct vcpu_vmx *vmx = &vcpu->vmx;
+
 	pkvm_cpu_vmxoff();
+
+	if (vmx->vmcs01.vmcs) {
+		pkvm_free_vmcs(vmx->vmcs01.vmcs, &pkvm->vmcs_config);
+		vmx->vmcs01.vmcs = NULL;
+	}
+
+	if (vmx->vmcs01.msr_bitmap) {
+		pkvm_early_free(vmx->vmcs01.msr_bitmap, 1);
+		vmx->vmcs01.msr_bitmap = NULL;
+	}
 }
 
 static __init int pkvm_host_check_and_setup_vmx_cap(struct pkvm_hyp *pkvm)
-- 
2.25.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux