[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 1/2] x86/hvm: don't let EFLAGS.IF block NMI/#MC due to nested state


  • To: chunjie.zhu@xxxxxxxxxx
  • From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
  • Date: Tue, 10 Nov 2026 17:36:56 +0000
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nEzt5PLBYKoocXUSBJwvrYheorBJZJhabmHGtVyxvj8=; b=B/eHmfuCSV3hdSkXDT5AVLyA8VHPeY+3SS1RRtD1zF7j8dcTOWCu+Y9s59ZZFV3M4sPBDFJz+dlj74myc3WRX+ilHJoTj7QP7duAiCbdAKFQthxqnxAycESI78CWh6TN0Dv9psB4FKORCWQaQA6+/Gd3iDSahEa/ExTaZQXy7WM+UtFHlQ7kPu33jOT6klhB9QJKYgwr9dh5fszqJvpbvjz61Vwf1Q7SkH4euiyTU7VHKNp8vIjto5lr0C+d5GY0jkqLkP9lSNiGfwLijOnveZs/EJOIpKeXgg8FdXjhuaaQv4nwi03dxwSa1ea4lP3cgbMvioJMJH++90X32xn6ow==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=G25j9gLLtnIJGYUF5yUvM8DamaJ8nlrG142Rm8KtY9Ntp400DK4smNod18qPPQL8+JT36QRiGyJ3LxOxNahMQqdplsSzjYCB1HHkfsXEZ12yMX0lNe9BzIqCc2IaYCg2ZoFpx4fk++d6JIMX3NaigVk2sHR5wtXkSGPgXGkdoWfuFHBvFaniX0guFne2eszRaoMZV0zIijsp42F7FlwWYNw1oozlRKxEwHvlxUhWIo0QXd+C2/N+UvR94d3LW/ZsSMkKIXqsgUT59lRsMnSqv1TEqgD+oi8X+XVU2EGZmKNW+uPyoLQsaYVFm9FfCl56jecKkREvIJSmGPbS1GK/FA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: andrew.cooper3@xxxxxxxxxx, jason.andryuk@xxxxxxx, jbeulich@xxxxxxxx, roger@xxxxxxxxxxxxxx, teddy.astie@xxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Tue, 10 Nov 2026 17:37:16 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 11/10/26 8:57 AM, chunjie.zhu@xxxxxxxxxx wrote:
From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>

nhvm_interrupt_blocked() reports why an interrupt is blocked, but both
callers, nestedsvm_vcpu_interrupt() and hvm_interrupt_blocked(), treat any
reason as blocking every event source.  EFLAGS.IF (hvm_intblk_rflags_ie)
doesn't mask NMI or #MC, so NMI/#MC get held pending needlessly, e.g. when
L1 sets V_INTR_MASKING and L1's IF is clear.

Have nhvm_interrupt_blocked() take the intack and report no block for
NMI/#MC when the reason is hvm_intblk_rflags_ie.

nvmx_intr_blocked() used hvm_intblk_rflags_ie for vmexit/vmentry in
progress and a valid VM_ENTRY_INTR_INFO.  Those block every event source
and have nothing to do with RFLAGS.IF, so report hvm_intblk_arch instead.
This doesn't change behaviour as all callers only compare against
hvm_intblk_none and hvm_intblk_tpr.

Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
---
v2:
  * New patch.  Handle the blocking reason in callers, as suggested by Ross.
  * Report hvm_intblk_arch from nvmx_intr_blocked() so the NMI/#MC exemption
    doesn't affect VMX.

  xen/arch/x86/hvm/hvm.c             |  2 +-
  xen/arch/x86/hvm/svm/nestedsvm.c   |  2 +-
  xen/arch/x86/hvm/vmx/intr.c        |  6 +++---
  xen/arch/x86/include/asm/hvm/hvm.h | 12 ++++++++++--
  4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ef9c7cd05777..8fd095a4f8e6 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3897,7 +3897,7 @@ enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, 
struct hvm_intack intack)
      if ( nestedhvm_enabled(v->domain) ) {
          enum hvm_intblk intr;
- intr = nhvm_interrupt_blocked(v);
+        intr = nhvm_interrupt_blocked(v, intack);
          if ( intr != hvm_intblk_none )
              return intr;
      }
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 66b77c6efe7d..a93681e9bbcd 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1496,7 +1496,7 @@ nestedsvm_vcpu_interrupt(struct vcpu *v, const struct 
hvm_intack intack)
      uint64_t exitinfo2 = 0;
      ASSERT(nestedhvm_vcpu_in_guestmode(v));
- intr = nhvm_interrupt_blocked(v);
+    intr = nhvm_interrupt_blocked(v, intack);
      if ( intr != hvm_intblk_none )
          return NSVM_INTR_MASKED;
diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c
index 6c220c4c2e49..38be2387739d 100644
--- a/xen/arch/x86/hvm/vmx/intr.c
+++ b/xen/arch/x86/hvm/vmx/intr.c
@@ -142,18 +142,18 @@ enum hvm_intblk cf_check nvmx_intr_blocked(struct vcpu *v)
      {
          if ( nvcpu->nv_vmexit_pending ||
               nvcpu->nv_vmswitch_in_progress )
-            r = hvm_intblk_rflags_ie;
+            r = hvm_intblk_arch;
          else
          {
              unsigned long intr_info;
__vmread(VM_ENTRY_INTR_INFO, &intr_info);
              if ( intr_info & INTR_INFO_VALID_MASK )
-                r = hvm_intblk_rflags_ie;
+                r = hvm_intblk_arch;
          }
      }
      else if ( nvcpu->nv_vmentry_pending )
-        r = hvm_intblk_rflags_ie;
+        r = hvm_intblk_arch;
return r;
  }
diff --git a/xen/arch/x86/include/asm/hvm/hvm.h 
b/xen/arch/x86/include/asm/hvm/hvm.h
index 02d9c44373ff..3e03a08a4818 100644
--- a/xen/arch/x86/include/asm/hvm/hvm.h
+++ b/xen/arch/x86/include/asm/hvm/hvm.h
@@ -682,9 +682,17 @@ static inline bool nhvm_vmcx_hap_enabled(struct vcpu *v)
  }
/* interrupt */
-static inline enum hvm_intblk nhvm_interrupt_blocked(struct vcpu *v)
+static inline enum hvm_intblk nhvm_interrupt_blocked(
+    struct vcpu *v, const struct hvm_intack intack)
  {
-    return alternative_call(hvm_funcs.nhvm_intr_blocked, v);
+    enum hvm_intblk intr = alternative_call(hvm_funcs.nhvm_intr_blocked, v);
+
+    /* EFLAGS.IF doesn't mask NMI or #MC. */
+    if ( intr == hvm_intblk_rflags_ie &&
+         (intack.source == hvm_intsrc_nmi || intack.source == hvm_intsrc_mce) )
+        return hvm_intblk_none;
+
+    return intr;
  }

Not specifically for this patch, but I note that hvm_interrupt_blocked()
similarly checks the interrupt flag but only ignores it for NMIs, not MCEs.
That should probably be fixed.

Ross



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.