bitkeeper revision 1.1159.223.54 (41ff4a05JwUWXLAjyzybyxNxCOE3yw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 1 Feb 2005 09:21:09 +0000 (09:21 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 1 Feb 2005 09:21:09 +0000 (09:21 +0000)
Defer NMI that cannot be handled, instead of dropping it completely.

xen/arch/x86/traps.c
xen/arch/x86/x86_32/asm-offsets.c
xen/arch/x86/x86_32/entry.S
xen/include/asm-x86/apicdef.h
xen/include/asm-x86/processor.h

index 2bdb160373a19b14980db7e3935642aef61705b9..d053705c135c991f1392d9c119745a8c6f56d135 100644 (file)
@@ -803,6 +803,7 @@ void __init trap_init(void)
     set_intr_gate(TRAP_alignment_check,&alignment_check);
     set_intr_gate(TRAP_machine_check,&machine_check);
     set_intr_gate(TRAP_simd_error,&simd_coprocessor_error);
+    set_intr_gate(TRAP_deferred_nmi,&nmi);
 
     /* Only ring 1 can access Xen services. */
     _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall);
index f187acbc4c132e96ed1504b12496a25ad7462fe0..a85aa15db4030134983f130a26c286e69cdb1cb8 100644 (file)
@@ -67,4 +67,7 @@ void __dummy__(void)
     OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]);
     OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]);
     OFFSET(MULTICALL_result, multicall_entry_t, args[5]);
+    BLANK();
+
+    DEFINE(FIXMAP_apic_base, fix_to_virt(FIX_APIC_BASE));
 }
index 7eb7c9075cdfec3eff9a428f03b7cfd286a918aa..aeef45059c231512932cd56d71c3210607f21304 100644 (file)
@@ -57,6 +57,7 @@
 #include <xen/errno.h>
 #include <xen/softirq.h>
 #include <asm/asm_defns.h>
+#include <asm/apicdef.h>
 #include <public/xen.h>
 
 #define GET_CURRENT(reg)   \
@@ -497,10 +498,10 @@ ENTRY(nmi)
         jnz   do_watchdog_tick
         movl  %ds,%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   restore_all_xen
+        jne   defer_nmi
         movl  %es,%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   restore_all_xen
+        jne   defer_nmi
 
 do_watchdog_tick:
         movl  $(__HYPERVISOR_DS),%edx
@@ -518,6 +519,17 @@ do_watchdog_tick:
         GET_CURRENT(%ebx)
         jmp   restore_all_guest
 
+defer_nmi:
+        movl  $FIXMAP_apic_base,%eax
+        # apic_wait_icr_idle()
+1:      movl  APIC_ICR(%eax),%ebx
+        testl $APIC_ICR_BUSY,%ebx
+        jnz   1b
+        # __send_IPI_shortcut(APIC_DEST_SELF, TRAP_deferred_nmi)
+        movl  $(APIC_DM_FIXED | APIC_DEST_SELF | APIC_DEST_LOGICAL | \
+                TRAP_deferred_nmi),APIC_ICR(%eax)
+        jmp   restore_all_xen
+
 nmi_parity_err:
         # Clear and disable the parity-error line
         andb $0xf,%al
index 9f07409b3ff1519b8ffc5bc30712639b92a8da69..8d7f3aa3d760daa8ad8e47157826047700b741a0 100644 (file)
 #define APIC_BROADCAST_ID_XAPIC (0xFF)
 #define APIC_BROADCAST_ID_APIC  (0x0F)
 
