Check minimal vmx capabilities requirement for pKVM on Intel platform. Setup vmcs config and vmx cap for later run VCPUs of deprivileged host VM. The vmx capabilities are checked through setup_vmcs_config_common, the same API as KVM. pKVM tries to pass-thru resource to host VM as much as possible, so it does not need to do a lot of emulations; but some capabilities are still required for pKVM's emulations (e.g. EPT, SHADOW_VMCS, MSR_BITMAP etc.), so pKVM has its own different check-set from KVM. Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx> Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx> --- arch/x86/kvm/vmx/pkvm/Makefile | 1 + arch/x86/kvm/vmx/pkvm/include/pkvm.h | 5 +++ arch/x86/kvm/vmx/pkvm/pkvm_host.c | 66 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/arch/x86/kvm/vmx/pkvm/Makefile b/arch/x86/kvm/vmx/pkvm/Makefile index 493bec8501c9..1795d5f9b4b0 100644 --- a/arch/x86/kvm/vmx/pkvm/Makefile +++ b/arch/x86/kvm/vmx/pkvm/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +ccflags-y += -I $(srctree)/arch/x86/kvm ccflags-y += -I $(srctree)/arch/x86/kvm/vmx/pkvm/include pkvm-obj := pkvm_host.o diff --git a/arch/x86/kvm/vmx/pkvm/include/pkvm.h b/arch/x86/kvm/vmx/pkvm/include/pkvm.h index 3fb76665e785..cda599194588 100644 --- a/arch/x86/kvm/vmx/pkvm/include/pkvm.h +++ b/arch/x86/kvm/vmx/pkvm/include/pkvm.h @@ -6,8 +6,13 @@ #ifndef _PKVM_H_ #define _PKVM_H_ +#include <vmx/vmx.h> + struct pkvm_hyp { int num_cpus; + + struct vmx_capability vmx_cap; + struct vmcs_config vmcs_config; }; #define PKVM_PAGES (ALIGN(sizeof(struct pkvm_hyp), PAGE_SIZE) >> PAGE_SHIFT) diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c index 7677df6a2b34..8fd31360faf8 100644 --- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c +++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c @@ -17,6 +17,64 @@ static void *pkvm_early_alloc_contig(int pages) return alloc_pages_exact(pages << PAGE_SHIFT, GFP_KERNEL | __GFP_ZERO); } +static void pkvm_early_free(void *ptr, int pages) +{ + free_pages_exact(ptr, pages << PAGE_SHIFT); +} + +static __init int pkvm_host_check_and_setup_vmx_cap(struct pkvm_hyp *pkvm) +{ + struct vmcs_config *vmcs_config = &pkvm->vmcs_config; + struct vmx_capability *vmx_cap = &pkvm->vmx_cap; + int ret = 0; + struct vmcs_config_setting setting = { + .cpu_based_vm_exec_ctrl_req = + CPU_BASED_INTR_WINDOW_EXITING | + CPU_BASED_USE_MSR_BITMAPS | + CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, + .cpu_based_vm_exec_ctrl_opt = 0, + .secondary_vm_exec_ctrl_req = + SECONDARY_EXEC_ENABLE_EPT | + SECONDARY_EXEC_SHADOW_VMCS, + .secondary_vm_exec_ctrl_opt = + SECONDARY_EXEC_ENABLE_VPID | + SECONDARY_EXEC_ENABLE_INVPCID | + SECONDARY_EXEC_XSAVES | + SECONDARY_EXEC_ENABLE_RDTSCP | + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE, + .tertiary_vm_exec_ctrl_opt = 0, + .pin_based_vm_exec_ctrl_req = 0, + .pin_based_vm_exec_ctrl_opt = 0, + .vmexit_ctrl_req = + VM_EXIT_HOST_ADDR_SPACE_SIZE | + VM_EXIT_LOAD_IA32_PAT | + VM_EXIT_LOAD_IA32_EFER | + VM_EXIT_SAVE_IA32_PAT | + VM_EXIT_SAVE_IA32_EFER | + VM_EXIT_SAVE_DEBUG_CONTROLS, + .vmexit_ctrl_opt = 0, + .vmentry_ctrl_req = + VM_ENTRY_LOAD_DEBUG_CONTROLS | + VM_ENTRY_IA32E_MODE | + VM_ENTRY_LOAD_IA32_EFER | + VM_ENTRY_LOAD_IA32_PAT, + .vmentry_ctrl_opt = 0, + }; + + ret = setup_vmcs_config_common(vmcs_config, vmx_cap, &setting); + if (ret) { + pr_err("%s: fail with ret %d\n", __func__, ret); + } else { + pr_info("pin_based_exec_ctrl 0x%x\n", vmcs_config->pin_based_exec_ctrl); + pr_info("cpu_based_exec_ctrl 0x%x\n", vmcs_config->cpu_based_exec_ctrl); + pr_info("cpu_based_2nd_exec_ctrl 0x%x\n", vmcs_config->cpu_based_2nd_exec_ctrl); + pr_info("vmexit_ctrl 0x%x\n", vmcs_config->vmexit_ctrl); + pr_info("vmentry_ctrl 0x%x\n", vmcs_config->vmentry_ctrl); + } + + return ret; +} + __init int pkvm_init(void) { int ret = 0; @@ -27,8 +85,16 @@ __init int pkvm_init(void) goto out; } + ret = pkvm_host_check_and_setup_vmx_cap(pkvm); + if (ret) + goto out_free_pkvm; + pkvm->num_cpus = num_possible_cpus(); + return 0; + +out_free_pkvm: + pkvm_early_free(pkvm, PKVM_PAGES); out: return ret; } -- 2.25.1