During the VMPTRLD emulation for nested guest, pKVM need to initialize shadow vmcs's host state area based on hypervisor's setting as well, so move this function from pkvm_host.c to hypervisor dir. Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx> --- arch/x86/kvm/vmx/pkvm/hyp/Makefile | 2 +- arch/x86/kvm/vmx/pkvm/hyp/vmx.c | 77 ++++++++++++++++++++++++++++ arch/x86/kvm/vmx/pkvm/hyp/vmx.h | 2 + arch/x86/kvm/vmx/pkvm/include/pkvm.h | 1 + arch/x86/kvm/vmx/pkvm/pkvm_host.c | 75 +-------------------------- 5 files changed, 82 insertions(+), 75 deletions(-) diff --git a/arch/x86/kvm/vmx/pkvm/hyp/Makefile b/arch/x86/kvm/vmx/pkvm/hyp/Makefile index 660fd611395f..ca6d43509ddc 100644 --- a/arch/x86/kvm/vmx/pkvm/hyp/Makefile +++ b/arch/x86/kvm/vmx/pkvm/hyp/Makefile @@ -12,7 +12,7 @@ ccflags-y += -D__PKVM_HYP__ virt-dir := ../../../../../../$(KVM_PKVM) pkvm-hyp-y := vmx_asm.o vmexit.o memory.o early_alloc.o pgtable.o mmu.o pkvm.o \ - init_finalise.o ept.o idt.o irq.o nested.o + init_finalise.o ept.o idt.o irq.o nested.o vmx.o ifndef CONFIG_PKVM_INTEL_DEBUG lib-dir := lib diff --git a/arch/x86/kvm/vmx/pkvm/hyp/vmx.c b/arch/x86/kvm/vmx/pkvm/hyp/vmx.c new file mode 100644 index 000000000000..fec99c567d07 --- /dev/null +++ b/arch/x86/kvm/vmx/pkvm/hyp/vmx.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <pkvm.h> +#include "cpu.h" + +void pkvm_init_host_state_area(struct pkvm_pcpu *pcpu, int cpu) +{ + unsigned long a; +#ifdef CONFIG_PKVM_INTEL_DEBUG + u32 high, low; + struct desc_ptr dt; + u16 selector; +#endif + + vmcs_writel(HOST_CR0, native_read_cr0() & ~X86_CR0_TS); + vmcs_writel(HOST_CR3, pcpu->cr3); + vmcs_writel(HOST_CR4, native_read_cr4()); + +#ifdef CONFIG_PKVM_INTEL_DEBUG + savesegment(cs, selector); + vmcs_write16(HOST_CS_SELECTOR, selector); + savesegment(ss, selector); + vmcs_write16(HOST_SS_SELECTOR, selector); + savesegment(ds, selector); + vmcs_write16(HOST_DS_SELECTOR, selector); + savesegment(es, selector); + vmcs_write16(HOST_ES_SELECTOR, selector); + savesegment(fs, selector); + vmcs_write16(HOST_FS_SELECTOR, selector); + pkvm_rdmsrl(MSR_FS_BASE, a); + vmcs_writel(HOST_FS_BASE, a); + savesegment(gs, selector); + vmcs_write16(HOST_GS_SELECTOR, selector); + pkvm_rdmsrl(MSR_GS_BASE, a); + vmcs_writel(HOST_GS_BASE, a); + + vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); + vmcs_writel(HOST_TR_BASE, (unsigned long)&get_cpu_entry_area(cpu)->tss.x86_tss); + + native_store_gdt(&dt); + vmcs_writel(HOST_GDTR_BASE, dt.address); + vmcs_writel(HOST_IDTR_BASE, (unsigned long)(&pcpu->idt_page)); + + pkvm_rdmsr(MSR_IA32_SYSENTER_CS, low, high); + vmcs_write32(HOST_IA32_SYSENTER_CS, low); + + pkvm_rdmsrl(MSR_IA32_SYSENTER_ESP, a); + vmcs_writel(HOST_IA32_SYSENTER_ESP, a); + + pkvm_rdmsrl(MSR_IA32_SYSENTER_EIP, a); + vmcs_writel(HOST_IA32_SYSENTER_EIP, a); +#else + 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)); + + vmcs_write16(HOST_GS_SELECTOR, __KERNEL_DS); + vmcs_writel(HOST_GS_BASE, cpu); +#endif + + /* MSR area */ + pkvm_rdmsrl(MSR_EFER, a); + vmcs_write64(HOST_IA32_EFER, a); + + pkvm_rdmsrl(MSR_IA32_CR_PAT, a); + vmcs_write64(HOST_IA32_PAT, a); +} diff --git a/arch/x86/kvm/vmx/pkvm/hyp/vmx.h b/arch/x86/kvm/vmx/pkvm/hyp/vmx.h index 178139d1b61f..35369cc3b646 100644 --- a/arch/x86/kvm/vmx/pkvm/hyp/vmx.h +++ b/arch/x86/kvm/vmx/pkvm/hyp/vmx.h @@ -50,4 +50,6 @@ static inline void vmx_enable_irq_window(struct vcpu_vmx *vmx) exec_controls_setbit(vmx, CPU_BASED_INTR_WINDOW_EXITING); } +void pkvm_init_host_state_area(struct pkvm_pcpu *pcpu, int cpu); + #endif diff --git a/arch/x86/kvm/vmx/pkvm/include/pkvm.h b/arch/x86/kvm/vmx/pkvm/include/pkvm.h index 292d48d8ee44..d5393d477df1 100644 --- a/arch/x86/kvm/vmx/pkvm/include/pkvm.h +++ b/arch/x86/kvm/vmx/pkvm/include/pkvm.h @@ -98,6 +98,7 @@ extern struct pkvm_hyp *pkvm_sym(pkvm_hyp); PKVM_DECLARE(void, __pkvm_vmx_vmexit(void)); PKVM_DECLARE(int, pkvm_main(struct kvm_vcpu *vcpu)); +PKVM_DECLARE(void, pkvm_init_host_state_area(struct pkvm_pcpu *pcpu, int cpu)); PKVM_DECLARE(void *, pkvm_early_alloc_contig(unsigned int nr_pages)); PKVM_DECLARE(void *, pkvm_early_alloc_page(void)); diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c index 4ea82a147af5..cbba3033ba63 100644 --- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c +++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c @@ -240,84 +240,11 @@ 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, int cpu) -{ - unsigned long a; -#ifdef CONFIG_PKVM_INTEL_DEBUG - u32 high, low; - struct desc_ptr dt; - u16 selector; -#endif - - vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); - vmcs_writel(HOST_CR3, pcpu->cr3); - vmcs_writel(HOST_CR4, native_read_cr4()); - -#ifdef CONFIG_PKVM_INTEL_DEBUG - savesegment(cs, selector); - vmcs_write16(HOST_CS_SELECTOR, selector); - savesegment(ss, selector); - vmcs_write16(HOST_SS_SELECTOR, selector); - savesegment(ds, selector); - vmcs_write16(HOST_DS_SELECTOR, selector); - savesegment(es, selector); - vmcs_write16(HOST_ES_SELECTOR, selector); - savesegment(fs, selector); - vmcs_write16(HOST_FS_SELECTOR, selector); - rdmsrl(MSR_FS_BASE, a); - vmcs_writel(HOST_FS_BASE, a); - savesegment(gs, selector); - vmcs_write16(HOST_GS_SELECTOR, selector); - rdmsrl(MSR_GS_BASE, a); - vmcs_writel(HOST_GS_BASE, a); - - vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); - vmcs_writel(HOST_TR_BASE, (unsigned long)&get_cpu_entry_area(cpu)->tss.x86_tss); - - native_store_gdt(&dt); - vmcs_writel(HOST_GDTR_BASE, dt.address); - vmcs_writel(HOST_IDTR_BASE, (unsigned long)(&pcpu->idt_page)); - - rdmsr(MSR_IA32_SYSENTER_CS, low, high); - vmcs_write32(HOST_IA32_SYSENTER_CS, low); - - rdmsrl(MSR_IA32_SYSENTER_ESP, a); - vmcs_writel(HOST_IA32_SYSENTER_ESP, a); - - rdmsrl(MSR_IA32_SYSENTER_EIP, a); - vmcs_writel(HOST_IA32_SYSENTER_EIP, a); -#else - 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)); - - vmcs_write16(HOST_GS_SELECTOR, __KERNEL_DS); - vmcs_writel(HOST_GS_BASE, cpu); -#endif - - /* 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, int cpu) { struct pkvm_pcpu *pcpu = vcpu->pcpu; - _init_host_state_area(pcpu, cpu); + pkvm_sym(pkvm_init_host_state_area)(pcpu, cpu); /*host RIP*/ vmcs_writel(HOST_RIP, (unsigned long)pkvm_sym(__pkvm_vmx_vmexit)); -- 2.25.1