Skip to contentSkip to conversation

Machine Check Support

PATCH New Christoph Egger 1 participant 1 message Jul 4, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 Machine Check Support

Hi,

This patch introduces machine check support as described in the pdf.

Signature · 12 lines
AMD Saxony, Dresden, Germany
Operating System Research Center

Legal Information:
AMD Saxony Limited Liability Company & Co. KG
Sitz (Geschäftsanschrift):
   Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland
Registergericht Dresden: HRA 4896
vertretungsberechtigter Komplementär:
   AMD Saxony LLC (Sitz Wilmington, Delaware, USA)
Geschäftsführer der AMD Saxony LLC:
   Dr. Hans-R. Deppe, Thomas McCoy
xen/arch/x86/cpu/mcheck/Makefile +3 -0
diff -r 0b2eb9d85620 xen/arch/x86/cpu/mcheck/Makefile
@@ -1,4 +1,7 @@ obj-y += k7.o
+obj-y += amd_nonfatal.o
 obj-y += k7.o
+obj-y += amd_k8.o
+obj-y += amd_f10.o
 obj-y += mce.o
 obj-y += non-fatal.o
 obj-y += p4.o
xen/arch/x86/cpu/mcheck/amd_f10.c new file +131 -0

131 lines not on this page · raw message

xen/arch/x86/cpu/mcheck/amd_k8.c new file +324 -0

324 lines not on this page · raw message

xen/arch/x86/cpu/mcheck/amd_nonfatal.c new file +303 -0

303 lines not on this page · raw message

xen/arch/x86/cpu/mcheck/k7.c +3 -4
diff -r 0b2eb9d85620 xen/arch/x86/cpu/mcheck/k7.c
@@ -66,8 +66,8 @@ static fastcall void k7_machine_check(st
 }
 
 
-/* AMD K7 machine check is Intel like */
-void amd_mcheck_init(struct cpuinfo_x86 *c)
+/* AMD K7 machine check */
+void amd_k7_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
@@ -75,7 +75,6 @@ void amd_mcheck_init(struct cpuinfo_x86 
 	machine_check_vector = k7_machine_check;
 	wmb();
 
-	printk (KERN_INFO "Intel machine check architecture supported.\n");
 	rdmsr (MSR_IA32_MCG_CAP, l, h);
 	if (l & (1<<8))	/* Control register present ? */
 		wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
@@ -90,6 +89,6 @@ void amd_mcheck_init(struct cpuinfo_x86 
 	}
 
 	set_in_cr4 (X86_CR4_MCE);
-	printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
+	printk (KERN_INFO "CPU%d: AMD K7 machine check reporting enabled.\n",
 		smp_processor_id());
 }
xen/arch/x86/cpu/mcheck/mce.c +521 -35

597 lines not on this page · raw message

xen/arch/x86/cpu/mcheck/mce.h +21 -5
diff -r 0b2eb9d85620 xen/arch/x86/cpu/mcheck/mce.h
@@ -1,14 +1,30 @@
 #include <xen/init.h>
+#include <asm/traps.h>
 
-void amd_mcheck_init(struct cpuinfo_x86 *c);
+/* Init functions */
+void amd_nonfatal_mcheck_init(struct cpuinfo_x86 *c);
+void amd_k7_mcheck_init(struct cpuinfo_x86 *c);
+void amd_k8_mcheck_init(struct cpuinfo_x86 *c);
+void amd_f10_mcheck_init(struct cpuinfo_x86 *c);
 void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
 void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
 void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
 void winchip_mcheck_init(struct cpuinfo_x86 *c);
 
-/* Call the installed machine check handler for this CPU setup. */
-extern fastcall void (*machine_check_vector)(struct cpu_user_regs *, long error_code);
+/* Function pointer used in the handlers to collect additional information
+ * provided by newer CPU families/models without the need to duplicate
+ * the whole handler resulting in various handlers each with its own
+ * tweaks and bugs */
+extern int (*mc_callback_bank_extended)(struct mc_info *mi,
+		uint16_t bank, uint64_t status);
 
+
+/* Helper functions used for collecting error telemetry */
+struct mc_info *x86_mcinfo_getptr(void);
+void x86_mcinfo_clear(struct mc_info *mi);
+int x86_mcinfo_add(struct mc_info *mi, void *mcinfo);
+void x86_mcinfo_dump(struct mc_info *mi);
+
+/* Global variables */
 extern int mce_disabled __initdata;
