mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-05 11:36:50 +00:00
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:
parent
4e54c3880b
commit
0466d7055f
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user