# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID faad84c126e26a5db34469a29e02fa1ae925a268
# Parent 3bac94fc40756d405cc9adb7fda4e7c0bff8ccdf
Merge nmi_op functionality with the callback_op hypercall.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
diff -r 3bac94fc4075 -r faad84c126e2
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Apr
21 17:19:19 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Apr
21 17:19:22 2006 +0100
@@ -34,7 +34,10 @@ static void __init machine_specific_arch
.type = CALLBACKTYPE_failsafe,
.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
};
- struct xennmi_callback cb;
+ struct callback_register nmi_cb = {
+ .type = CALLBACKTYPE_nmi,
+ .address = { __KERNEL_CS, (unsigned long)nmi },
+ };
if (xen_feature(XENFEAT_auto_translated_physmap) &&
xen_start_info->shared_info < xen_start_info->nr_pages) {
@@ -52,8 +55,14 @@ static void __init machine_specific_arch
failsafe.address.cs, failsafe.address.eip);
BUG_ON(ret);
- cb.handler_address = (unsigned long)&nmi;
- HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
+ ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+ if (ret == -ENOSYS) {
+ struct xennmi_callback cb;
+
+ cb.handler_address = nmi_cb.address.eip;
+ ret = HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
+ }
+ BUG_ON(ret);
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
diff -r 3bac94fc4075 -r faad84c126e2
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Fri Apr 21 17:19:19 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Fri Apr 21 17:19:22 2006 +0100
@@ -28,7 +28,10 @@ static void __init machine_specific_arch
.address = (unsigned long)system_call,
};
#ifdef CONFIG_X86_LOCAL_APIC
- struct xennmi_callback cb;
+ struct callback_register nmi_cb = {
+ .type = CALLBACKTYPE_nmi,
+ .address = (unsigned long)nmi,
+ };
#endif
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
@@ -44,7 +47,13 @@ static void __init machine_specific_arch
BUG_ON(ret);
#ifdef CONFIG_X86_LOCAL_APIC
- cb.handler_address = (unsigned long)&nmi;
- HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
+ ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+ if (ret == -ENOSYS) {
+ struct xennmi_callback cb;
+
+ cb.handler_address = nmi_cb.address;
+ ret = HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
+ }
+ BUG_ON(ret);
#endif
}
diff -r 3bac94fc4075 -r faad84c126e2 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:19 2006 +0100
+++ b/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:22 2006 +0100
@@ -10,6 +10,7 @@
#include <xen/irq.h>
#include <xen/symbols.h>
#include <xen/reboot.h>
+#include <xen/nmi.h>
#include <asm/current.h>
#include <asm/flushtlb.h>
#include <asm/hvm/hvm.h>
@@ -336,6 +337,10 @@ static long register_guest_callback(stru
v->arch.guest_context.failsafe_callback_eip = reg->address.eip;
break;
+ case CALLBACKTYPE_nmi:
+ ret = register_guest_nmi_callback(reg->address.eip);
+ break;
+
default:
ret = -EINVAL;
break;
@@ -350,6 +355,10 @@ static long unregister_guest_callback(st
switch ( unreg->type )
{
+ case CALLBACKTYPE_nmi:
+ ret = unregister_guest_nmi_callback();
+ break;
+
default:
ret = -EINVAL;
break;
diff -r 3bac94fc4075 -r faad84c126e2 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Fri Apr 21 17:19:19 2006 +0100
+++ b/xen/arch/x86/x86_64/traps.c Fri Apr 21 17:19:22 2006 +0100
@@ -11,6 +11,7 @@
#include <xen/console.h>
#include <xen/sched.h>
#include <xen/reboot.h>
+#include <xen/nmi.h>
#include <asm/current.h>
#include <asm/flushtlb.h>
#include <asm/msr.h>
@@ -339,6 +340,10 @@ static long register_guest_callback(stru
v->arch.guest_context.syscall_callback_eip = reg->address;
break;
+ case CALLBACKTYPE_nmi:
+ ret = register_guest_nmi_callback(reg->address);
+ break;
+
default:
ret = -EINVAL;
break;
@@ -353,6 +358,10 @@ static long unregister_guest_callback(st
switch ( unreg->type )
{
+ case CALLBACKTYPE_nmi:
+ ret = unregister_guest_nmi_callback();
+ break;
+
default:
ret = -EINVAL;
break;
diff -r 3bac94fc4075 -r faad84c126e2 xen/common/kernel.c
--- a/xen/common/kernel.c Fri Apr 21 17:19:19 2006 +0100
+++ b/xen/common/kernel.c Fri Apr 21 17:19:22 2006 +0100
@@ -213,37 +213,51 @@ long do_xen_version(int cmd, GUEST_HANDL
return -ENOSYS;
}
-long do_nmi_op(unsigned int cmd, GUEST_HANDLE(void) arg)
+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 ( d->shared_info->arch.nmi_reason != 0 )
+ set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
+#endif
+
+ return 0;
+}
+
+long unregister_guest_nmi_callback(void)
+{
+ struct vcpu *v = current;
+
+ v->nmi_addr = 0;
+
+ return 0;
+}
+
+long do_nmi_op(unsigned int cmd, GUEST_HANDLE(void) arg)
+{
struct xennmi_callback cb;
long rc = 0;
switch ( cmd )
{
case XENNMI_register_callback:
- rc = -EINVAL;
- if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
- break;
-
rc = -EFAULT;
if ( copy_from_guest(&cb, arg, 1) )
break;
-
- v->nmi_addr = cb.handler_address;
-#ifdef CONFIG_X86
- /*
- * If no handler was registered we can 'lose the NMI edge'. Re-assert
- * it now.
- */
- if ( d->shared_info->arch.nmi_reason != 0 )
- set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
-#endif
- rc = 0;
+ rc = register_guest_nmi_callback(cb.handler_address);
break;
case XENNMI_unregister_callback:
- v->nmi_addr = 0;
+ rc = unregister_guest_nmi_callback();
break;
default:
rc = -ENOSYS;
diff -r 3bac94fc4075 -r faad84c126e2 xen/include/public/callback.h
--- a/xen/include/public/callback.h Fri Apr 21 17:19:19 2006 +0100
+++ b/xen/include/public/callback.h Fri Apr 21 17:19:22 2006 +0100
@@ -21,6 +21,7 @@
#define CALLBACKTYPE_event 0
#define CALLBACKTYPE_failsafe 1
#define CALLBACKTYPE_syscall 2 /* x86_64 only */
+#define CALLBACKTYPE_nmi 4
/*
* Register a callback.
diff -r 3bac94fc4075 -r faad84c126e2 xen/include/xen/nmi.h
--- a/xen/include/xen/nmi.h Fri Apr 21 17:19:19 2006 +0100
+++ b/xen/include/xen/nmi.h Fri Apr 21 17:19:22 2006 +0100
@@ -11,4 +11,19 @@
#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__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|