-extern int nr_mce_banks;
-
+extern unsigned int nr_mce_banks;
xen/arch/x86/cpu/mcheck/non-fatal.c +20 -10
diff -r 0b2eb9d85620 xen/arch/x86/cpu/mcheck/non-fatal.c
@@ -68,19 +68,29 @@ static int __init init_nonfatal_mce_chec
 	if (!cpu_has(c, X86_FEATURE_MCA))
 		return -ENODEV;
 
-	/* Some Athlons misbehave when we frob bank 0 */
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-		boot_cpu_data.x86 == 6)
-			firstbank = 1;
-	else
-			firstbank = 0;
-
 	/*
 	 * Check for non-fatal errors every MCE_RATE s
 	 */
-	init_timer(&mce_timer, mce_work_fn, NULL, 0);
-	set_timer(&mce_timer, NOW() + MCE_PERIOD);
-	printk(KERN_INFO "Machine check exception polling timer started.\n");
+	switch (c->x86_vendor) {
+	case X86_VENDOR_AMD:
+		if (c->x86 == 6) { /* K7 */
+			firstbank = 1;
+			init_timer(&mce_timer, mce_work_fn, NULL, 0);
+			set_timer(&mce_timer, NOW() + MCE_PERIOD);
+			break;
+		}
+
+		/* Assume we are on K8 or newer AMD CPU here */
+		amd_nonfatal_mcheck_init(c);
+		break;
+
+	case X86_VENDOR_INTEL:
+		init_timer(&mce_timer, mce_work_fn, NULL, 0);
+		set_timer(&mce_timer, NOW() + MCE_PERIOD);
+		break;
+	}
+
+	printk(KERN_INFO "MCA: Machine check polling timer started.\n");
 	return 0;
 }
 __initcall(init_nonfatal_mce_checker);
xen/arch/x86/cpu/mcheck/x86_mca.h new file +72 -0

72 lines not on this page · raw message

xen/arch/x86/nmi.c +2 -2
diff -r 0b2eb9d85620 xen/arch/x86/nmi.c
@@ -457,10 +457,10 @@ static void do_nmi_stats(unsigned char k
     if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) )
         return;
 
-    if ( v->nmi_pending || v->nmi_masked )
+    if ( v->nmi_pending || (v->trap_priority >= VCPU_TRAP_NMI) )
         printk("dom0 vpu0: NMI %s%s\n",
                v->nmi_pending ? "pending " : "",
-               v->nmi_masked  ? "masked " : "");
+               (v->trap_priority >= VCPU_TRAP_NMI)  ? "masked " : "");
     else
         printk("dom0 vcpu0: NMI neither pending nor masked\n");
 }
xen/arch/x86/traps.c +49 -2

75 lines not on this page · raw message

xen/arch/x86/x86_32/asm-offsets.c +5 -1
diff -r 0b2eb9d85620 xen/arch/x86/x86_32/asm-offsets.c
@@ -67,7 +67,11 @@ void __dummy__(void)
            arch.guest_context.kernel_sp);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
     OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
-    OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
+    OFFSET(VCPU_mce_pending, struct vcpu, mce_pending);
+    OFFSET(VCPU_old_trap_priority, struct vcpu, old_trap_priority);
+    OFFSET(VCPU_trap_priority, struct vcpu, trap_priority);
+    DEFINE(VCPU_TRAP_NMI, VCPU_TRAP_NMI);
+    DEFINE(VCPU_TRAP_MCE, VCPU_TRAP_MCE);
     DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
     BLANK();
 
xen/arch/x86/x86_32/entry.S +33 -3
diff -r 0b2eb9d85620 xen/arch/x86/x86_32/entry.S
@@ -229,6 +229,8 @@ test_all_events:
         shl  $IRQSTAT_shift,%eax
         test %ecx,irq_stat(%eax,1)
         jnz  process_softirqs
+        testb $1,VCPU_mce_pending(%ebx)
+        jnz  process_mce
         testb $1,VCPU_nmi_pending(%ebx)
         jnz  process_nmi
 test_guest_events:
