Introduce pkvm_host_vm and pkvm_host_vcpu data structure. The pKVM supports one host vm with up to CONFIG_NR_CPUS host vcpus. The pkvm_host_vcpu is the key data entry to assist running vcpu of host VM. Struct vcpu_vmx is used as its major part to allow pKVM easily sharing code logic from KVM VMX. The pkvm_host_vcpu data entry is allocated according to the real cpu number system running, during the new added vcpu setup logic within pkvm_init. NOTE: the vcpu of host VM is 1:1 mapping to pCPU. Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx> Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx> --- arch/x86/kvm/vmx/pkvm/include/pkvm.h | 12 ++++++++++++ arch/x86/kvm/vmx/pkvm/pkvm_host.c | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/arch/x86/kvm/vmx/pkvm/include/pkvm.h b/arch/x86/kvm/vmx/pkvm/include/pkvm.h index 3adcebd31ca6..73d2c235557a 100644 --- a/arch/x86/kvm/vmx/pkvm/include/pkvm.h +++ b/arch/x86/kvm/vmx/pkvm/include/pkvm.h @@ -22,6 +22,15 @@ struct pkvm_pcpu { struct tss_struct tss; }; +struct pkvm_host_vcpu { + struct vcpu_vmx vmx; + struct pkvm_pcpu *pcpu; +}; + +struct pkvm_host_vm { + struct pkvm_host_vcpu *host_vcpus[CONFIG_NR_CPUS]; +}; + struct pkvm_hyp { int num_cpus; @@ -29,9 +38,12 @@ struct pkvm_hyp { struct vmcs_config vmcs_config; struct pkvm_pcpu *pcpus[CONFIG_NR_CPUS]; + + struct pkvm_host_vm host_vm; }; #define PKVM_PAGES (ALIGN(sizeof(struct pkvm_hyp), PAGE_SIZE) >> PAGE_SHIFT) #define PKVM_PCPU_PAGES (ALIGN(sizeof(struct pkvm_pcpu), PAGE_SIZE) >> PAGE_SHIFT) +#define PKVM_HOST_VCPU_PAGES (ALIGN(sizeof(struct pkvm_host_vcpu), PAGE_SIZE) >> PAGE_SHIFT) #endif diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c index a076f023c582..c437cb965771 100644 --- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c +++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c @@ -151,6 +151,25 @@ static __init int pkvm_setup_pcpu(struct pkvm_hyp *pkvm, int cpu) return 0; } +static __init int pkvm_host_setup_vcpu(struct pkvm_hyp *pkvm, int cpu) +{ + struct pkvm_host_vcpu *pkvm_host_vcpu; + + if (cpu >= CONFIG_NR_CPUS) + return -ENOMEM; + + pkvm_host_vcpu = pkvm_early_alloc_contig(PKVM_HOST_VCPU_PAGES); + if (!pkvm_host_vcpu) + return -ENOMEM; + + pkvm_host_vcpu->pcpu = pkvm->pcpus[cpu]; + pkvm_host_vcpu->vmx.vcpu.cpu = cpu; + + pkvm->host_vm.host_vcpus[cpu] = pkvm_host_vcpu; + + return 0; +} + __init int pkvm_init(void) { int ret = 0, cpu; @@ -169,6 +188,9 @@ __init int pkvm_init(void) ret = pkvm_setup_pcpu(pkvm, cpu); if (ret) goto out_free_cpu; + ret = pkvm_host_setup_vcpu(pkvm, cpu); + if (ret) + goto out_free_cpu; } pkvm->num_cpus = num_possible_cpus(); @@ -177,6 +199,10 @@ __init int pkvm_init(void) out_free_cpu: for_each_possible_cpu(cpu) { + if (pkvm->host_vm.host_vcpus[cpu]) { + pkvm_early_free(pkvm->host_vm.host_vcpus[cpu], PKVM_HOST_VCPU_PAGES); + pkvm->host_vm.host_vcpus[cpu] = NULL; + } if (pkvm->pcpus[cpu]) { pkvm_early_free(pkvm->pcpus[cpu], PKVM_PCPU_PAGES); pkvm->pcpus[cpu] = NULL; -- 2.25.1