# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID 278e536ade72e6b31651315e12095b47f3be8676
# Parent 06ab200a9e23b1820197e3ae4a101e5b7590041b
Pass NMIs to DOM0 via a dedicated callback, Xen/Linux i386 support.
Register our NMI handler with Xen. Use a pseudo-flag in EFLAGS in
indicate that we should return from the NMI via a hypervisor iret.
Signed-off-by: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>
diff -r 06ab200a9e23 -r 278e536ade72
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Wed Jan 11 15:52:33 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Wed Jan 11 15:52:54 2006
@@ -76,7 +76,9 @@
DF_MASK = 0x00000400
NT_MASK = 0x00004000
VM_MASK = 0x00020000
-
+/* pseudo-eflags */
+NMI_MASK = 0x80000000
+
/* Offsets into shared_info_t. */
#define evtchn_upcall_pending /* 0 */
#define evtchn_upcall_mask 1
@@ -305,8 +307,8 @@
je ldt_ss # returning to user-space with LDT SS
#endif /* XEN */
restore_nocheck:
- testl $VM_MASK, EFLAGS(%esp)
- jnz resume_vm86
+ testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
+ jnz hypervisor_iret
movb EVENT_MASK(%esp), %al
notb %al # %al == ~saved_mask
XEN_GET_VCPU_INFO(%esi)
@@ -328,11 +330,11 @@
.long 1b,iret_exc
.previous
-resume_vm86:
- XEN_UNBLOCK_EVENTS(%esi)
+hypervisor_iret:
+ andl $~NMI_MASK, EFLAGS(%esp)
RESTORE_REGS
movl %eax,(%esp)
- movl $__HYPERVISOR_switch_vm86,%eax
+ movl $__HYPERVISOR_iret,%eax
int $0x82
ud2
@@ -691,6 +693,15 @@
call do_debug
jmp ret_from_exception
+ENTRY(nmi)
+ pushl %eax
+ SAVE_ALL
+ xorl %edx,%edx # zero error code
+ movl %esp,%eax # pt_regs pointer
+ call do_nmi
+ orl $NMI_MASK, EFLAGS(%esp)
+ jmp restore_all
+
#if 0 /* XEN */
/*
* NMI is doubly nasty. It can happen _while_ we're handling
diff -r 06ab200a9e23 -r 278e536ade72
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Wed Jan 11
15:52:33 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Wed Jan 11
15:52:54 2006
@@ -32,6 +32,7 @@
#include <asm-xen/xen-public/xen.h>
#include <asm-xen/xen-public/sched.h>
+#include <asm-xen/xen-public/nmi.h>
#define _hypercall0(type, name) \
({ \
@@ -300,6 +301,14 @@
SHUTDOWN_suspend, srec);
}
+static inline int
+HYPERVISOR_nmi_op(
+ unsigned long op,
+ unsigned long arg)
+{
+ return _hypercall2(int, nmi_op, op, arg);
+}
+
#endif /* __HYPERCALL_H__ */
/*
diff -r 06ab200a9e23 -r 278e536ade72
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
Wed Jan 11 15:52:33 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
Wed Jan 11 15:52:54 2006
@@ -29,6 +29,7 @@
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
+extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
@@ -36,5 +37,7 @@
__KERNEL_CS, (unsigned long)hypervisor_callback,
__KERNEL_CS, (unsigned long)failsafe_callback);
+ HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
}
diff -r 06ab200a9e23 -r 278e536ade72
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
--- /dev/null Wed Jan 11 15:52:33 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
Wed Jan 11 15:52:54 2006
@@ -0,0 +1,33 @@
+/*
+ * include/asm-xen/asm-i386/mach-xen/mach_traps.h
+ *
+ * Machine specific NMI handling for Xen
+ */
+#ifndef _MACH_TRAPS_H
+#define _MACH_TRAPS_H
+
+#include <linux/bitops.h>
+#include <asm-xen/xen-public/nmi.h>
+
+static inline void clear_mem_error(unsigned char reason) {}
+static inline void clear_io_check_error(unsigned char reason) {}
+
+static inline unsigned char get_nmi_reason(void)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ unsigned char reason = 0;
+
+ /* construct a value which looks like it came from
+ * port 0x61.
+ */
+ if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
+ reason |= 0x40;
+ if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
+ reason |= 0x80;
+
+ return reason;
+}
+
+static inline void reassert_nmi(void) {}
+
+#endif /* !_MACH_TRAPS_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|