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