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

[Xen-changelog] [xen staging] x86: track when in NMI context



commit 88f8b8daa96de9062bb05b7d57f8f4ca2a77a834
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Wed Feb 26 17:37:22 2020 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Feb 26 17:37:22 2020 +0100

    x86: track when in NMI context
    
    Add helpers to track when running in NMI handler context. This is
    modeled after the in_irq helpers.
    
    The SDM states that no NMI can be delivered while handling a NMI
    until the processor has executed an iret instruction. It's possible
    however that another fault is received while handling the NMI (a #MC
    for example), and thus the iret from that fault would allow further
    NMIs to be injected while still processing the previous one, and
    hence an integer is needed in order to keep track of in service NMIs.
    The added macros only track when the execution context is in the NMI
    handler, but that doesn't mean NMIs are blocked for the reasons listed
    above.
    
    Note that there are no users of in_nmi_handler() introduced by the
    change, further users will be added by followup changes.
    
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/traps.c          | 6 ++++++
 xen/include/asm-x86/hardirq.h | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 3dbc66bb64..f4f2c13ae9 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1692,9 +1692,13 @@ void do_nmi(const struct cpu_user_regs *regs)
     bool handle_unknown = false;
 
     this_cpu(nmi_count)++;
+    nmi_enter();
 
     if ( nmi_callback(regs, cpu) )
+    {
+        nmi_exit();
         return;
+    }
 
     /*
      * Accessing port 0x61 may trap to SMM which has been actually
@@ -1720,6 +1724,8 @@ void do_nmi(const struct cpu_user_regs *regs)
         if ( !(reason & 0xc0) && handle_unknown )
             unknown_nmi_error(regs, reason);
     }
+
+    nmi_exit();
 }
 
 nmi_callback_t *set_nmi_callback(nmi_callback_t *callback)
diff --git a/xen/include/asm-x86/hardirq.h b/xen/include/asm-x86/hardirq.h
index 802f91cfdf..069e48fce9 100644
--- a/xen/include/asm-x86/hardirq.h
+++ b/xen/include/asm-x86/hardirq.h
@@ -7,6 +7,7 @@
 typedef struct {
        unsigned int __softirq_pending;
        unsigned int __local_irq_count;
+       unsigned int nmi_count;
        bool_t __mwait_wakeup;
 } __cacheline_aligned irq_cpustat_t;
 
@@ -17,6 +18,11 @@ typedef struct {
 #define irq_enter()    (local_irq_count(smp_processor_id())++)
 #define irq_exit()     (local_irq_count(smp_processor_id())--)
 
+#define nmi_count(cpu)         __IRQ_STAT(cpu, nmi_count)
+#define in_nmi_handler()       (nmi_count(smp_processor_id()) != 0)
+#define nmi_enter()            (nmi_count(smp_processor_id())++)
+#define nmi_exit()             (nmi_count(smp_processor_id())--)
+
 void ack_bad_irq(unsigned int irq);
 
 extern void apic_intr_init(void);
--
generated by git-patchbot for /home/xen/git/xen.git#staging

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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