[PATCH 4/7] HV: ignore the NMI injection request for lapic-pt vCPUs


Kaige Fu
 

NMI will be used as notification signal for lapic-pt vCPUs and
we don't support vNMI yet. So, this patch ignore the pending NMI
request and EXCP with vector 2.

Signed-off-by: Kaige Fu <kaige.fu@...>
---
hypervisor/arch/x86/guest/virq.c | 55 ++++++++++++++++++++------------
1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/hypervisor/arch/x86/guest/virq.c b/hypervisor/arch/x86/guest/virq.c
index 60358534..1c9904c4 100644
--- a/hypervisor/arch/x86/guest/virq.c
+++ b/hypervisor/arch/x86/guest/virq.c
@@ -211,26 +211,36 @@ int32_t vcpu_queue_exception(struct acrn_vcpu *vcpu, uint32_t vector_arg, uint32
static void vcpu_inject_exception(struct acrn_vcpu *vcpu, uint32_t vector)
{
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EXCP, &vcpu->arch.pending_req)) {
-
- if ((exception_type[vector] & EXCEPTION_ERROR_CODE_VALID) != 0U) {
- exec_vmwrite32(VMX_ENTRY_EXCEPTION_ERROR_CODE,
- vcpu->arch.exception_info.error);
- }
+ if (is_lapic_pt_enabled(vcpu) && (vector == IDT_NMI)) {
+ /*
+ * NMI will be used as notification signal for lapic-pt vCPUs and we
+ * don't support vNMI yet. So, here we just ignore the NMI injection
+ * request.
+ */
+ pr_warn("Don't allow to inject NMI to lapic-pt vCPU%u. Ignore this request.", vcpu->vcpu_id);
+ vcpu->arch.exception_info.exception = VECTOR_INVALID;
+ } else {
+ 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));
+ exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD, VMX_INT_INFO_VALID |
+ (exception_type[vector] << 8U) | (vector & 0xFFU));

- vcpu->arch.exception_info.exception = VECTOR_INVALID;
+ vcpu->arch.exception_info.exception = VECTOR_INVALID;

- /* retain rip for exception injection */
- vcpu_retain_rip(vcpu);
+ /* retain rip for exception injection */
+ 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);
+ /* 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);
+ }
}
}
}
@@ -383,10 +393,15 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
if (!injected) {
/* inject NMI before maskable hardware interrupt */
if (bitmap_test_and_clear_lock(ACRN_REQUEST_NMI, pending_req_bits)) {
- /* Inject NMI vector = 2 */
- exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD,
- VMX_INT_INFO_VALID | (VMX_INT_TYPE_NMI << 8U) | IDT_NMI);
- injected = true;
+ if (!is_lapic_pt_enabled(vcpu)) {
+ /* Inject NMI vector = 2 */
+ exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD,
+ VMX_INT_INFO_VALID | (VMX_INT_TYPE_NMI << 8U) | IDT_NMI);
+ injected = true;
+ } else {
+ pr_warn("Don't allow to inject NMI to lapic-pt vCPU%u. Ignore this request.",
+ vcpu->vcpu_id);
+ }
} else {
/* handling pending vector injection:
* there are many reason inject failed, we need re-inject again
--
2.20.0

Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.