Skip to content

Commit b922934

Browse files
conghuic23wenlingz
authored andcommitted
hv: fix for waag 2 core reboot issue
Waag will send NMIs to all its cores during reboot. But currently, NMI cannot be injected to vcpu which is in HLT state. To fix the problem, need to wakeup target vcpu, and inject NMI through interrupt-window. Tracked-On: #4620 Signed-off-by: Conghui Chen <conghui.chen@intel.com>
1 parent 45b65b3 commit b922934

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

hypervisor/arch/x86/guest/virq.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ static bool is_guest_irq_enabled(struct acrn_vcpu *vcpu)
105105
return status;
106106
}
107107

108+
static inline bool is_nmi_injectable(void)
109+
{
110+
uint64_t guest_state;
111+
112+
guest_state = exec_vmread32(VMX_GUEST_INTERRUPTIBILITY_INFO);
113+
114+
return ((guest_state & (HV_ARCH_VCPU_BLOCKED_BY_STI |
115+
HV_ARCH_VCPU_BLOCKED_BY_MOVSS | HV_ARCH_VCPU_BLOCKED_BY_NMI)) == 0UL);
116+
}
108117
void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid)
109118
{
110119
bitmap_set_lock(eventid, &vcpu->arch.pending_req);
@@ -286,6 +295,7 @@ void vcpu_inject_extint(struct acrn_vcpu *vcpu)
286295
void vcpu_inject_nmi(struct acrn_vcpu *vcpu)
287296
{
288297
vcpu_make_request(vcpu, ACRN_REQUEST_NMI);
298+
signal_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
289299
}
290300

291301
/* Inject general protection exception(#GP) to guest */
@@ -401,11 +411,17 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
401411
injected = vcpu_inject_hi_exception(vcpu);
402412
if (!injected) {
403413
/* inject NMI before maskable hardware interrupt */
414+
404415
if (bitmap_test_and_clear_lock(ACRN_REQUEST_NMI, pending_req_bits)) {
405-
/* Inject NMI vector = 2 */
406-
exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD,
407-
VMX_INT_INFO_VALID | (VMX_INT_TYPE_NMI << 8U) | IDT_NMI);
408-
injected = true;
416+
if (is_nmi_injectable()) {
417+
/* Inject NMI vector = 2 */
418+
exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD,
419+
VMX_INT_INFO_VALID | (VMX_INT_TYPE_NMI << 8U) | IDT_NMI);
420+
injected = true;
421+
} else {
422+
/* keep the NMI request for next vmexit */
423+
bitmap_set_lock(ACRN_REQUEST_NMI, pending_req_bits);
424+
}
409425
} else {
410426
/* handling pending vector injection:
411427
* there are many reason inject failed, we need re-inject again
@@ -442,7 +458,13 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
442458
* deliver is disabled.
443459
*/
444460
if (!arch->irq_window_enabled) {
461+
/*
462+
* TODO: Currently, NMI exiting and virtual NMIs are not enabled,
463+
* so use interrupt window to inject NMI.
464+
* After enable virtual NMIs, we can use NMI-Window
465+
*/
445466
if (bitmap_test(ACRN_REQUEST_EXTINT, pending_req_bits) ||
467+
bitmap_test(ACRN_REQUEST_NMI, pending_req_bits) ||
446468
vlapic_has_pending_delivery_intr(vcpu)) {
447469
tmp = exec_vmread32(VMX_PROC_VM_EXEC_CONTROLS);
448470
tmp |= VMX_PROCBASED_CTLS_IRQ_WIN;

hypervisor/include/arch/x86/irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ uint32_t alloc_irq_vector(uint32_t irq);
108108
#define HV_ARCH_VCPU_RFLAGS_RF (1UL<<16U)
109109

110110
/* Interruptability State info */
111+
112+
#define HV_ARCH_VCPU_BLOCKED_BY_NMI (1UL<<3U)
111113
#define HV_ARCH_VCPU_BLOCKED_BY_MOVSS (1UL<<1U)
112114
#define HV_ARCH_VCPU_BLOCKED_BY_STI (1UL<<0U)
113115

0 commit comments

Comments
 (0)