@@ -255,15 +257,35 @@ process_softirqs:
         jmp  test_all_events
 
         ALIGN
+/* %ebx: struct vcpu */
+process_mce:
+        cmpw $VCPU_TRAP_MCE,VCPU_trap_priority(%ebx)
+        jae  test_guest_events
+        sti
+        movb $0,VCPU_mce_pending(%ebx)
+        call set_guest_machinecheck_trapbounce
+        test %eax,%eax
+        jz   test_all_events
+        movw VCPU_trap_priority(%ebx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%ebx)       # iret hypercall
+        movw $VCPU_TRAP_MCE,VCPU_trap_priority(%ebx)
+        jmp process_trap
+
+        ALIGN
+/* %ebx: struct vcpu */
 process_nmi:
-        testb $1,VCPU_nmi_masked(%ebx)
-        jnz  test_guest_events
+        cmpw $VCPU_TRAP_NMI,VCPU_trap_priority(%ebx)
+        jae  test_guest_events
         sti
         movb $0,VCPU_nmi_pending(%ebx)
         call set_guest_nmi_trapbounce
         test %eax,%eax
         jz   test_all_events
-        movb $1,VCPU_nmi_masked(%ebx)
+        movw VCPU_trap_priority(%ebx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%ebx)       # iret hypercall
+        movw $VCPU_TRAP_NMI,VCPU_trap_priority(%ebx)
+        /* FALLTHROUGH */
+process_trap:
         leal VCPU_trap_bounce(%ebx),%edx
         call create_bounce_frame
         jmp  test_all_events
@@ -681,6 +703,10 @@ ENTRY(hypercall_table)
         .long do_sysctl             /* 35 */
         .long do_domctl
         .long do_kexec_op
+        .rept __HYPERVISOR_arch_0-((.-hypercall_table)/4)
+        .long do_ni_hypercall
+        .endr
+        .long do_mca                /* 48 */
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -724,6 +750,10 @@ ENTRY(hypercall_args_table)
         .byte 1 /* do_sysctl            */  /* 35 */
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec_op          */
+        .rept __HYPERVISOR_arch_0-(.-hypercall_args_table)
+        .byte 0 /* do_ni_hypercall      */
+        .endr
+        .byte 1 /* do_mca               */  /* 48 */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
xen/arch/x86/x86_32/traps.c +2 -2
diff -r 0b2eb9d85620 xen/arch/x86/x86_32/traps.c
@@ -259,8 +259,8 @@ unsigned long do_iret(void)
     if (!cpus_equal(v->cpu_affinity_tmp, v->cpu_affinity))
         vcpu_set_affinity(v, &v->cpu_affinity_tmp);
 
-    /* No longer in NMI context. */
-    v->nmi_masked = 0;
+    /* Restore previous trap priority */
+    v->trap_priority = v->old_trap_priority;
 
     /* Restore upcall mask from supplied EFLAGS.IF. */
     vcpu_info(v, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF);
xen/arch/x86/x86_64/asm-offsets.c +5 -1
diff -r 0b2eb9d85620 xen/arch/x86/x86_64/asm-offsets.c
@@ -92,7 +92,11 @@ void __dummy__(void)
     OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss);
     OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
     OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
-    OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
+    OFFSET(VCPU_mce_pending, struct vcpu, mce_pending);
+    OFFSET(VCPU_old_trap_priority, struct vcpu, old_trap_priority);
+    OFFSET(VCPU_trap_priority, struct vcpu, trap_priority);
+    DEFINE(VCPU_TRAP_NMI, VCPU_TRAP_NMI);
+    DEFINE(VCPU_TRAP_MCE, VCPU_TRAP_MCE);
     DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
     DEFINE(_VGCF_syscall_disables_events,  _VGCF_syscall_disables_events);
     BLANK();
xen/arch/x86/x86_64/compat/entry.S +32 -3
diff -r 0b2eb9d85620 xen/arch/x86/x86_64/compat/entry.S
@@ -101,6 +101,8 @@ ENTRY(compat_test_all_events)
         leaq  irq_stat(%rip),%rcx
         testl $~0,(%rcx,%rax,1)
         jnz   compat_process_softirqs
