mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-09 12:08:30 +00:00
hv: nested: some API signature changes
No any logical changes, this patch is preparing for multiple active VMCS12 support. - currently it's easy to get the vmcs12 pointer from the vcpu pointer. In multiple active vmcs12 case, we need to explicitly add "struct acrn_vmcs12 *vmcs12" to certain APIs' input argument list, in order to get the desired vmcs12 pointer. - merge flush_current_vmcs12() into clear_vmcs02() for multiple reasons: a) it's called only once; b) we don't wrap the opposite operation (loading vmcs12) in an API; c) this API has simple and clear logic. 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
e4c69546a0
commit
cf697e753d
@ -902,15 +902,14 @@ int32_t vmwrite_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
* @pre vcpu != NULL
|
* @pre vcpu != NULL
|
||||||
* @pre vmcs02 is current
|
* @pre vmcs02 is current
|
||||||
*/
|
*/
|
||||||
static void sync_vmcs02_to_vmcs12(struct acrn_vcpu *vcpu)
|
static void sync_vmcs02_to_vmcs12(struct acrn_vmcs12 *vmcs12)
|
||||||
{
|
{
|
||||||
uint64_t vmcs12 = (uint64_t)&vcpu->arch.nested.vmcs12;
|
|
||||||
uint64_t val64;
|
uint64_t val64;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
for (idx = 0; idx < MAX_SHADOW_VMCS_FIELDS; idx++) {
|
for (idx = 0; idx < MAX_SHADOW_VMCS_FIELDS; idx++) {
|
||||||
val64 = exec_vmread(vmcs_shadowing_fields[idx]);
|
val64 = exec_vmread(vmcs_shadowing_fields[idx]);
|
||||||
vmcs12_write_field(vmcs12, vmcs_shadowing_fields[idx], val64);
|
vmcs12_write_field((uint64_t)vmcs12, vmcs_shadowing_fields[idx], val64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,9 +917,8 @@ static void sync_vmcs02_to_vmcs12(struct acrn_vcpu *vcpu)
|
|||||||
* @pre vcpu != NULL
|
* @pre vcpu != NULL
|
||||||
* @pre VMCS02 (as an ordinary VMCS) is current
|
* @pre VMCS02 (as an ordinary VMCS) is current
|
||||||
*/
|
*/
|
||||||
static void merge_and_sync_control_fields(struct acrn_vcpu *vcpu)
|
static void merge_and_sync_control_fields(struct acrn_vcpu *vcpu, struct acrn_vmcs12 *vmcs12)
|
||||||
{
|
{
|
||||||
struct acrn_vmcs12 *vmcs12 = &vcpu->arch.nested.vmcs12;
|
|
||||||
uint64_t value64;
|
uint64_t value64;
|
||||||
|
|
||||||
/* Sync VMCS fields that are not shadowing. Don't need to sync these fields back to VMCS12. */
|
/* Sync VMCS fields that are not shadowing. Don't need to sync these fields back to VMCS12. */
|
||||||
@ -954,37 +952,17 @@ static void merge_and_sync_control_fields(struct acrn_vcpu *vcpu)
|
|||||||
* @pre vcpu != NULL
|
* @pre vcpu != NULL
|
||||||
* @pre vmcs02 is current
|
* @pre vmcs02 is current
|
||||||
*/
|
*/
|
||||||
static void sync_vmcs12_to_vmcs02(struct acrn_vcpu *vcpu)
|
static void sync_vmcs12_to_vmcs02(struct acrn_vcpu *vcpu, struct acrn_vmcs12 *vmcs12)
|
||||||
{
|
{
|
||||||
uint64_t vmcs12 = (uint64_t)&vcpu->arch.nested.vmcs12;
|
|
||||||
uint64_t val64;
|
uint64_t val64;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
for (idx = 0; idx < MAX_SHADOW_VMCS_FIELDS; idx++) {
|
for (idx = 0; idx < MAX_SHADOW_VMCS_FIELDS; idx++) {
|
||||||
val64 = vmcs12_read_field(vmcs12, vmcs_shadowing_fields[idx]);
|
val64 = vmcs12_read_field((uint64_t)vmcs12, vmcs_shadowing_fields[idx]);
|
||||||
exec_vmwrite(vmcs_shadowing_fields[idx], val64);
|
exec_vmwrite(vmcs_shadowing_fields[idx], val64);
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_and_sync_control_fields(vcpu);
|
merge_and_sync_control_fields(vcpu, vmcs12);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @pre vcpu != NULL
|
|
||||||
* @pre vmcs02 is current
|
|
||||||
*/
|
|
||||||
static void flush_current_vmcs12(struct acrn_vcpu *vcpu)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Since we have one cache VMCS12 and one active VMCS02 per vCPU,
|
|
||||||
* at the time of VMCLEAR current VMCS12, or VMPTRLD a new VMCS12
|
|
||||||
* on this vCPU, we need to sync the shadow fields from VMCS02 to
|
|
||||||
* cache VMCS12, and save the cache VMCS12 to guest memory.
|
|
||||||
*/
|
|
||||||
sync_vmcs02_to_vmcs12(vcpu);
|
|
||||||
|
|
||||||
/* flush cached VMCS12 back to L1 guest */
|
|
||||||
(void)copy_to_gpa(vcpu->vm, (void *)&vcpu->arch.nested.vmcs12,
|
|
||||||
vcpu->arch.nested.current_vmcs12_ptr, sizeof(struct acrn_vmcs12));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1047,6 +1025,10 @@ static void disable_vmcs_shadowing(void)
|
|||||||
exec_vmwrite(VMX_VMS_LINK_PTR_FULL, ~0UL);
|
exec_vmwrite(VMX_VMS_LINK_PTR_FULL, ~0UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vcpu != NULL
|
||||||
|
* @pre vmcs01 is current
|
||||||
|
*/
|
||||||
static void clear_vmcs02(struct acrn_vcpu *vcpu)
|
static void clear_vmcs02(struct acrn_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct acrn_nested *nested = &vcpu->arch.nested;
|
struct acrn_nested *nested = &vcpu->arch.nested;
|
||||||
@ -1064,8 +1046,11 @@ static void clear_vmcs02(struct acrn_vcpu *vcpu)
|
|||||||
/* VMPTRLD the shadow VMCS so that we are able to sync it to VMCS12 */
|
/* VMPTRLD the shadow VMCS so that we are able to sync it to VMCS12 */
|
||||||
load_va_vmcs(nested->vmcs02);
|
load_va_vmcs(nested->vmcs02);
|
||||||
|
|
||||||
/* Sync shadow VMCS to cache VMCS12, and copy cache VMCS12 to L1 guest */
|
sync_vmcs02_to_vmcs12(&nested->vmcs12);
|
||||||
flush_current_vmcs12(vcpu);
|
|
||||||
|
/* flush cached VMCS12 back to L1 guest */
|
||||||
|
(void)copy_to_gpa(vcpu->vm, (void *)&nested->vmcs12, nested->current_vmcs12_ptr,
|
||||||
|
sizeof(struct acrn_vmcs12));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The current VMCS12 has been flushed out, so that the active VMCS02
|
* The current VMCS12 has been flushed out, so that the active VMCS02
|
||||||
@ -1137,7 +1122,7 @@ int32_t vmptrld_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
get_nept_desc(nested->vmcs12.ept_pointer);
|
get_nept_desc(nested->vmcs12.ept_pointer);
|
||||||
|
|
||||||
/* Need to load shadow fields from this new VMCS12 to VMCS02 */
|
/* Need to load shadow fields from this new VMCS12 to VMCS02 */
|
||||||
sync_vmcs12_to_vmcs02(vcpu);
|
sync_vmcs12_to_vmcs02(vcpu, &nested->vmcs12);
|
||||||
|
|
||||||
/* Before VMCS02 is being used as a shadow VMCS, VMCLEAR it */
|
/* Before VMCS02 is being used as a shadow VMCS, VMCLEAR it */
|
||||||
clear_va_vmcs(nested->vmcs02);
|
clear_va_vmcs(nested->vmcs02);
|
||||||
@ -1406,7 +1391,7 @@ static void nested_vmentry(struct acrn_vcpu *vcpu, bool is_launch)
|
|||||||
|
|
||||||
if (vcpu->arch.nested.control_fields_dirty) {
|
if (vcpu->arch.nested.control_fields_dirty) {
|
||||||
vcpu->arch.nested.control_fields_dirty = false;
|
vcpu->arch.nested.control_fields_dirty = false;
|
||||||
merge_and_sync_control_fields(vcpu);
|
merge_and_sync_control_fields(vcpu, vmcs12);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vCPU is in guest mode from this point */
|
/* vCPU is in guest mode from this point */
|
||||||
@ -1416,7 +1401,7 @@ static void nested_vmentry(struct acrn_vcpu *vcpu, bool is_launch)
|
|||||||
vmcs12->launch_state = VMCS12_LAUNCH_STATE_LAUNCHED;
|
vmcs12->launch_state = VMCS12_LAUNCH_STATE_LAUNCHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sanitize_l2_vpid(&vcpu->arch.nested.vmcs12);
|
sanitize_l2_vpid(vmcs12);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set vcpu->launched to false because the launch state of VMCS02 is
|
* set vcpu->launched to false because the launch state of VMCS02 is
|
||||||
|
Loading…
Reference in New Issue
Block a user