-/*
- * the local APIC register structure, memory mapped. Not terribly well
- * tested, but we might eventually use this one in the future - the
- * problem why we cannot use it right now is the P5 APIC, it has an
- * errata which cannot take 8-bit reads and writes, only 32-bit ones ...
- */
-#define u32 unsigned int
-
-#define lapic ((volatile struct local_apic *)APIC_BASE)
-
-struct local_apic {
-
-/*000*/        struct { u32 __reserved[4]; } __reserved_01;
-
-/*010*/        struct { u32 __reserved[4]; } __reserved_02;
-
-/*020*/        struct { /* APIC ID Register */
-               u32   __reserved_1      : 24,
-                       phys_apic_id    :  4,
-                       __reserved_2    :  4;
-               u32 __reserved[3];
-       } id;
-
-/*030*/        const
-       struct { /* APIC Version Register */
-               u32   version           :  8,
-                       __reserved_1    :  8,
-                       max_lvt         :  8,
-                       __reserved_2    :  8;
-               u32 __reserved[3];
-       } version;
-
-/*040*/        struct { u32 __reserved[4]; } __reserved_03;
-
-/*050*/        struct { u32 __reserved[4]; } __reserved_04;
-
-/*060*/        struct { u32 __reserved[4]; } __reserved_05;
-
-/*070*/        struct { u32 __reserved[4]; } __reserved_06;
-
-/*080*/        struct { /* Task Priority Register */
-               u32   priority  :  8,
-                       __reserved_1    : 24;
-               u32 __reserved_2[3];
-       } tpr;
-
-/*090*/        const
-       struct { /* Arbitration Priority Register */
-               u32   priority  :  8,
-                       __reserved_1    : 24;
-               u32 __reserved_2[3];
-       } apr;
-
-/*0A0*/        const
-       struct { /* Processor Priority Register */
-               u32   priority  :  8,
-                       __reserved_1    : 24;
-               u32 __reserved_2[3];
-       } ppr;
-
-/*0B0*/        struct { /* End Of Interrupt Register */
-               u32   eoi;
-               u32 __reserved[3];
-       } eoi;
-
-/*0C0*/        struct { u32 __reserved[4]; } __reserved_07;
-
-/*0D0*/        struct { /* Logical Destination Register */
-               u32   __reserved_1      : 24,
-                       logical_dest    :  8;
-               u32 __reserved_2[3];
-       } ldr;
-
-/*0E0*/        struct { /* Destination Format Register */
-               u32   __reserved_1      : 28,
-                       model           :  4;
-               u32 __reserved_2[3];
-       } dfr;
-
-/*0F0*/        struct { /* Spurious Interrupt Vector Register */
-               u32     spurious_vector :  8,
-                       apic_enabled    :  1,
-                       focus_cpu       :  1,
-                       __reserved_2    : 22;
-               u32 __reserved_3[3];
-       } svr;
-
-/*100*/        struct { /* In Service Register */
-/*170*/                u32 bitfield;
-               u32 __reserved[3];
-       } isr [8];
-
-/*180*/        struct { /* Trigger Mode Register */
-/*1F0*/                u32 bitfield;
-               u32 __reserved[3];
-       } tmr [8];
-
-/*200*/        struct { /* Interrupt Request Register */
-/*270*/                u32 bitfield;
-               u32 __reserved[3];
-       } irr [8];
-
-/*280*/        union { /* Error Status Register */
-               struct {
-                       u32   send_cs_error                     :  1,
-                               receive_cs_error                :  1,
-                               send_accept_error               :  1,
-                               receive_accept_error            :  1,
-                               __reserved_1                    :  1,
-                               send_illegal_vector             :  1,
-                               receive_illegal_vector          :  1,
-                               illegal_register_address        :  1,
-                               __reserved_2                    : 24;
-                       u32 __reserved_3[3];
-               } error_bits;
-               struct {
-                       u32 errors;
-                       u32 __reserved_3[3];
-               } all_errors;
-       } esr;
-
-/*290*/        struct { u32 __reserved[4]; } __reserved_08;
-
-/*2A0*/        struct { u32 __reserved[4]; } __reserved_09;
-
-/*2B0*/        struct { u32 __reserved[4]; } __reserved_10;
-
-/*2C0*/        struct { u32 __reserved[4]; } __reserved_11;
-
-/*2D0*/        struct { u32 __reserved[4]; } __reserved_12;
-
-/*2E0*/        struct { u32 __reserved[4]; } __reserved_13;
-
-/*2F0*/        struct { u32 __reserved[4]; } __reserved_14;
-
-/*300*/        struct { /* Interrupt Command Register 1 */
-               u32   vector                    :  8,
-                       delivery_mode           :  3,
-                       destination_mode        :  1,
-                       delivery_status         :  1,
-                       __reserved_1            :  1,
-                       level                   :  1,
-                       trigger                 :  1,
-                       __reserved_2            :  2,
-                       shorthand               :  2,
-                       __reserved_3            :  12;
-               u32 __reserved_4[3];
-       } icr1;
-
-/*310*/        struct { /* Interrupt Command Register 2 */
-               union {
-                       u32   __reserved_1      : 24,
-                               phys_dest       :  4,
-                               __reserved_2    :  4;
-                       u32   __reserved_3      : 24,
-                               logical_dest    :  8;
-               } dest;
-               u32 __reserved_4[3];
-       } icr2;
-
-/*320*/        struct { /* LVT - Timer */
-               u32   vector            :  8,
-                       __reserved_1    :  4,
-                       delivery_status :  1,
-                       __reserved_2    :  3,
-                       mask            :  1,
-                       timer_mode      :  1,
-                       __reserved_3    : 14;
-               u32 __reserved_4[3];
-       } lvt_timer;
-
-/*330*/        struct { u32 __reserved[4]; } __reserved_15;
-
-/*340*/        struct { /* LVT - Performance Counter */
-               u32   vector            :  8,
-                       delivery_mode   :  3,
-                       __reserved_1    :  1,
-                       delivery_status :  1,
-                       __reserved_2    :  3,
-                       mask            :  1,
-                       __reserved_3    : 15;
-               u32 __reserved_4[3];
-       } lvt_pc;
-
-/*350*/        struct { /* LVT - LINT0 */
-               u32   vector            :  8,
-                       delivery_mode   :  3,
-                       __reserved_1    :  1,
-                       delivery_status :  1,
-                       polarity        :  1,
-                       remote_irr      :  1,
-                       trigger         :  1,
-                       mask            :  1,
-                       __reserved_2    : 15;
-               u32 __reserved_3[3];
-       } lvt_lint0;
-
-/*360*/        struct { /* LVT - LINT1 */
-               u32   vector            :  8,
-                       delivery_mode   :  3,
-                       __reserved_1    :  1,
-                       delivery_status :  1,
-                       polarity        :  1,
-                       remote_irr      :  1,
-                       trigger         :  1,
-                       mask            :  1,
-                       __reserved_2    : 15;
-               u32 __reserved_3[3];
-       } lvt_lint1;
-
-/*370*/        struct { /* LVT - Error */
-               u32   vector            :  8,
-                       __reserved_1    :  4,
-                       delivery_status :  1,
-                       __reserved_2    :  3,
-                       mask            :  1,
-                       __reserved_3    : 15;
-               u32 __reserved_4[3];
-       } lvt_error;
-
-/*380*/        struct { /* Timer Initial Count Register */
-               u32   initial_count;
-               u32 __reserved_2[3];
-       } timer_icr;
-
-/*390*/        const
-       struct { /* Timer Current Count Register */
-               u32   curr_count;
-               u32 __reserved_2[3];
-       } timer_ccr;
-
-/*3A0*/        struct { u32 __reserved[4]; } __reserved_16;
-
-/*3B0*/        struct { u32 __reserved[4]; } __reserved_17;
-
-/*3C0*/        struct { u32 __reserved[4]; } __reserved_18;
-
-/*3D0*/        struct { u32 __reserved[4]; } __reserved_19;
-
-/*3E0*/        struct { /* Timer Divide Configuration Register */
-               u32   divisor           :  4,
-                       __reserved_1    : 28;
-               u32 __reserved_2[3];
-       } timer_dcr;
-
-/*3F0*/        struct { u32 __reserved[4]; } __reserved_20;
-
-} __attribute__ ((packed));
-
-#undef u32
-
 #endif
index 55deb004a9769eb151b74c21eee6679f55f2025e..e3446aaeae5aecec4fa356fdf61c61fb32ddf9d1 100644 (file)
 #define TRAP_alignment_check 17
 #define TRAP_machine_check   18
 #define TRAP_simd_error      19
+#define TRAP_deferred_nmi    31
 
 /*
  * Non-fatal fault/trap handlers return an error code to the caller. If the