277 lines
10 KiB
Diff
277 lines
10 KiB
Diff
Index: 2007-05-14/xen/arch/x86/physdev.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/physdev.c 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/physdev.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -143,6 +143,56 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
|
break;
|
|
}
|
|
|
|
+ case PHYSDEVOP_send_nmi: {
|
|
+ struct physdev_send_nmi send_nmi;
|
|
+ struct domain *d;
|
|
+
|
|
+ ret = -EFAULT;
|
|
+ if ( copy_from_guest(&send_nmi, arg, 1) != 0 )
|
|
+ break;
|
|
+
|
|
+ ret = -EPERM;
|
|
+ if ( send_nmi.domain == DOMID_SELF )
|
|
+ d = rcu_lock_current_domain();
|
|
+ else if ( IS_PRIV(current->domain) )
|
|
+ d = rcu_lock_domain_by_id(send_nmi.domain);
|
|
+ else
|
|
+ break;
|
|
+ ret = -ESRCH;
|
|
+ if ( d == NULL )
|
|
+ break;
|
|
+
|
|
+ switch ( send_nmi.vcpu )
|
|
+ {
|
|
+ struct vcpu *v;
|
|
+
|
|
+ case XEN_SEND_NMI_ALL:
|
|
+ case XEN_SEND_NMI_ALL_BUT_SELF:
|
|
+ for_each_vcpu(d, v)
|
|
+ {
|
|
+ if ( (send_nmi.vcpu == XEN_SEND_NMI_ALL || v != current) &&
|
|
+ !xchg(&v->nmi_pending, 1) )
|
|
+ vcpu_kick(v);
|
|
+ }
|
|
+ ret = 0;
|
|
+ break;
|
|
+ case 0 ... MAX_VIRT_CPUS - 1:
|
|
+ if ( (v = d->vcpu[send_nmi.vcpu]) != NULL )
|
|
+ {
|
|
+ if ( !xchg(&v->nmi_pending, 1) )
|
|
+ vcpu_kick(v);
|
|
+ ret = 0;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ ret = EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ rcu_unlock_domain(d);
|
|
+ break;
|
|
+ }
|
|
+
|
|
default:
|
|
ret = -ENOSYS;
|
|
break;
|
|
Index: 2007-05-14/xen/arch/x86/traps.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/traps.c 2007-05-14 14:40:03.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/traps.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -2517,6 +2517,12 @@ long do_set_trap_table(XEN_GUEST_HANDLE(
|
|
if ( cur.address == 0 )
|
|
break;
|
|
|
|
+ if ( cur.vector == 2 && !TI_GET_IF(&cur) )
|
|
+ {
|
|
+ rc = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
fixup_guest_code_selector(current->domain, cur.cs);
|
|
|
|
memcpy(&dst[cur.vector], &cur, sizeof(cur));
|
|
Index: 2007-05-14/xen/arch/x86/x86_32/asm-offsets.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_32/asm-offsets.c 2007-04-27 09:31:25.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_32/asm-offsets.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -68,6 +68,7 @@ void __dummy__(void)
|
|
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[2].cs);
|
|
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);
|
|
Index: 2007-05-14/xen/arch/x86/x86_32/entry.S
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_32/entry.S 2007-07-02 10:48:50.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_32/entry.S 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -263,14 +263,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 $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
|
|
+ movl %ecx,TRAPBOUNCE_eip(%edx)
|
|
+ movw %ax,TRAPBOUNCE_cs(%edx)
|
|
movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
|
|
call create_bounce_frame
|
|
jmp test_all_events
|
|
Index: 2007-05-14/xen/arch/x86/x86_64/asm-offsets.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-04-27 09:31:25.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_64/asm-offsets.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -77,6 +77,7 @@ void __dummy__(void)
|
|
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[2].cs);
|
|
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);
|
|
Index: 2007-05-14/xen/arch/x86/x86_64/compat/entry.S
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_64/compat/entry.S 2007-07-02 10:48:18.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_64/compat/entry.S 2007-07-02 11:56:42.000000000 +0200
|
|
@@ -119,14 +119,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 $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
|
|
+ movl %ecx,TRAPBOUNCE_eip(%rdx)
|
|
+ movw %ax,TRAPBOUNCE_cs(%rdx)
|
|
movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
|
|
call compat_create_bounce_frame
|
|
jmp compat_test_all_events
|
|
Index: 2007-05-14/xen/arch/x86/x86_64/compat/traps.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_64/compat/traps.c 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_64/compat/traps.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -288,6 +288,12 @@ int compat_set_trap_table(XEN_GUEST_HAND
|
|
if ( cur.address == 0 )
|
|
break;
|
|
|
|
+ if ( cur.vector == 2 && !TI_GET_IF(&cur) )
|
|
+ {
|
|
+ rc = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
fixup_guest_code_selector(current->domain, cur.cs);
|
|
|
|
XLAT_trap_info(dst + cur.vector, &cur);
|
|
Index: 2007-05-14/xen/arch/x86/x86_64/physdev.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/x86_64/physdev.c 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/x86_64/physdev.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -30,6 +30,10 @@
|
|
#define physdev_irq_status_query compat_physdev_irq_status_query
|
|
#define physdev_irq_status_query_t physdev_irq_status_query_compat_t
|
|
|
|
+#define xen_physdev_send_nmi physdev_send_nmi
|
|
+CHECK_physdev_send_nmi;
|
|
+#undef xen_physdev_send_nmi
|
|
+
|
|
#define COMPAT
|
|
#undef guest_handle_okay
|
|
#define guest_handle_okay compat_handle_okay
|
|
Index: 2007-05-14/xen/common/kernel.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/common/kernel.c 2007-05-14 14:33:33.000000000 +0200
|
|
+++ 2007-05-14/xen/common/kernel.c 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -246,16 +246,20 @@ long register_guest_nmi_callback(unsigne
|
|
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
|
|
+ v->arch.guest_context.trap_ctxt[2].vector = 2;
|
|
+ v->arch.guest_context.trap_ctxt[2].flags = 0;
|
|
+ TI_SET_IF(v->arch.guest_context.trap_ctxt + 2, 1);
|
|
+ v->arch.guest_context.trap_ctxt[2].cs =
|
|
+ !is_pv_32on64_domain(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS;
|
|
+
|
|
/*
|
|
* If no handler was registered we can 'lose the NMI edge'. Re-assert it
|
|
* now.
|
|
*/
|
|
- if ( arch_get_nmi_reason(d) != 0 )
|
|
+ if ( d->domain_id == 0 && v->vcpu_id == 0 &&
|
|
+ arch_get_nmi_reason(d) != 0 )
|
|
v->nmi_pending = 1;
|
|
#endif
|
|
|
|
@@ -266,6 +270,11 @@ long unregister_guest_nmi_callback(void)
|
|
{
|
|
struct vcpu *v = current;
|
|
|
|
+#ifdef CONFIG_X86
|
|
+ v->arch.guest_context.trap_ctxt[2].cs = 0;
|
|
+ v->arch.guest_context.trap_ctxt[2].vector = 0;
|
|
+ v->arch.guest_context.trap_ctxt[2].flags = 0;
|
|
+#endif
|
|
v->nmi_addr = 0;
|
|
|
|
return 0;
|
|
Index: 2007-05-14/xen/include/public/physdev.h
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/include/public/physdev.h 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/include/public/physdev.h 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -119,6 +119,22 @@ typedef struct physdev_irq physdev_irq_t
|
|
DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
|
|
|
|
/*
|
|
+ * Allocate or free a physical upcall vector for the specified IRQ line.
|
|
+ * @arg == pointer to physdev_irq structure.
|
|
+ */
|
|
+#define PHYSDEVOP_send_nmi 13
|
|
+struct physdev_send_nmi {
|
|
+ /* IN */
|
|
+ domid_t domain;
|
|
+ uint32_t vcpu;
|
|
+};
|
|
+typedef struct physdev_send_nmi physdev_send_nmi_t;
|
|
+DEFINE_XEN_GUEST_HANDLE(physdev_send_nmi_t);
|
|
+
|
|
+#define XEN_SEND_NMI_ALL (~(uint32_t)0)
|
|
+#define XEN_SEND_NMI_ALL_BUT_SELF (~(uint32_t)1)
|
|
+
|
|
+/*
|
|
* Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
|
|
* hypercall since 0x00030202.
|
|
*/
|
|
Index: 2007-05-14/xen/include/xen/sched.h
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/include/xen/sched.h 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/include/xen/sched.h 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -128,7 +128,11 @@ struct vcpu
|
|
/* Bitmask of CPUs on which this VCPU may run. */
|
|
cpumask_t cpu_affinity;
|
|
|
|
+#ifndef CONFIG_X86
|
|
unsigned long nmi_addr; /* NMI callback address. */
|
|
+#else
|
|
+# define nmi_addr arch.guest_context.trap_ctxt[2].address
|
|
+#endif
|
|
|
|
/* Bitmask of CPUs which are holding onto this VCPU's state. */
|
|
cpumask_t vcpu_dirty_cpumask;
|
|
Index: 2007-05-14/xen/include/xlat.lst
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/include/xlat.lst 2007-07-02 10:37:50.000000000 +0200
|
|
+++ 2007-05-14/xen/include/xlat.lst 2007-05-14 14:40:35.000000000 +0200
|
|
@@ -35,6 +35,7 @@
|
|
! memory_map memory.h
|
|
! memory_reservation memory.h
|
|
! translate_gpfn_list memory.h
|
|
+? physdev_send_nmi physdev.h
|
|
! sched_poll sched.h
|
|
? sched_remote_shutdown sched.h
|
|
? sched_shutdown sched.h
|