+        testb $1,VCPU_mce_pending(%rbx)
+        jnz   compat_process_mce
         testb $1,VCPU_nmi_pending(%rbx)
         jnz   compat_process_nmi
 compat_test_guest_events:
@@ -129,15 +131,34 @@ compat_process_softirqs:
 
 	ALIGN
 /* %rbx: struct vcpu */
+compat_process_mce:
+        cmpw $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx)
+        jae  compat_test_guest_events
+        sti
+        movb $0,VCPU_mce_pending(%rbx)
+        call set_guest_machinecheck_trapbounce
+        testl %eax,%eax
+        jz    compat_test_all_events
+        movw VCPU_trap_priority(%rbx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%rbx)       # iret hypercall
+        movw  $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx)
+        jmp   compat_process_trap
+
+	ALIGN
+/* %rbx: struct vcpu */
 compat_process_nmi:
-        testb $1,VCPU_nmi_masked(%rbx)
-        jnz   compat_test_guest_events
+        cmpw $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx)
+        jae   compat_test_guest_events
         sti
         movb  $0,VCPU_nmi_pending(%rbx)
         call  set_guest_nmi_trapbounce
         testl %eax,%eax
         jz    compat_test_all_events
-        movb  $1,VCPU_nmi_masked(%rbx)
+        movw VCPU_trap_priority(%rbx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%rbx)       # iret hypercall
+        movw  $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx)
+        /* FALLTHROUGH */
+compat_process_trap:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         call  compat_create_bounce_frame
         jmp   compat_test_all_events
@@ -386,6 +407,10 @@ ENTRY(compat_hypercall_table)
         .quad do_sysctl                 /* 35 */
         .quad do_domctl
         .quad compat_kexec_op
+        .rept __HYPERVISOR_arch_0-((.-compat_hypercall_table)/8)
+        .quad compat_ni_hypercall
+        .endr
+        .quad do_mca                    /* 48 */
         .rept NR_hypercalls-((.-compat_hypercall_table)/8)
         .quad compat_ni_hypercall
         .endr
@@ -429,6 +454,10 @@ ENTRY(compat_hypercall_args_table)
         .byte 1 /* do_sysctl                */  /* 35 */
         .byte 1 /* do_domctl                */
         .byte 2 /* compat_kexec_op          */
+        .rept __HYPERVISOR_arch_0-(.-compat_hypercall_args_table)
+        .byte 0 /* compat_ni_hypercall      */
+        .endr
+        .byte 1 /* do_mca                   */
         .rept NR_hypercalls-(.-compat_hypercall_args_table)
         .byte 0 /* compat_ni_hypercall      */
         .endr
xen/arch/x86/x86_64/compat/traps.c +2 -2
diff -r 0b2eb9d85620 xen/arch/x86/x86_64/compat/traps.c
@@ -125,8 +125,8 @@ unsigned int compat_iret(void)
     if (!cpus_equal(v->cpu_affinity_tmp, v->cpu_affinity))
         vcpu_set_affinity(v, &v->cpu_affinity_tmp);
 
-    /* No longer in NMI context. */
-    v->nmi_masked = 0;
+    /* Restore previous trap priority */
+    v->trap_priority = v->old_trap_priority;
 
     /* Restore upcall mask from supplied EFLAGS.IF. */
     vcpu_info(v, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF);
xen/arch/x86/x86_64/entry.S +32 -3
diff -r 0b2eb9d85620 xen/arch/x86/x86_64/entry.S
@@ -205,6 +205,8 @@ test_all_events:
         leaq  irq_stat(%rip),%rcx
         testl $~0,(%rcx,%rax,1)
         jnz   process_softirqs
+        testb $1,VCPU_mce_pending(%rbx)
+        jnz   process_mce
         testb $1,VCPU_nmi_pending(%rbx)
         jnz   process_nmi
 test_guest_events:
@@ -231,15 +233,34 @@ process_softirqs:
 
         ALIGN
 /* %rbx: struct vcpu */
+process_mce:
+        cmpw $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx)
+        jae  test_guest_events
+        sti
+        movb $0,VCPU_mce_pending(%rbx)
+        call set_guest_machinecheck_trapbounce
+        test %eax,%eax
+        jz   test_all_events
+        movw VCPU_trap_priority(%rbx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%rbx)       # iret hypercall
+        movw $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx)
+        jmp  process_trap
+
+        ALIGN
+/* %rbx: struct vcpu */
 process_nmi:
