mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
hv: call vcpu_inject_exception() only when ACRN_REQUEST_EXCP is set
move the bitmap test call out of vcpu_inject_exception(), then we call the expensive bitmap_test_and_clear_lock() only pending_req_bits is non-zero and call vcpu_inject_exception() only if needed. 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
f801ba4ed7
commit
2b683f8f5b
@ -247,40 +247,32 @@ int32_t vcpu_queue_exception(struct acrn_vcpu *vcpu, uint32_t vector_arg, uint32
|
||||
/*
|
||||
* @pre vcpu->arch.exception_info.exception < 0x20U
|
||||
*/
|
||||
static bool vcpu_inject_exception(struct acrn_vcpu *vcpu)
|
||||
static void vcpu_inject_exception(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
bool injected = false;
|
||||
uint32_t vector = vcpu->arch.exception_info.exception;
|
||||
|
||||
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EXCP, &vcpu->arch.pending_req)) {
|
||||
uint32_t vector = vcpu->arch.exception_info.exception;
|
||||
|
||||
if ((exception_type[vector] & EXCEPTION_ERROR_CODE_VALID) != 0U) {
|
||||
exec_vmwrite32(VMX_ENTRY_EXCEPTION_ERROR_CODE,
|
||||
vcpu->arch.exception_info.error);
|
||||
}
|
||||
|
||||
exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD, VMX_INT_INFO_VALID |
|
||||
(exception_type[vector] << 8U) | (vector & 0xFFU));
|
||||
|
||||
vcpu->arch.exception_info.exception = VECTOR_INVALID;
|
||||
|
||||
/* If this is a fault, we should retain the RIP */
|
||||
if (get_exception_type(vector) == EXCEPTION_FAULT) {
|
||||
vcpu_retain_rip(vcpu);
|
||||
}
|
||||
|
||||
/* SDM 17.3.1.1 For any fault-class exception except a debug exception generated in response to an
|
||||
* instruction breakpoint, the value pushed for RF is 1.
|
||||
* #DB is treated as Trap in get_exception_type, so RF will not be set for instruction breakpoint.
|
||||
*/
|
||||
if (get_exception_type(vector) == EXCEPTION_FAULT) {
|
||||
vcpu_set_rflags(vcpu, vcpu_get_rflags(vcpu) | HV_ARCH_VCPU_RFLAGS_RF);
|
||||
}
|
||||
|
||||
injected = true;
|
||||
if ((exception_type[vector] & EXCEPTION_ERROR_CODE_VALID) != 0U) {
|
||||
exec_vmwrite32(VMX_ENTRY_EXCEPTION_ERROR_CODE,
|
||||
vcpu->arch.exception_info.error);
|
||||
}
|
||||
|
||||
return injected;
|
||||
exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD, VMX_INT_INFO_VALID |
|
||||
(exception_type[vector] << 8U) | (vector & 0xFFU));
|
||||
|
||||
vcpu->arch.exception_info.exception = VECTOR_INVALID;
|
||||
|
||||
/* If this is a fault, we should retain the RIP */
|
||||
if (get_exception_type(vector) == EXCEPTION_FAULT) {
|
||||
vcpu_retain_rip(vcpu);
|
||||
}
|
||||
|
||||
/* SDM 17.3.1.1 For any fault-class exception except a debug exception generated in response to an
|
||||
* instruction breakpoint, the value pushed for RF is 1.
|
||||
* #DB is treated as Trap in get_exception_type, so RF will not be set for instruction breakpoint.
|
||||
*/
|
||||
if (get_exception_type(vector) == EXCEPTION_FAULT) {
|
||||
vcpu_set_rflags(vcpu, vcpu_get_rflags(vcpu) | HV_ARCH_VCPU_RFLAGS_RF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Inject external interrupt to guest */
|
||||
@ -415,8 +407,10 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
|
||||
/*
|
||||
* Inject pending exception prior pending interrupt to complete the previous instruction.
|
||||
*/
|
||||
injected = vcpu_inject_exception(vcpu);
|
||||
if (!injected) {
|
||||
if ((*pending_req_bits != 0UL) && bitmap_test_and_clear_lock(ACRN_REQUEST_EXCP, pending_req_bits)) {
|
||||
vcpu_inject_exception(vcpu);
|
||||
injected = true;
|
||||
} else {
|
||||
/* inject NMI before maskable hardware interrupt */
|
||||
|
||||
if ((*pending_req_bits != 0UL) &&
|
||||
|
Loading…
Reference in New Issue
Block a user