ia64/xen-unstable
changeset 9814:faad84c126e2
Merge nmi_op functionality with the callback_op hypercall.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian.Campbell@xensource.com |
---|---|
date | Fri Apr 21 17:19:22 2006 +0100 (2006-04-21) |
parents | 3bac94fc4075 |
children | d73eeceeae69 |
files | linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/traps.c xen/common/kernel.c xen/include/public/callback.h xen/include/xen/nmi.h |
line diff
1.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Apr 21 17:19:19 2006 +0100 1.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Apr 21 17:19:22 2006 +0100 1.3 @@ -34,7 +34,10 @@ static void __init machine_specific_arch 1.4 .type = CALLBACKTYPE_failsafe, 1.5 .address = { __KERNEL_CS, (unsigned long)failsafe_callback }, 1.6 }; 1.7 - struct xennmi_callback cb; 1.8 + struct callback_register nmi_cb = { 1.9 + .type = CALLBACKTYPE_nmi, 1.10 + .address = { __KERNEL_CS, (unsigned long)nmi }, 1.11 + }; 1.12 1.13 if (xen_feature(XENFEAT_auto_translated_physmap) && 1.14 xen_start_info->shared_info < xen_start_info->nr_pages) { 1.15 @@ -52,8 +55,14 @@ static void __init machine_specific_arch 1.16 failsafe.address.cs, failsafe.address.eip); 1.17 BUG_ON(ret); 1.18 1.19 - cb.handler_address = (unsigned long)&nmi; 1.20 - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); 1.21 + ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); 1.22 + if (ret == -ENOSYS) { 1.23 + struct xennmi_callback cb; 1.24 + 1.25 + cb.handler_address = nmi_cb.address.eip; 1.26 + ret = HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); 1.27 + } 1.28 + BUG_ON(ret); 1.29 1.30 if (HYPERVISOR_xen_version(XENVER_platform_parameters, 1.31 &pp) == 0)
2.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Fri Apr 21 17:19:19 2006 +0100 2.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Fri Apr 21 17:19:22 2006 +0100 2.3 @@ -28,7 +28,10 @@ static void __init machine_specific_arch 2.4 .address = (unsigned long)system_call, 2.5 }; 2.6 #ifdef CONFIG_X86_LOCAL_APIC 2.7 - struct xennmi_callback cb; 2.8 + struct callback_register nmi_cb = { 2.9 + .type = CALLBACKTYPE_nmi, 2.10 + .address = (unsigned long)nmi, 2.11 + }; 2.12 #endif 2.13 2.14 ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event); 2.15 @@ -44,7 +47,13 @@ static void __init machine_specific_arch 2.16 BUG_ON(ret); 2.17 2.18 #ifdef CONFIG_X86_LOCAL_APIC 2.19 - cb.handler_address = (unsigned long)&nmi; 2.20 - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); 2.21 + ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); 2.22 + if (ret == -ENOSYS) { 2.23 + struct xennmi_callback cb; 2.24 + 2.25 + cb.handler_address = nmi_cb.address; 2.26 + ret = HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); 2.27 + } 2.28 + BUG_ON(ret); 2.29 #endif 2.30 }
3.1 --- a/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:19 2006 +0100 3.2 +++ b/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:22 2006 +0100 3.3 @@ -10,6 +10,7 @@ 3.4 #include <xen/irq.h> 3.5 #include <xen/symbols.h> 3.6 #include <xen/reboot.h> 3.7 +#include <xen/nmi.h> 3.8 #include <asm/current.h> 3.9 #include <asm/flushtlb.h> 3.10 #include <asm/hvm/hvm.h> 3.11 @@ -336,6 +337,10 @@ static long register_guest_callback(stru 3.12 v->arch.guest_context.failsafe_callback_eip = reg->address.eip; 3.13 break; 3.14 3.15 + case CALLBACKTYPE_nmi: 3.16 + ret = register_guest_nmi_callback(reg->address.eip); 3.17 + break; 3.18 + 3.19 default: 3.20 ret = -EINVAL; 3.21 break; 3.22 @@ -350,6 +355,10 @@ static long unregister_guest_callback(st 3.23 3.24 switch ( unreg->type ) 3.25 { 3.26 + case CALLBACKTYPE_nmi: 3.27 + ret = unregister_guest_nmi_callback(); 3.28 + break; 3.29 + 3.30 default: 3.31 ret = -EINVAL; 3.32 break;
4.1 --- a/xen/arch/x86/x86_64/traps.c Fri Apr 21 17:19:19 2006 +0100 4.2 +++ b/xen/arch/x86/x86_64/traps.c Fri Apr 21 17:19:22 2006 +0100 4.3 @@ -11,6 +11,7 @@ 4.4 #include <xen/console.h> 4.5 #include <xen/sched.h> 4.6 #include <xen/reboot.h> 4.7 +#include <xen/nmi.h> 4.8 #include <asm/current.h> 4.9 #include <asm/flushtlb.h> 4.10 #include <asm/msr.h> 4.11 @@ -339,6 +340,10 @@ static long register_guest_callback(stru 4.12 v->arch.guest_context.syscall_callback_eip = reg->address; 4.13 break; 4.14 4.15 + case CALLBACKTYPE_nmi: 4.16 + ret = register_guest_nmi_callback(reg->address); 4.17 + break; 4.18 + 4.19 default: 4.20 ret = -EINVAL; 4.21 break; 4.22 @@ -353,6 +358,10 @@ static long unregister_guest_callback(st 4.23 4.24 switch ( unreg->type ) 4.25 { 4.26 + case CALLBACKTYPE_nmi: 4.27 + ret = unregister_guest_nmi_callback(); 4.28 + break; 4.29 + 4.30 default: 4.31 ret = -EINVAL; 4.32 break;
5.1 --- a/xen/common/kernel.c Fri Apr 21 17:19:19 2006 +0100 5.2 +++ b/xen/common/kernel.c Fri Apr 21 17:19:22 2006 +0100 5.3 @@ -213,37 +213,51 @@ long do_xen_version(int cmd, GUEST_HANDL 5.4 return -ENOSYS; 5.5 } 5.6 5.7 -long do_nmi_op(unsigned int cmd, GUEST_HANDLE(void) arg) 5.8 +long register_guest_nmi_callback(unsigned long address) 5.9 { 5.10 struct vcpu *v = current; 5.11 struct domain *d = current->domain; 5.12 + 5.13 + if ( (d->domain_id != 0) || (v->vcpu_id != 0) ) 5.14 + return -EINVAL; 5.15 + 5.16 + v->nmi_addr = address; 5.17 +#ifdef CONFIG_X86 5.18 + /* 5.19 + * If no handler was registered we can 'lose the NMI edge'. Re-assert it 5.20 + * now. 5.21 + */ 5.22 + if ( d->shared_info->arch.nmi_reason != 0 ) 5.23 + set_bit(_VCPUF_nmi_pending, &v->vcpu_flags); 5.24 +#endif 5.25 + 5.26 + return 0; 5.27 +} 5.28 + 5.29 +long unregister_guest_nmi_callback(void) 5.30 +{ 5.31 + struct vcpu *v = current; 5.32 + 5.33 + v->nmi_addr = 0; 5.34 + 5.35 + return 0; 5.36 +} 5.37 + 5.38 +long do_nmi_op(unsigned int cmd, GUEST_HANDLE(void) arg) 5.39 +{ 5.40 struct xennmi_callback cb; 5.41 long rc = 0; 5.42 5.43 switch ( cmd ) 5.44 { 5.45 case XENNMI_register_callback: 5.46 - rc = -EINVAL; 5.47 - if ( (d->domain_id != 0) || (v->vcpu_id != 0) ) 5.48 - break; 5.49 - 5.50 rc = -EFAULT; 5.51 if ( copy_from_guest(&cb, arg, 1) ) 5.52 break; 5.53 - 5.54 - v->nmi_addr = cb.handler_address; 5.55 -#ifdef CONFIG_X86 5.56 - /* 5.57 - * If no handler was registered we can 'lose the NMI edge'. Re-assert 5.58 - * it now. 5.59 - */ 5.60 - if ( d->shared_info->arch.nmi_reason != 0 ) 5.61 - set_bit(_VCPUF_nmi_pending, &v->vcpu_flags); 5.62 -#endif 5.63 - rc = 0; 5.64 + rc = register_guest_nmi_callback(cb.handler_address); 5.65 break; 5.66 case XENNMI_unregister_callback: 5.67 - v->nmi_addr = 0; 5.68 + rc = unregister_guest_nmi_callback(); 5.69 break; 5.70 default: 5.71 rc = -ENOSYS;
6.1 --- a/xen/include/public/callback.h Fri Apr 21 17:19:19 2006 +0100 6.2 +++ b/xen/include/public/callback.h Fri Apr 21 17:19:22 2006 +0100 6.3 @@ -21,6 +21,7 @@ 6.4 #define CALLBACKTYPE_event 0 6.5 #define CALLBACKTYPE_failsafe 1 6.6 #define CALLBACKTYPE_syscall 2 /* x86_64 only */ 6.7 +#define CALLBACKTYPE_nmi 4 6.8 6.9 /* 6.10 * Register a callback.
7.1 --- a/xen/include/xen/nmi.h Fri Apr 21 17:19:19 2006 +0100 7.2 +++ b/xen/include/xen/nmi.h Fri Apr 21 17:19:22 2006 +0100 7.3 @@ -11,4 +11,19 @@ 7.4 7.5 #include <asm/nmi.h> 7.6 7.7 +/** 7.8 + * register_guest_nmi_callback 7.9 + * 7.10 + * The default NMI handler passes the NMI to a guest callback. This 7.11 + * function registers the address of that callback. 7.12 + */ 7.13 +extern long register_guest_nmi_callback(unsigned long address); 7.14 + 7.15 +/** 7.16 + * unregister_guest_nmi_callback 7.17 + * 7.18 + * Unregister a guest NMI handler. 7.19 + */ 7.20 +extern long unregister_guest_nmi_callback(void); 7.21 + 7.22 #endif /* __XEN_NMI_H__ */