hv: nested: fix bug in syncing EPTP from VMCS12 to VMCS02

Currently vmptrld_vmexit_handler() doesn't sync VMX_EPT_POINTER_FULL
from vmcs12 to vmcs02, instead it sets gpa_field_dirty and relies on
nested_vmentry() to sync EPTP in next nested VMentry.

This creates readability issue since all other intercepted VMCS fields
are synced in sync_vmcs12_to_vmcs02().  Another issue is that other
VMCS fields managed by gpa_field_dirty are repeatedly synced in both
vmptrld and nested vmentry handler.

This patch moves get_nept_desc() ahead of sync_vmcs12_to_vmcs02(), such
that shadow_eptp is allocated before sync_vmcs12_to_vmcs02() which
can sync EPTP properly.

BTW, in nested_vmexit_handler(), don't need to read from VMCS to get
the exit reason, since vcpu->arch.exit_reason has it already.

Tracked-On: #5923
Signed-off-by: Zide Chen <zide.chen@intel.com>
This commit is contained in:
Zide Chen 2021-08-27 17:10:23 -07:00 committed by wenlingz
parent 01bf5110c5
commit 6376d5a0d3
1 changed files with 7 additions and 3 deletions

View File

@ -972,6 +972,9 @@ static void sync_vmcs12_to_vmcs02(struct acrn_vcpu *vcpu)
val64 = vmcs12_read_field(vmcs12, VMX_MSR_BITMAP_FULL);
exec_vmwrite(VMX_MSR_BITMAP_FULL, gpa2hpa(vcpu->vm, val64));
val64 = vmcs12_read_field(vmcs12, VMX_EPT_POINTER_FULL);
exec_vmwrite(VMX_EPT_POINTER_FULL, get_shadow_eptp(val64));
/* For VM-execution, entry and exit controls */
adjust_vmcs02_control_fields(vcpu);
}
@ -1140,11 +1143,12 @@ int32_t vmptrld_vmexit_handler(struct acrn_vcpu *vcpu)
/* Load VMCS12 from L1 guest memory */
(void)copy_from_gpa(vcpu->vm, (void *)&nested->vmcs12, vmcs12_gpa,
sizeof(struct acrn_vmcs12));
vcpu->arch.nested.gpa_field_dirty = true;
/* if needed, create nept_desc and allocate shadow root for the EPTP */
get_nept_desc(nested->vmcs12.ept_pointer);
/* Need to load shadow fields from this new VMCS12 to VMCS02 */
sync_vmcs12_to_vmcs02(vcpu);
get_nept_desc(nested->vmcs12.ept_pointer);
/* Before VMCS02 is being used as a shadow VMCS, VMCLEAR it */
clear_va_vmcs(nested->vmcs02);
@ -1343,7 +1347,7 @@ int32_t nested_vmexit_handler(struct acrn_vcpu *vcpu)
struct acrn_vmcs12 *vmcs12 = (struct acrn_vmcs12 *)&vcpu->arch.nested.vmcs12;
bool is_l1_vmexit = true;
if ((exec_vmread(VMX_EXIT_REASON) & 0xFFFFU) == VMX_EXIT_REASON_EPT_VIOLATION) {
if ((vcpu->arch.exit_reason & 0xFFFFU) == VMX_EXIT_REASON_EPT_VIOLATION) {
is_l1_vmexit = handle_l2_ept_violation(vcpu);
}