-        testb $1,VCPU_nmi_masked(%rbx)
-        jnz  test_guest_events
+        cmpw $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx)
+        jae  test_guest_events
         sti
         movb $0,VCPU_nmi_pending(%rbx)
         call set_guest_nmi_trapbounce
         test %eax,%eax
         jz   test_all_events
-        movb $1,VCPU_nmi_masked(%rbx)
+        movw VCPU_trap_priority(%rbx),%dx           # safe priority for the
+        movw %dx,VCPU_old_trap_priority(%rbx)       # iret hypercall
+        movw $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx)
+        /* FALLTHROUGH */
+process_trap:
         leaq VCPU_trap_bounce(%rbx),%rdx
         call create_bounce_frame
         jmp  test_all_events
@@ -671,6 +692,10 @@ ENTRY(hypercall_table)
         .quad do_sysctl             /* 35 */
         .quad do_domctl
         .quad do_kexec_op
+        .rept __HYPERVISOR_arch_0-((.-hypercall_table)/8)
+        .quad do_ni_hypercall
+        .endr
+        .quad do_mca                /* 48 */
         .rept NR_hypercalls-((.-hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
@@ -715,6 +740,10 @@ ENTRY(hypercall_args_table)
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec             */
         .byte 1 /* do_xsm_op            */
+        .rept __HYPERVISOR_arch_0-(.-hypercall_args_table)
+        .byte 0 /* do_ni_hypercall      */
+        .endr
+        .byte 1 /* do_mca               */  /* 48 */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
xen/arch/x86/x86_64/traps.c +2 -2
diff -r 0b2eb9d85620 xen/arch/x86/x86_64/traps.c
@@ -292,8 +292,8 @@ unsigned long do_iret(void)
     if (!cpus_equal(v->cpu_affinity_tmp, v->cpu_affinity))
         vcpu_set_affinity(v, &v->cpu_affinity_tmp);
 
-    /* No longer in NMI context. */
-    v->nmi_masked = 0;
+    /* Restore previous trap priority */
+    v->trap_priority = v->old_trap_priority;
 
     /* Restore upcall mask from supplied EFLAGS.IF. */
     vcpu_info(v, evtchn_upcall_mask) = !(iret_saved.rflags & EF_IE);
xen/common/domain.c +3 -1
diff -r 0b2eb9d85620 xen/common/domain.c
@@ -651,7 +651,9 @@ void vcpu_reset(struct vcpu *v)
     v->is_polling      = 0;
     v->is_initialised  = 0;
     v->nmi_pending     = 0;
-    v->nmi_masked      = 0;
+    v->mce_pending     = 0;
+    v->old_trap_priority = VCPU_TRAP_NONE;
+    v->trap_priority   = VCPU_TRAP_NONE;
     clear_bit(_VPF_blocked, &v->pause_flags);
 
     domain_unlock(v->domain);
xen/common/event_channel.c +15 -0
diff -r 0b2eb9d85620 xen/common/event_channel.c
@@ -586,6 +586,21 @@ void send_guest_vcpu_virq(struct vcpu *v
     evtchn_set_pending(v, port);
 }
 
+int guest_enabled_event(struct vcpu *v, int virq)
+{
+    int port;
+
+    if ( unlikely(v == NULL) )
+        return 0;
+
+    port = v->virq_to_evtchn[virq];
+    if ( port == 0 )
+        return 0;
+
+    /* virq is in use */
+    return 1;
+}
+
 void send_guest_global_virq(struct domain *d, int virq)
 {
     int port;
xen/include/Makefile +1 -0
diff -r 0b2eb9d85620 xen/include/Makefile
@@ -20,6 +20,7 @@ headers-y := \
     compat/xen.h \
     compat/xencomm.h \
     compat/xenoprof.h
+headers-$(CONFIG_X86)     += compat/arch-x86/xen-mca.h
 headers-$(CONFIG_X86)     += compat/arch-x86/xen.h
 headers-$(CONFIG_X86)     += compat/arch-x86/xen-$(compat-arch-y).h
 headers-y                 += compat/arch-$(compat-arch-y).h compat/xlat.h
xen/include/asm-x86/event.h +6 -1
diff -r 0b2eb9d85620 xen/include/asm-x86/event.h
@@ -69,7 +69,12 @@ static inline void local_event_delivery_
 /* No arch specific virq definition now. Default to global. */
 static inline int arch_virq_is_global(int virq)
 {
-    return 1;
+    switch (virq) {
+    case VIRQ_MCA:
+        return 1;
+    default:
+        return 1;
+    }
 }
 
 #endif
xen/include/asm-x86/mm.h +3 -0
diff -r 0b2eb9d85620 xen/include/asm-x86/mm.h
@@ -141,6 +141,9 @@ static inline u32 pickle_domptr(struct d
 #define page_get_owner(_p)    (unpickle_domptr((_p)->u.inuse._domain))
 #define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d))
 
+#define maddr_get_owner(ma)   (page_get_owner(maddr_to_page((ma))))
+#define vaddr_get_owner(va)   (page_get_owner(virt_to_page((va))))
+
 #define XENSHARE_writable 0
 #define XENSHARE_readonly 1
 extern void share_xen_page_with_guest(
xen/include/asm-x86/traps.h +12 -1
diff -r 0b2eb9d85620 xen/include/asm-x86/traps.h
@@ -27,6 +27,18 @@ struct softirq_trap {
 	int processor;		/* physical cpu to inject trap */
 };
 
+struct cpu_user_regs;
+
+extern void (*machine_check_vector)(struct cpu_user_regs *regs, long error_code);
+ 
+/**
+ * guest_has_trap_callback
+ *
+ * returns true (non-zero) if guest registered a trap handler
+ */
+extern int guest_has_trap_callback(struct domain *d, uint16_t vcpuid,
+				unsigned int trap_nr);
+
 /**
  * send_guest_trap
  *
@@ -36,5 +48,4 @@ extern int send_guest_trap(struct domain
 extern int send_guest_trap(struct domain *d, uint16_t vcpuid,
 				unsigned int trap_nr);
 
-
 #endif /* ASM_TRAP_H */
xen/include/public/arch-x86/xen-mca.h new file +279 -0

279 lines not on this page · raw message

xen/include/public/arch-x86/xen.h +4 -0
diff -r 0b2eb9d85620 xen/include/public/arch-x86/xen.h
@@ -76,6 +76,10 @@ typedef unsigned long xen_pfn_t;
 /* Maximum number of virtual CPUs in multi-processor guests. */
 #define MAX_VIRT_CPUS 32
 
+
+/* Machine check support */
+#include "xen-mca.h"
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned long xen_ulong_t;
xen/include/xen/event.h +3 -0
diff -r 0b2eb9d85620 xen/include/xen/event.h
@@ -51,6 +51,9 @@ void free_xen_event_channel(
 void free_xen_event_channel(
     struct vcpu *local_vcpu, int port);
 
+/* Query if event channel is in use by the guest */
+int guest_enabled_event(struct vcpu *v, int virq);
+
 /* Notify remote end of a Xen-attached event channel.*/
 void notify_via_xen_event_channel(int lport);
 
xen/include/xen/sched.h +13 -2
diff -r 0b2eb9d85620 xen/include/xen/sched.h
@@ -112,10 +112,21 @@ struct vcpu
     bool_t           is_initialised;
     /* Currently running on a CPU? */
     bool_t           is_running;
+    /* MCE callback pending for this VCPU? */
+    bool_t           mce_pending;
     /* NMI callback pending for this VCPU? */
     bool_t           nmi_pending;
-    /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
-    bool_t           nmi_masked;
+
+    /* Higher priorized traps may interrupt lower priorized traps,
+     * lower priorized traps wait until higher priorized traps finished.
+     * Note: This concept is known as "system priority level" (spl)
+     * in the UNIX world. */
+    uint16_t         old_trap_priority;
+    uint16_t         trap_priority;
+#define VCPU_TRAP_NONE    0
+#define VCPU_TRAP_NMI     1
+#define VCPU_TRAP_MCE     2
+
     /* Require shutdown to be deferred for some asynchronous operation? */
     bool_t           defer_shutdown;
     /* VCPU is paused following shutdown request (d->is_shutting_down)? */

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel