[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Allow NMI callback CS to be specified via set_trap_table()
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1193054672 -3600 # Node ID 42d8dadb5864eac0140262b9475a7b1ed150b607 # Parent 183a2d6eaadf5a24e231de4b473d0ff683ebd2c2 x86: Allow NMI callback CS to be specified via set_trap_table() hypercall. Based on a patch by Jan Beulich. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/traps.c | 37 ++++++++++++++++++++++++++++++ xen/arch/x86/x86_32/asm-offsets.c | 5 +++- xen/arch/x86/x86_32/entry.S | 6 +++- xen/arch/x86/x86_64/asm-offsets.c | 5 +++- xen/arch/x86/x86_64/compat/entry.S | 6 +++- xen/arch/x86/x86_64/compat/traps.c | 6 ++++ xen/common/kernel.c | 34 --------------------------- xen/include/asm-ia64/linux-null/asm/nmi.h | 8 +++++- xen/include/asm-powerpc/nmi.h | 3 ++ xen/include/asm-x86/nmi.h | 15 ++++++++++++ xen/include/xen/nmi.h | 15 ------------ xen/include/xen/sched.h | 2 - 12 files changed, 84 insertions(+), 58 deletions(-) diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/traps.c Mon Oct 22 13:04:32 2007 +0100 @@ -2229,6 +2229,37 @@ void __init trap_init(void) open_softirq(NMI_SOFTIRQ, nmi_softirq); } +long register_guest_nmi_callback(unsigned long address) +{ + struct vcpu *v = current; + struct domain *d = current->domain; + struct trap_info *t = &v->arch.guest_context.trap_ctxt[TRAP_nmi]; + + t->vector = TRAP_nmi; + t->flags = 0; + t->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; + t->address = address; + TI_SET_IF(t, 1); + + /* + * If no handler was registered we can 'lose the NMI edge'. Re-assert it + * now. + */ + if ( (v->vcpu_id == 0) && (arch_get_nmi_reason(d) != 0) ) + v->nmi_pending = 1; + + return 0; +} + +long unregister_guest_nmi_callback(void) +{ + struct vcpu *v = current; + struct trap_info *t = &v->arch.guest_context.trap_ctxt[TRAP_nmi]; + + memset(t, 0, sizeof(*t)); + + return 0; +} long do_set_trap_table(XEN_GUEST_HANDLE(trap_info_t) traps) { @@ -2261,6 +2292,12 @@ long do_set_trap_table(XEN_GUEST_HANDLE( if ( cur.address == 0 ) break; + + if ( (cur.vector == TRAP_nmi) && !TI_GET_IF(&cur) ) + { + rc = -EINVAL; + break; + } fixup_guest_code_selector(current->domain, cur.cs); diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_32/asm-offsets.c --- a/xen/arch/x86/x86_32/asm-offsets.c Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/x86_32/asm-offsets.c Mon Oct 22 13:04:32 2007 +0100 @@ -66,7 +66,10 @@ void __dummy__(void) arch.guest_context.kernel_sp); OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags); OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); - OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr); + OFFSET(VCPU_nmi_cs, struct vcpu, + arch.guest_context.trap_ctxt[TRAP_nmi].cs); + OFFSET(VCPU_nmi_addr, struct vcpu, + arch.guest_context.trap_ctxt[TRAP_nmi].address); OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending); OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked); DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events); diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/x86_32/entry.S Mon Oct 22 13:04:32 2007 +0100 @@ -257,13 +257,15 @@ process_nmi: testb $1,VCPU_nmi_masked(%ebx) jnz test_guest_events movb $0,VCPU_nmi_pending(%ebx) - movl VCPU_nmi_addr(%ebx),%eax + movzwl VCPU_nmi_cs(%ebx),%eax + movl VCPU_nmi_addr(%ebx),%ecx test %eax,%eax jz test_guest_events movb $1,VCPU_nmi_masked(%ebx) sti leal VCPU_trap_bounce(%ebx),%edx - movl %eax,TRAPBOUNCE_eip(%edx) + movw %ax,TRAPBOUNCE_cs(%edx) + movl %ecx,TRAPBOUNCE_eip(%edx) movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx) movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx) call create_bounce_frame diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/asm-offsets.c --- a/xen/arch/x86/x86_64/asm-offsets.c Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/x86_64/asm-offsets.c Mon Oct 22 13:04:32 2007 +0100 @@ -75,7 +75,10 @@ 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_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); - OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr); + OFFSET(VCPU_nmi_cs, struct vcpu, + arch.guest_context.trap_ctxt[TRAP_nmi].cs); + OFFSET(VCPU_nmi_addr, struct vcpu, + arch.guest_context.trap_ctxt[TRAP_nmi].address); OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending); OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked); DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events); diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/compat/entry.S --- a/xen/arch/x86/x86_64/compat/entry.S Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/x86_64/compat/entry.S Mon Oct 22 13:04:32 2007 +0100 @@ -131,13 +131,15 @@ compat_process_nmi: testb $1,VCPU_nmi_masked(%rbx) jnz compat_test_guest_events movb $0,VCPU_nmi_pending(%rbx) - movl VCPU_nmi_addr(%rbx),%eax + movzwl VCPU_nmi_cs(%rbx),%eax + movl VCPU_nmi_addr(%rbx),%ecx testl %eax,%eax jz compat_test_guest_events movb $1,VCPU_nmi_masked(%rbx) sti leaq VCPU_trap_bounce(%rbx),%rdx - movl %eax,TRAPBOUNCE_eip(%rdx) + movw %ax,TRAPBOUNCE_cs(%rdx) + movl %ecx,TRAPBOUNCE_eip(%rdx) movw $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call compat_create_bounce_frame diff -r 183a2d6eaadf -r 42d8dadb5864 xen/arch/x86/x86_64/compat/traps.c --- a/xen/arch/x86/x86_64/compat/traps.c Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/arch/x86/x86_64/compat/traps.c Mon Oct 22 13:04:32 2007 +0100 @@ -294,6 +294,12 @@ int compat_set_trap_table(XEN_GUEST_HAND if ( cur.address == 0 ) break; + if ( (cur.vector == TRAP_nmi) && !TI_GET_IF(&cur) ) + { + rc = -EINVAL; + break; + } + fixup_guest_code_selector(current->domain, cur.cs); XLAT_trap_info(dst + cur.vector, &cur); diff -r 183a2d6eaadf -r 42d8dadb5864 xen/common/kernel.c --- a/xen/common/kernel.c Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/common/kernel.c Mon Oct 22 13:04:32 2007 +0100 @@ -247,40 +247,6 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL return -ENOSYS; } -#ifndef COMPAT - -long register_guest_nmi_callback(unsigned long address) -{ - struct vcpu *v = current; - struct domain *d = current->domain; - - if ( (d->domain_id != 0) || (v->vcpu_id != 0) ) - return -EINVAL; - - v->nmi_addr = address; -#ifdef CONFIG_X86 - /* - * If no handler was registered we can 'lose the NMI edge'. Re-assert it - * now. - */ - if ( arch_get_nmi_reason(d) != 0 ) - v->nmi_pending = 1; -#endif - - return 0; -} - -long unregister_guest_nmi_callback(void) -{ - struct vcpu *v = current; - - v->nmi_addr = 0; - - return 0; -} - -#endif - DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) { struct xennmi_callback cb; diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-ia64/linux-null/asm/nmi.h --- a/xen/include/asm-ia64/linux-null/asm/nmi.h Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/include/asm-ia64/linux-null/asm/nmi.h Mon Oct 22 13:04:32 2007 +0100 @@ -1,1 +1,7 @@ -/* This file is intentionally left empty. */ +#ifndef __IA64_NMI_H__ +#define __IA64_NMI_H__ + +#define register_guest_nmi_callback(a) (-ENOSYS) +#define unregister_guest_nmi_callback() (-ENOSYS) + +#endif /* __IA64_NMI_H__ */ diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-powerpc/nmi.h --- a/xen/include/asm-powerpc/nmi.h Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/include/asm-powerpc/nmi.h Mon Oct 22 13:04:32 2007 +0100 @@ -3,4 +3,7 @@ #include <public/nmi.h> +#define register_guest_nmi_callback(a) (-ENOSYS) +#define unregister_guest_nmi_callback() (-ENOSYS) + #endif /* ASM_NMI_H */ diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/asm-x86/nmi.h --- a/xen/include/asm-x86/nmi.h Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/include/asm-x86/nmi.h Mon Oct 22 13:04:32 2007 +0100 @@ -23,4 +23,19 @@ void set_nmi_callback(nmi_callback_t cal */ void unset_nmi_callback(void); +/** + * register_guest_nmi_callback + * + * The default NMI handler passes the NMI to a guest callback. This + * function registers the address of that callback. + */ +long register_guest_nmi_callback(unsigned long address); + +/** + * unregister_guest_nmi_callback + * + * Unregister a guest NMI handler. + */ +long unregister_guest_nmi_callback(void); + #endif /* ASM_NMI_H */ diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/xen/nmi.h --- a/xen/include/xen/nmi.h Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/include/xen/nmi.h Mon Oct 22 13:04:32 2007 +0100 @@ -11,19 +11,4 @@ #include <asm/nmi.h> -/** - * register_guest_nmi_callback - * - * The default NMI handler passes the NMI to a guest callback. This - * function registers the address of that callback. - */ -extern long register_guest_nmi_callback(unsigned long address); - -/** - * unregister_guest_nmi_callback - * - * Unregister a guest NMI handler. - */ -extern long unregister_guest_nmi_callback(void); - #endif /* __XEN_NMI_H__ */ diff -r 183a2d6eaadf -r 42d8dadb5864 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Mon Oct 22 11:11:04 2007 +0100 +++ b/xen/include/xen/sched.h Mon Oct 22 13:04:32 2007 +0100 @@ -131,8 +131,6 @@ struct vcpu /* Bitmask of CPUs on which this VCPU may run. */ cpumask_t cpu_affinity; - unsigned long nmi_addr; /* NMI callback address. */ - /* Bitmask of CPUs which are holding onto this VCPU's state. */ cpumask_t vcpu_dirty_cpumask; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |