hv: nested: move the VMCS12 dirty flags to struct acrn_vvmcs

These dirty flags are supposed to be per VMCS12, so move them from the
per vCPU acrn_nested struct to the newly added acrn_vvmcs struct.

Tracked-On: #6289
Signed-off-by: Zide Chen <zide.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zide Chen 2021-09-05 23:20:22 -07:00 committed by wenlingz
parent 4e54c3880b
commit 0466d7055f
2 changed files with 16 additions and 16 deletions

View File

@ -734,8 +734,8 @@ int32_t vmxon_vmexit_handler(struct acrn_vcpu *vcpu)
nested_vmx_result(VMfailInvalid, 0); nested_vmx_result(VMfailInvalid, 0);
} else { } else {
vcpu->arch.nested.vmxon = true; vcpu->arch.nested.vmxon = true;
vcpu->arch.nested.host_state_dirty = false; vcpu->arch.nested.vvmcs[0].host_state_dirty = false;
vcpu->arch.nested.control_fields_dirty = false; vcpu->arch.nested.vvmcs[0].control_fields_dirty = false;
vcpu->arch.nested.in_l2_guest = false; vcpu->arch.nested.in_l2_guest = false;
vcpu->arch.nested.vmxon_ptr = vmptr_gpa; vcpu->arch.nested.vmxon_ptr = vmptr_gpa;
vcpu->arch.nested.current_vvmcs = NULL; vcpu->arch.nested.current_vvmcs = NULL;
@ -780,8 +780,8 @@ int32_t vmxoff_vmexit_handler(struct acrn_vcpu *vcpu)
{ {
if (check_vmx_permission(vcpu)) { if (check_vmx_permission(vcpu)) {
vcpu->arch.nested.vmxon = false; vcpu->arch.nested.vmxon = false;
vcpu->arch.nested.host_state_dirty = false; vcpu->arch.nested.vvmcs[0].host_state_dirty = false;
vcpu->arch.nested.control_fields_dirty = false; vcpu->arch.nested.vvmcs[0].control_fields_dirty = false;
vcpu->arch.nested.in_l2_guest = false; vcpu->arch.nested.in_l2_guest = false;
vcpu->arch.nested.current_vvmcs = NULL; vcpu->arch.nested.current_vvmcs = NULL;
@ -871,7 +871,7 @@ int32_t vmwrite_vmexit_handler(struct acrn_vcpu *vcpu)
} }
if (VMX_VMCS_FIELD_TYPE(vmcs_field) == VMX_VMCS_FIELD_TYPE_HOST) { if (VMX_VMCS_FIELD_TYPE(vmcs_field) == VMX_VMCS_FIELD_TYPE_HOST) {
vcpu->arch.nested.host_state_dirty = true; cur_vvmcs->host_state_dirty = true;
} }
if ((vmcs_field == VMX_MSR_BITMAP_FULL) if ((vmcs_field == VMX_MSR_BITMAP_FULL)
@ -879,7 +879,7 @@ int32_t vmwrite_vmexit_handler(struct acrn_vcpu *vcpu)
|| (vmcs_field == VMX_VPID) || (vmcs_field == VMX_VPID)
|| (vmcs_field == VMX_ENTRY_CONTROLS) || (vmcs_field == VMX_ENTRY_CONTROLS)
|| (vmcs_field == VMX_EXIT_CONTROLS)) { || (vmcs_field == VMX_EXIT_CONTROLS)) {
vcpu->arch.nested.control_fields_dirty = true; cur_vvmcs->control_fields_dirty = true;
if (vmcs_field == VMX_EPT_POINTER_FULL) { if (vmcs_field == VMX_EPT_POINTER_FULL) {
if (cur_vvmcs->vmcs12.ept_pointer != vmcs_value) { if (cur_vvmcs->vmcs12.ept_pointer != vmcs_value) {
@ -1063,6 +1063,10 @@ static void clear_vmcs02(struct acrn_vcpu *vcpu, struct acrn_vvmcs *vvmcs)
/* This vvmcs[] entry doesn't cache a VMCS12 any more */ /* This vvmcs[] entry doesn't cache a VMCS12 any more */
vvmcs->vmcs12_gpa = INVALID_GPA; vvmcs->vmcs12_gpa = INVALID_GPA;
/* Cleanup per VVMCS dirty flags */
vvmcs->host_state_dirty = false;
vvmcs->control_fields_dirty = false;
} }
/* /*
@ -1172,10 +1176,6 @@ int32_t vmclear_vmexit_handler(struct acrn_vcpu *vcpu)
/* Switch back to vmcs01 (no VMCS shadowing) */ /* Switch back to vmcs01 (no VMCS shadowing) */
load_va_vmcs(vcpu->arch.vmcs); load_va_vmcs(vcpu->arch.vmcs);
/* If no L2 VM entry happens between VMWRITE and VMCLEAR, need to clear these flags */
vcpu->arch.nested.host_state_dirty = false;
vcpu->arch.nested.control_fields_dirty = false;
/* no current VMCS12 */ /* no current VMCS12 */
nested->current_vvmcs = NULL; nested->current_vvmcs = NULL;
} else { } else {
@ -1239,8 +1239,8 @@ static void set_vmcs01_guest_state(struct acrn_vcpu *vcpu)
struct acrn_vmcs12 *vmcs12 = &vcpu->arch.nested.current_vvmcs->vmcs12; struct acrn_vmcs12 *vmcs12 = &vcpu->arch.nested.current_vvmcs->vmcs12;
struct segment_sel seg; struct segment_sel seg;
if (vcpu->arch.nested.host_state_dirty == true) { if (vcpu->arch.nested.current_vvmcs->host_state_dirty == true) {
vcpu->arch.nested.host_state_dirty = false; vcpu->arch.nested.current_vvmcs->host_state_dirty = false;
/* /*
* We want vcpu_get_cr0/4() can get the up-to-date values, but we don't * We want vcpu_get_cr0/4() can get the up-to-date values, but we don't
@ -1396,8 +1396,8 @@ static void nested_vmentry(struct acrn_vcpu *vcpu, bool is_launch)
/* as an ordinary VMCS, VMCS02 is active and currernt when L2 guest is running */ /* as an ordinary VMCS, VMCS02 is active and currernt when L2 guest is running */
load_va_vmcs(cur_vvmcs->vmcs02); load_va_vmcs(cur_vvmcs->vmcs02);
if (vcpu->arch.nested.control_fields_dirty) { if (cur_vvmcs->control_fields_dirty) {
vcpu->arch.nested.control_fields_dirty = false; cur_vvmcs->control_fields_dirty = false;
merge_and_sync_control_fields(vcpu, vmcs12); merge_and_sync_control_fields(vcpu, vmcs12);
} }

View File

@ -333,6 +333,8 @@ struct acrn_vvmcs {
uint8_t vmcs02[PAGE_SIZE]; /* VMCS to run L2 and as Link Pointer in VMCS01 */ uint8_t vmcs02[PAGE_SIZE]; /* VMCS to run L2 and as Link Pointer in VMCS01 */
struct acrn_vmcs12 vmcs12; /* To cache L1's VMCS12*/ struct acrn_vmcs12 vmcs12; /* To cache L1's VMCS12*/
uint64_t vmcs12_gpa; /* The corresponding L1 GPA for this VMCS12 */ uint64_t vmcs12_gpa; /* The corresponding L1 GPA for this VMCS12 */
bool host_state_dirty; /* To indicate need to merge VMCS12 host-state fields to VMCS01 */
bool control_fields_dirty; /* For all other non-host-state fields that need to be merged */
} __aligned(PAGE_SIZE); } __aligned(PAGE_SIZE);
struct acrn_nested { struct acrn_nested {
@ -341,8 +343,6 @@ struct acrn_nested {
uint64_t vmxon_ptr; /* GPA */ uint64_t vmxon_ptr; /* GPA */
bool vmxon; /* To indicate if vCPU entered VMX operation */ bool vmxon; /* To indicate if vCPU entered VMX operation */
bool in_l2_guest; /* To indicate if vCPU is currently in Guest mode (from L1's perspective) */ bool in_l2_guest; /* To indicate if vCPU is currently in Guest mode (from L1's perspective) */
bool host_state_dirty; /* To indicate need to merge VMCS12 host-state fields to VMCS01 */
bool control_fields_dirty; /* For all other non-host-state fields that need to be merged */
} __aligned(PAGE_SIZE); } __aligned(PAGE_SIZE);
void init_nested_vmx(__unused struct acrn_vm *vm); void init_nested_vmx(__unused struct acrn_vm *vm);