HV: Don't make NMI injection req when notifying vCPU

The NMI for notification should not be inject to guest. So,
this patch drops NMI injection request when we use NMI
to notify vCPUs. Meanwhile, ACRN doesn't support vNMI well
and there is no well-designed way to check if the NMI is
for notification or for guest now. So, we take all the NMIs as
notificaton NMI for hard rtvm temporarily. It means that the
hard rtvm will never receive NMI with this patch applied.

TODO: vNMI support is not ready yet. we will add it later.

Tracked-On: #3886
Signed-off-by: Kaige Fu <kaige.fu@intel.com>
This commit is contained in:
Kaige Fu 2019-12-11 19:45:54 +00:00 committed by wenlingz
parent 24c2c0ecc0
commit d26d8bec01
4 changed files with 53 additions and 3 deletions

View File

@ -202,7 +202,20 @@ int32_t vcpu_queue_exception(struct acrn_vcpu *vcpu, uint32_t vector_arg, uint32
} else {
arch->exception_info.error = 0U;
}
vcpu_make_request(vcpu, ACRN_REQUEST_EXCP);
if ((vector == IDT_NMI) && is_notification_nmi(vcpu->vm)) {
/*
* Currently, ACRN doesn't support vNMI well and there is no well-designed
* way to check if the NMI is for notification or not. Here we take all the
* NMIs as notification NMI for lapic-pt VMs temporarily.
*
* TODO: Add a way in is_notification_nmi to check the NMI is for notification
* or not in order to support vNMI.
*/
pr_dbg("This NMI is used as notification signal. So ignore it.");
} else {
vcpu_make_request(vcpu, ACRN_REQUEST_EXCP);
}
}
}

View File

@ -194,8 +194,20 @@ int32_t vmexit_handler(struct acrn_vcpu *vcpu)
(void)vcpu_queue_exception(vcpu, vector, err_code);
vcpu->arch.idt_vectoring_info = 0U;
} else if (type == VMX_INT_TYPE_NMI) {
vcpu_make_request(vcpu, ACRN_REQUEST_NMI);
vcpu->arch.idt_vectoring_info = 0U;
if (is_notification_nmi(vcpu->vm)) {
/*
* Currently, ACRN doesn't support vNMI well and there is no well-designed
* way to check if the NMI is for notification or not. Here we take all the
* NMIs as notification NMI for lapic-pt VMs temporarily.
*
* TODO: Add a way in is_notification_nmi to check the NMI is for notification
* or not in order to support vNMI.
*/
pr_dbg("This NMI is used as notification signal. So ignore it.");
} else {
vcpu_make_request(vcpu, ACRN_REQUEST_NMI);
vcpu->arch.idt_vectoring_info = 0U;
}
} else {
/* No action on EXT_INT or SW exception. */
}

View File

@ -12,6 +12,7 @@
#include <cpu.h>
#include <per_cpu.h>
#include <lapic.h>
#include <vm.h>
static uint32_t notification_irq = IRQ_INVALID;
@ -114,3 +115,25 @@ void setup_posted_intr_notification(void)
pr_err("Failed to setup posted-intr notification");
}
}
/**
* @brief Check if the NMI is for notification purpose
*
* @return true, if the NMI is triggered for notifying vCPU
* @return false, if the NMI is triggered for other purpose
*/
bool is_notification_nmi(const struct acrn_vm *vm)
{
bool ret;
/*
* Currently, ACRN doesn't support vNMI well and there is no well-designed
* way to check if the NMI is for notification or not. Here we take all the
* NMIs as notification NMI for lapic-pt VMs temporarily.
*
* TODO: Add a way to check the NMI is for notification or not in order to support vNMI.
*/
ret = is_lapic_pt_configured(vm);
return ret;
}

View File

@ -65,6 +65,7 @@
#define IRQF_PT (1U << 2U) /* 1: for passthrough dev */
struct acrn_vcpu;
struct acrn_vm;
/*
* Definition of the stack frame layout
@ -87,6 +88,7 @@ struct smp_call_info_data {
};
void smp_call_function(uint64_t mask, smp_call_func_t func, void *data);
bool is_notification_nmi(const struct acrn_vm *vm);
void init_default_irqs(uint16_t cpu_id);