hv: nested: implement nested VM exit handler

Nested VM exits happen when vCPU is in guest mode (VMCS02 is current).
Initially we reflect all nested VM exits to L1 hypervisor. To prepare
the environment to run L1 guest:

- restore some VMCS fields to the value as what L1 hypervisor programmed.
- VMCLEAR VMCS02, VMPTRLD VMCS01 and enable VMCS shadowing.
- load the non-shadowing host states from VMCS12 to VMCS01 guest states.
- VMRESUME to L1 guest with this modified VMCS01.

Tracked-On: #5923
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Alexander Merritt <alex.merritt@intel.com>
This commit is contained in:
Zide Chen
2021-04-29 15:50:40 -07:00
committed by wenlingz
parent 22d225663f
commit 811e367ad9
3 changed files with 166 additions and 0 deletions

View File

@@ -317,6 +317,7 @@ enum VMXResult {
void nested_vmx_result(enum VMXResult, int error_number);
int64_t get_invvpid_ept_operands(struct acrn_vcpu *vcpu, void *desc, size_t size);
bool check_vmx_permission(struct acrn_vcpu *vcpu);
int32_t nested_vmexit_handler(struct acrn_vcpu *vcpu);
int32_t vmxon_vmexit_handler(struct acrn_vcpu *vcpu);
int32_t vmxoff_vmexit_handler(struct acrn_vcpu *vcpu);
int32_t vmptrld_vmexit_handler(struct acrn_vcpu *vcpu);
@@ -343,6 +344,7 @@ struct acrn_nested {
} __aligned(PAGE_SIZE);
void init_nested_vmx(__unused struct acrn_vm *vm);
bool is_vcpu_in_l2_guest(struct acrn_vcpu *vcpu);
bool is_vmx_msr(uint32_t msr);
void init_vmx_msrs(struct acrn_vcpu *vcpu);
int32_t read_vmx_msr(__unused struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val);
@@ -350,6 +352,10 @@ int32_t read_vmx_msr(__unused struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *va
struct acrn_nested {};
static inline void init_nested_vmx(__unused struct acrn_vm *vm) {}
static inline bool is_vcpu_in_l2_guest(__unused struct acrn_vcpu *vcpu) {
return false;
}
static inline bool is_vmx_msr(__unused uint32_t msr)
{
/*