ia64/xen-unstable

changeset 8562:278e536ade72

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@XenSource.com>
author Ian.Campbell@xensource.com
date Wed Jan 11 15:52:54 2006 +0000 (2006-01-11)
parents 06ab200a9e23
children 0ffd94a02318
files linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Wed Jan 11 15:52:33 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Wed Jan 11 15:52:54 2006 +0000
     1.3 @@ -76,7 +76,9 @@ IF_MASK		= 0x00000200
     1.4  DF_MASK		= 0x00000400 
     1.5  NT_MASK		= 0x00004000
     1.6  VM_MASK		= 0x00020000
     1.7 -
     1.8 +/* pseudo-eflags */
     1.9 +NMI_MASK	= 0x80000000
    1.10 +	
    1.11  /* Offsets into shared_info_t. */
    1.12  #define evtchn_upcall_pending		/* 0 */
    1.13  #define evtchn_upcall_mask		1
    1.14 @@ -305,8 +307,8 @@ restore_all:
    1.15  	je ldt_ss			# returning to user-space with LDT SS
    1.16  #endif /* XEN */
    1.17  restore_nocheck:
    1.18 -	testl $VM_MASK, EFLAGS(%esp)
    1.19 -	jnz resume_vm86
    1.20 +	testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
    1.21 +	jnz hypervisor_iret
    1.22  	movb EVENT_MASK(%esp), %al
    1.23  	notb %al			# %al == ~saved_mask
    1.24  	XEN_GET_VCPU_INFO(%esi)
    1.25 @@ -328,11 +330,11 @@ iret_exc:
    1.26  	.long 1b,iret_exc
    1.27  .previous
    1.28  
    1.29 -resume_vm86:
    1.30 -	XEN_UNBLOCK_EVENTS(%esi)
    1.31 +hypervisor_iret:
    1.32 +	andl $~NMI_MASK, EFLAGS(%esp)
    1.33  	RESTORE_REGS
    1.34  	movl %eax,(%esp)
    1.35 -	movl $__HYPERVISOR_switch_vm86,%eax
    1.36 +	movl $__HYPERVISOR_iret,%eax
    1.37  	int $0x82
    1.38  	ud2
    1.39  
    1.40 @@ -691,6 +693,15 @@ debug_stack_correct:
    1.41  	call do_debug
    1.42  	jmp ret_from_exception
    1.43  
    1.44 +ENTRY(nmi)
    1.45 +	pushl %eax
    1.46 +	SAVE_ALL
    1.47 +	xorl %edx,%edx		# zero error code
    1.48 +	movl %esp,%eax		# pt_regs pointer
    1.49 +	call do_nmi
    1.50 +	orl  $NMI_MASK, EFLAGS(%esp)
    1.51 +	jmp restore_all
    1.52 +
    1.53  #if 0 /* XEN */
    1.54  /*
    1.55   * NMI is doubly nasty. It can happen _while_ we're handling
     2.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Wed Jan 11 15:52:33 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Wed Jan 11 15:52:54 2006 +0000
     2.3 @@ -32,6 +32,7 @@
     2.4  
     2.5  #include <asm-xen/xen-public/xen.h>
     2.6  #include <asm-xen/xen-public/sched.h>
     2.7 +#include <asm-xen/xen-public/nmi.h>
     2.8  
     2.9  #define _hypercall0(type, name)			\
    2.10  ({						\
    2.11 @@ -300,6 +301,14 @@ HYPERVISOR_suspend(
    2.12  			   SHUTDOWN_suspend, srec);
    2.13  }
    2.14  
    2.15 +static inline int
    2.16 +HYPERVISOR_nmi_op(
    2.17 +	unsigned long op,
    2.18 +	unsigned long arg)
    2.19 +{
    2.20 +	return _hypercall2(int, nmi_op, op, arg);
    2.21 +}
    2.22 +
    2.23  #endif /* __HYPERCALL_H__ */
    2.24  
    2.25  /*
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h	Wed Jan 11 15:52:54 2006 +0000
     3.3 @@ -0,0 +1,33 @@
     3.4 +/*
     3.5 + *  include/asm-xen/asm-i386/mach-xen/mach_traps.h
     3.6 + *
     3.7 + *  Machine specific NMI handling for Xen
     3.8 + */
     3.9 +#ifndef _MACH_TRAPS_H
    3.10 +#define _MACH_TRAPS_H
    3.11 +
    3.12 +#include <linux/bitops.h>
    3.13 +#include <asm-xen/xen-public/nmi.h>
    3.14 +
    3.15 +static inline void clear_mem_error(unsigned char reason) {}
    3.16 +static inline void clear_io_check_error(unsigned char reason) {}
    3.17 +
    3.18 +static inline unsigned char get_nmi_reason(void)
    3.19 +{
    3.20 +	shared_info_t *s = HYPERVISOR_shared_info;
    3.21 +	unsigned char reason = 0;
    3.22 +
    3.23 +	/* construct a value which looks like it came from
    3.24 +	 * port 0x61.
    3.25 +	 */
    3.26 +	if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
    3.27 +		reason |= 0x40;
    3.28 +	if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
    3.29 +		reason |= 0x80;
    3.30 +
    3.31 +        return reason;
    3.32 +}
    3.33 +
    3.34 +static inline void reassert_nmi(void) {}
    3.35 +
    3.36 +#endif /* !_MACH_TRAPS_H */
     4.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h	Wed Jan 11 15:52:33 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h	Wed Jan 11 15:52:54 2006 +0000
     4.3 @@ -29,6 +29,7 @@ void __init machine_specific_modify_cpu_
     4.4  
     4.5  extern void hypervisor_callback(void);
     4.6  extern void failsafe_callback(void);
     4.7 +extern void nmi(void);
     4.8  
     4.9  static void __init machine_specific_arch_setup(void)
    4.10  {
    4.11 @@ -36,5 +37,7 @@ static void __init machine_specific_arch
    4.12  	    __KERNEL_CS, (unsigned long)hypervisor_callback,
    4.13  	    __KERNEL_CS, (unsigned long)failsafe_callback);
    4.14  
    4.15 +	HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
    4.16 +
    4.17  	machine_specific_modify_cpu_capabilities(&boot_cpu_data);
    4.18  }