mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-05 02:11:23 +00:00
hv: update guest RIP only if vcpu->arch.inst_len is non zero
In very large number of VM extis, the VM-exit instruction length could be zero, and it's no need to update VMX_GUEST_RIP. Some examples: - all external interrupt VM exits in non LAPIC passthru setup. - for all the nested VM-exits that are reflecting to L1 hypervisor. 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
b7e9a68923
commit
f801ba4ed7
@ -1450,6 +1450,16 @@ int32_t nested_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
vcpu->arch.nested.in_l2_guest = false;
|
vcpu->arch.nested.in_l2_guest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For VM-exits that reflect to L1 hypervisor, ACRN can't advance to next guest RIP
|
||||||
|
* which is up to the L1 hypervisor to make the decision.
|
||||||
|
*
|
||||||
|
* The only case that doesn't need to be reflected is EPT violations that can be
|
||||||
|
* completely handled by ACRN, which requires L2 VM to re-execute the instruction
|
||||||
|
* after the shadow EPT is being properly setup.
|
||||||
|
|
||||||
|
* In either case, need to set vcpu->arch.inst_len to zero.
|
||||||
|
*/
|
||||||
vcpu_retain_rip(vcpu);
|
vcpu_retain_rip(vcpu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -657,8 +657,8 @@ static void write_cached_registers(struct acrn_vcpu *vcpu)
|
|||||||
*/
|
*/
|
||||||
int32_t run_vcpu(struct acrn_vcpu *vcpu)
|
int32_t run_vcpu(struct acrn_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
uint32_t instlen, cs_attr;
|
uint32_t cs_attr;
|
||||||
uint64_t rip, ia32_efer, cr0;
|
uint64_t ia32_efer, cr0;
|
||||||
struct run_context *ctx =
|
struct run_context *ctx =
|
||||||
&vcpu->arch.contexts[vcpu->arch.cur_context].run_ctx;
|
&vcpu->arch.contexts[vcpu->arch.cur_context].run_ctx;
|
||||||
int32_t status = 0;
|
int32_t status = 0;
|
||||||
@ -718,9 +718,9 @@ int32_t run_vcpu(struct acrn_vcpu *vcpu)
|
|||||||
/* This VCPU was already launched, check if the last guest
|
/* This VCPU was already launched, check if the last guest
|
||||||
* instruction needs to be repeated and resume VCPU accordingly
|
* instruction needs to be repeated and resume VCPU accordingly
|
||||||
*/
|
*/
|
||||||
instlen = vcpu->arch.inst_len;
|
if (vcpu->arch.inst_len != 0U) {
|
||||||
rip = vcpu_get_rip(vcpu);
|
exec_vmwrite(VMX_GUEST_RIP, vcpu_get_rip(vcpu) + vcpu->arch.inst_len);
|
||||||
exec_vmwrite(VMX_GUEST_RIP, rip + instlen);
|
}
|
||||||
|
|
||||||
/* Resume the VM */
|
/* Resume the VM */
|
||||||
status = exec_vmentry(ctx, VM_RESUME, ibrs_type);
|
status = exec_vmentry(ctx, VM_RESUME, ibrs_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user