diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index c8d16e982..b31122c9d 100755 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -739,15 +739,6 @@ void arch_deinit_vcpu(struct acrn_vcpu *vcpu) vlapic_free(vcpu); } -void kick_vcpu(struct acrn_vcpu *vcpu) -{ - uint16_t pcpu_id = pcpuid_from_vcpu(vcpu); - - if ((get_pcpu_id() != pcpu_id) && (per_cpu(arch.vmcs_run, pcpu_id) == vcpu->arch.vmcs)) { - kick_pcpu(pcpu_id); - } -} - /* * @pre (&vcpu->stack[CONFIG_STACK_SIZE] & (CPU_STACK_ALIGN - 1UL)) == 0 */ diff --git a/hypervisor/arch/x86/guest/virq.c b/hypervisor/arch/x86/guest/virq.c index 61e3f930e..652e49057 100644 --- a/hypervisor/arch/x86/guest/virq.c +++ b/hypervisor/arch/x86/guest/virq.c @@ -128,11 +128,6 @@ static inline bool is_nmi_injectable(void) return ((guest_state & (HV_ARCH_VCPU_BLOCKED_BY_STI | HV_ARCH_VCPU_BLOCKED_BY_MOVSS | HV_ARCH_VCPU_BLOCKED_BY_NMI)) == 0UL); } -void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid) -{ - bitmap_set(eventid, &vcpu->pending_req); - kick_vcpu(vcpu); -} /* * @retval true when INT is injected to guest. @@ -365,40 +360,40 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) struct acrn_vcpu_arch *arch = &vcpu->arch; uint64_t *pending_req_bits = &vcpu->pending_req; - if (*pending_req_bits != 0UL) { + if (vcpu_has_pending_request(vcpu)) { /* make sure ACRN_REQUEST_INIT_VMCS handler as the first one */ - if (bitmap_test_and_clear(ACRN_REQUEST_INIT_VMCS, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_INIT_VMCS)) { init_vmcs(vcpu); } - if (bitmap_test_and_clear(ACRN_REQUEST_TRP_FAULT, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_TRP_FAULT)) { pr_fatal("Triple fault happen -> shutdown!"); ret = -EFAULT; } else { - if (bitmap_test_and_clear(ACRN_REQUEST_WAIT_WBINVD, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_WAIT_WBINVD)) { wait_event(&vcpu->events[VCPU_EVENT_SYNC_WBINVD]); } - if (bitmap_test_and_clear(ACRN_REQUEST_SPLIT_LOCK, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_SPLIT_LOCK)) { wait_event(&vcpu->events[VCPU_EVENT_SPLIT_LOCK]); } - if (bitmap_test_and_clear(ACRN_REQUEST_EPT_FLUSH, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_EPT_FLUSH)) { invept(vcpu->vm->root_stg2ptp); if (vcpu->vm->arch_vm.sworld_control.flag.active != 0UL) { invept(vcpu->vm->arch_vm.sworld_eptp); } } - if (bitmap_test_and_clear(ACRN_REQUEST_VPID_FLUSH, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_VPID_FLUSH)) { flush_vpid_single(arch->vpid); } - if (bitmap_test_and_clear(ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE)) { vcpu_set_vmcs_eoi_exit(vcpu); } - if (bitmap_test_and_clear(ACRN_REQUEST_SMP_CALL, pending_req_bits)) { + if (vcpu_take_request(vcpu, ACRN_REQUEST_SMP_CALL)) { handle_smp_call(); } @@ -409,14 +404,14 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) /* * Inject pending exception prior pending interrupt to complete the previous instruction. */ - if ((*pending_req_bits != 0UL) && bitmap_test_and_clear(ACRN_REQUEST_EXCP, pending_req_bits)) { + if (vcpu_has_pending_request(vcpu) && vcpu_take_request(vcpu, ACRN_REQUEST_EXCP)) { vcpu_inject_exception(vcpu); injected = true; } else { /* inject NMI before maskable hardware interrupt */ - if ((*pending_req_bits != 0UL) && - bitmap_test_and_clear(ACRN_REQUEST_NMI, pending_req_bits)) { + if (vcpu_has_pending_request(vcpu) && + vcpu_take_request(vcpu, ACRN_REQUEST_NMI)) { if (is_nmi_injectable()) { /* Inject NMI vector = 2 */ exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD, diff --git a/hypervisor/common/vcpu.c b/hypervisor/common/vcpu.c index dce8af96f..6bc5a39bc 100644 --- a/hypervisor/common/vcpu.c +++ b/hypervisor/common/vcpu.c @@ -11,6 +11,7 @@ #include #include #include +#include bool is_vcpu_bsp(const struct acrn_vcpu *vcpu) { @@ -87,6 +88,21 @@ void vcpu_set_state(struct acrn_vcpu *vcpu, enum vcpu_state new_state) vcpu->state = new_state; } +void kick_vcpu(struct acrn_vcpu *vcpu) +{ + uint16_t pcpu_id = pcpuid_from_vcpu(vcpu); + + if ((get_pcpu_id() != pcpu_id) && (get_running_vcpu(pcpu_id) == vcpu)) { + arch_smp_call_kick_pcpu(pcpu_id); + } +} + +void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid) +{ + bitmap_set(eventid, &vcpu->pending_req); + kick_vcpu(vcpu); +} + /** * @brief create a vcpu for the target vm * diff --git a/hypervisor/include/arch/x86/asm/guest/vcpu.h b/hypervisor/include/arch/x86/asm/guest/vcpu.h index 84c86086d..ce7364f82 100644 --- a/hypervisor/include/arch/x86/asm/guest/vcpu.h +++ b/hypervisor/include/arch/x86/asm/guest/vcpu.h @@ -547,15 +547,6 @@ void load_iwkey(struct acrn_vcpu *vcpu); */ int32_t run_vcpu(struct acrn_vcpu *vcpu); -/** - * @brief kick the vcpu and let it handle pending events - * - * Kick a vCPU to handle the pending events. - * - * @param[in] vcpu pointer to vcpu data structure - */ -void kick_vcpu(struct acrn_vcpu *vcpu); - /** * @brief create a vcpu for the vm and mapped to the pcpu. * diff --git a/hypervisor/include/arch/x86/asm/guest/virq.h b/hypervisor/include/arch/x86/asm/guest/virq.h index 8836ae10a..d539878c0 100644 --- a/hypervisor/include/arch/x86/asm/guest/virq.h +++ b/hypervisor/include/arch/x86/asm/guest/virq.h @@ -101,7 +101,6 @@ void vcpu_inject_ss(struct acrn_vcpu *vcpu); * @pre vcpu != NULL */ void vcpu_inject_thermal_interrupt(struct acrn_vcpu *vcpu); -void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid); /* * @pre vcpu != NULL diff --git a/hypervisor/include/common/notify.h b/hypervisor/include/common/notify.h index f2d212fef..385719cb6 100644 --- a/hypervisor/include/common/notify.h +++ b/hypervisor/include/common/notify.h @@ -8,6 +8,7 @@ #define COMMON_NOTIFY_H #include +#include typedef void (*smp_call_func_t)(void *data); diff --git a/hypervisor/include/common/vcpu.h b/hypervisor/include/common/vcpu.h index 9cccd4838..8552f0481 100644 --- a/hypervisor/include/common/vcpu.h +++ b/hypervisor/include/common/vcpu.h @@ -21,6 +21,7 @@ #include #include #include +#include #include /** @@ -110,6 +111,18 @@ uint64_t arch_build_stack_frame(struct acrn_vcpu *vcpu); /* Common helpers */ bool is_vcpu_bsp(const struct acrn_vcpu *vcpu); uint16_t pcpuid_from_vcpu(const struct acrn_vcpu *vcpu); +void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid); + +static inline bool vcpu_has_pending_request(struct acrn_vcpu *vcpu) +{ + return (vcpu->pending_req != 0UL); +} + +static inline bool vcpu_take_request(struct acrn_vcpu *vcpu, uint16_t eventid) +{ + return bitmap_test_and_clear(eventid, &(vcpu->pending_req)); +} + /** * @brief get physical destination cpu mask @@ -181,6 +194,15 @@ void reset_vcpu(struct acrn_vcpu *vcpu); */ void zombie_vcpu(struct acrn_vcpu *vcpu); +/** + * @brief kick the vcpu and let it handle pending events + * + * Kick a vCPU to handle the pending events. + * + * @param[in] vcpu pointer to vcpu data structure + */ +void kick_vcpu(struct acrn_vcpu *vcpu); + /** * @} */