[RFC PATCH part-2 09/17] pkvm: x86: Initialize vmcs host state area for host vcpu

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

 



The VMCS host state shall keep the pKVM running state before switch
to guest (host VM for now). Most of such states are setup by pKVM init
code and can get from predefined value (e.g. CS/SS etc.) or pkvm_pcpu data
structure (e.g. GDT/IDT/TSS & cr3), a few states are initialized directly
from host native as they can just follow host Linux setting (e.g. EFER,
PAT, CR0).

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 | 40 +++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
index 5ed64ed2a801..9634bbccfbdd 100644
--- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c
+++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
@@ -241,6 +241,45 @@ static __init void init_guest_state_area(struct pkvm_host_vcpu *vcpu, int cpu)
 	vmcs_write64(VMCS_LINK_POINTER, -1ull);
 }
 
+static __init void _init_host_state_area(struct pkvm_pcpu *pcpu)
+{
+	unsigned long a;
+
+	vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS);
+	vmcs_writel(HOST_CR3, pcpu->cr3);
+	vmcs_writel(HOST_CR4, native_read_cr4());
+
+	vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS);
+	vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS);
+	vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS);
+	vmcs_write16(HOST_ES_SELECTOR, 0);
+	vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8);
+	vmcs_write16(HOST_FS_SELECTOR, 0);
+	vmcs_write16(HOST_GS_SELECTOR, 0);
+	vmcs_writel(HOST_FS_BASE, 0);
+	vmcs_writel(HOST_GS_BASE, 0);
+
+	vmcs_writel(HOST_TR_BASE, (unsigned long)&pcpu->tss);
+	vmcs_writel(HOST_GDTR_BASE, (unsigned long)(&pcpu->gdt_page));
+	vmcs_writel(HOST_IDTR_BASE, (unsigned long)(&pcpu->idt_page));
+
+	/* MSR area */
+	rdmsrl(MSR_EFER, a);
+	vmcs_write64(HOST_IA32_EFER, a);
+
+	rdmsrl(MSR_IA32_CR_PAT, a);
+	vmcs_write64(HOST_IA32_PAT, a);
+}
+
+static __init void init_host_state_area(struct pkvm_host_vcpu *vcpu)
+{
+	struct pkvm_pcpu *pcpu = vcpu->pcpu;
+
+	_init_host_state_area(pcpu);
+
+	/*TODO: add HOST_RIP */
+}
+
 static __init int pkvm_host_init_vmx(struct pkvm_host_vcpu *vcpu, int cpu)
 {
 	struct vcpu_vmx *vmx = &vcpu->vmx;
@@ -265,6 +304,7 @@ static __init int pkvm_host_init_vmx(struct pkvm_host_vcpu *vcpu, int cpu)
 	vmcs_load(vmx->loaded_vmcs->vmcs);
 
 	init_guest_state_area(vcpu, cpu);
+	init_host_state_area(vcpu);
 
 	return ret;
 }
-- 
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