aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-02-01 09:21:09 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-02-01 09:21:09 +0000
commit4baf6e1ed5aa662f25307b63f0444e2c4a1bbda7 (patch)
tree1a64df270c7235880701642ab1fe4aa5d97383c2
parent744d0bbffba678a9335cdbe18ab7e1d10a00a2cd (diff)
downloadxen-4baf6e1ed5aa662f25307b63f0444e2c4a1bbda7.tar.gz
xen-4baf6e1ed5aa662f25307b63f0444e2c4a1bbda7.tar.bz2
xen-4baf6e1ed5aa662f25307b63f0444e2c4a1bbda7.zip
bitkeeper revision 1.1159.223.54 (41ff4a05JwUWXLAjyzybyxNxCOE3yw)
Defer NMI that cannot be handled, instead of dropping it completely.
-rw-r--r--xen/arch/x86/traps.c1
-rw-r--r--xen/arch/x86/x86_32/asm-offsets.c3
-rw-r--r--xen/arch/x86/x86_32/entry.S16
-rw-r--r--xen/include/asm-x86/apicdef.h251
-rw-r--r--xen/include/asm-x86/processor.h1
5 files changed, 19 insertions, 253 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 2bdb160373..d053705c13 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -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);
diff --git a/xen/arch/x86/x86_32/asm-offsets.c b/xen/arch/x86/x86_32/asm-offsets.c
index f187acbc4c..a85aa15db4 100644
--- a/xen/arch/x86/x86_32/asm-offsets.c
+++ b/xen/arch/x86/x86_32/asm-offsets.c
@@ -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));
}
diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S
index 7eb7c9075c..aeef45059c 100644
--- a/xen/arch/x86/x86_32/entry.S
+++ b/xen/arch/x86/x86_32/entry.S
@@ -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
diff --git a/xen/include/asm-x86/apicdef.h b/xen/include/asm-x86/apicdef.h
index 9f07409b3f..8d7f3aa3d7 100644
--- a/xen/include/asm-x86/apicdef.h
+++ b/xen/include/asm-x86/apicdef.h
@@ -125,255 +125,4 @@
#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
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 55deb004a9..e3446aaeae 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -108,6 +108,7 @@
#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