diff options
-rw-r--r-- | arch/x86/include/asm/xen/events.h | 1 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 13 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 13 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 6 | ||||
-rw-r--r-- | drivers/xen/events.c | 11 | ||||
-rw-r--r-- | include/xen/interface/vcpu.h | 2 |
6 files changed, 38 insertions, 8 deletions
diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h index ca842f2769ef..608a79d5a466 100644 --- a/arch/x86/include/asm/xen/events.h +++ b/arch/x86/include/asm/xen/events.h | |||
@@ -7,6 +7,7 @@ enum ipi_vector { | |||
7 | XEN_CALL_FUNCTION_SINGLE_VECTOR, | 7 | XEN_CALL_FUNCTION_SINGLE_VECTOR, |
8 | XEN_SPIN_UNLOCK_VECTOR, | 8 | XEN_SPIN_UNLOCK_VECTOR, |
9 | XEN_IRQ_WORK_VECTOR, | 9 | XEN_IRQ_WORK_VECTOR, |
10 | XEN_NMI_VECTOR, | ||
10 | 11 | ||
11 | XEN_NR_IPIS, | 12 | XEN_NR_IPIS, |
12 | }; | 13 | }; |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 193097ef3d7d..b5a22fa7e249 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -427,8 +427,7 @@ static void __init xen_init_cpuid_mask(void) | |||
427 | 427 | ||
428 | if (!xen_initial_domain()) | 428 | if (!xen_initial_domain()) |
429 | cpuid_leaf1_edx_mask &= | 429 | cpuid_leaf1_edx_mask &= |
430 | ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ | 430 | ~((1 << X86_FEATURE_ACPI)); /* disable ACPI */ |
431 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ | ||
432 | 431 | ||
433 | cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32)); | 432 | cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32)); |
434 | 433 | ||
@@ -735,8 +734,7 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, | |||
735 | addr = (unsigned long)xen_int3; | 734 | addr = (unsigned long)xen_int3; |
736 | else if (addr == (unsigned long)stack_segment) | 735 | else if (addr == (unsigned long)stack_segment) |
737 | addr = (unsigned long)xen_stack_segment; | 736 | addr = (unsigned long)xen_stack_segment; |
738 | else if (addr == (unsigned long)double_fault || | 737 | else if (addr == (unsigned long)double_fault) { |
739 | addr == (unsigned long)nmi) { | ||
740 | /* Don't need to handle these */ | 738 | /* Don't need to handle these */ |
741 | return 0; | 739 | return 0; |
742 | #ifdef CONFIG_X86_MCE | 740 | #ifdef CONFIG_X86_MCE |
@@ -747,7 +745,12 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, | |||
747 | */ | 745 | */ |
748 | ; | 746 | ; |
749 | #endif | 747 | #endif |
750 | } else { | 748 | } else if (addr == (unsigned long)nmi) |
749 | /* | ||
750 | * Use the native version as well. | ||
751 | */ | ||
752 | ; | ||
753 | else { | ||
751 | /* Some other trap using IST? */ | 754 | /* Some other trap using IST? */ |
752 | if (WARN_ON(val->ist != 0)) | 755 | if (WARN_ON(val->ist != 0)) |
753 | return 0; | 756 | return 0; |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 056d11faef21..403f5cc5415b 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -33,6 +33,9 @@ | |||
33 | /* These are code, but not functions. Defined in entry.S */ | 33 | /* These are code, but not functions. Defined in entry.S */ |
34 | extern const char xen_hypervisor_callback[]; | 34 | extern const char xen_hypervisor_callback[]; |
35 | extern const char xen_failsafe_callback[]; | 35 | extern const char xen_failsafe_callback[]; |
36 | #ifdef CONFIG_X86_64 | ||
37 | extern const char nmi[]; | ||
38 | #endif | ||
36 | extern void xen_sysenter_target(void); | 39 | extern void xen_sysenter_target(void); |
37 | extern void xen_syscall_target(void); | 40 | extern void xen_syscall_target(void); |
38 | extern void xen_syscall32_target(void); | 41 | extern void xen_syscall32_target(void); |
@@ -525,7 +528,13 @@ void xen_enable_syscall(void) | |||
525 | } | 528 | } |
526 | #endif /* CONFIG_X86_64 */ | 529 | #endif /* CONFIG_X86_64 */ |
527 | } | 530 | } |
528 | 531 | void __cpuinit xen_enable_nmi(void) | |
532 | { | ||
533 | #ifdef CONFIG_X86_64 | ||
534 | if (register_callback(CALLBACKTYPE_nmi, nmi)) | ||
535 | BUG(); | ||
536 | #endif | ||
537 | } | ||
529 | void __init xen_arch_setup(void) | 538 | void __init xen_arch_setup(void) |
530 | { | 539 | { |
531 | xen_panic_handler_init(); | 540 | xen_panic_handler_init(); |
@@ -543,7 +552,7 @@ void __init xen_arch_setup(void) | |||
543 | 552 | ||
544 | xen_enable_sysenter(); | 553 | xen_enable_sysenter(); |
545 | xen_enable_syscall(); | 554 | xen_enable_syscall(); |
546 | 555 | xen_enable_nmi(); | |
547 | #ifdef CONFIG_ACPI | 556 | #ifdef CONFIG_ACPI |
548 | if (!(xen_start_info->flags & SIF_INITDOMAIN)) { | 557 | if (!(xen_start_info->flags & SIF_INITDOMAIN)) { |
549 | printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); | 558 | printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index ca92754eb846..22759c6d309f 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -572,6 +572,12 @@ static inline int xen_map_vector(int vector) | |||
572 | case IRQ_WORK_VECTOR: | 572 | case IRQ_WORK_VECTOR: |
573 | xen_vector = XEN_IRQ_WORK_VECTOR; | 573 | xen_vector = XEN_IRQ_WORK_VECTOR; |
574 | break; | 574 | break; |
575 | #ifdef CONFIG_X86_64 | ||
576 | case NMI_VECTOR: | ||
577 | case APIC_DM_NMI: /* Some use that instead of NMI_VECTOR */ | ||
578 | xen_vector = XEN_NMI_VECTOR; | ||
579 | break; | ||
580 | #endif | ||
575 | default: | 581 | default: |
576 | xen_vector = -1; | 582 | xen_vector = -1; |
577 | printk(KERN_ERR "xen: vector 0x%x is not implemented\n", | 583 | printk(KERN_ERR "xen: vector 0x%x is not implemented\n", |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a58ac435a9a4..c8b9d9fc77b5 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <xen/interface/hvm/params.h> | 56 | #include <xen/interface/hvm/params.h> |
57 | #include <xen/interface/physdev.h> | 57 | #include <xen/interface/physdev.h> |
58 | #include <xen/interface/sched.h> | 58 | #include <xen/interface/sched.h> |
59 | #include <xen/interface/vcpu.h> | ||
59 | #include <asm/hw_irq.h> | 60 | #include <asm/hw_irq.h> |
60 | 61 | ||
61 | /* | 62 | /* |
@@ -1212,7 +1213,15 @@ EXPORT_SYMBOL_GPL(evtchn_put); | |||
1212 | 1213 | ||
1213 | void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) | 1214 | void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) |
1214 | { | 1215 | { |
1215 | int irq = per_cpu(ipi_to_irq, cpu)[vector]; | 1216 | int irq; |
1217 | |||
1218 | if (unlikely(vector == XEN_NMI_VECTOR)) { | ||
1219 | int rc = HYPERVISOR_vcpu_op(VCPUOP_send_nmi, cpu, NULL); | ||
1220 | if (rc < 0) | ||
1221 | printk(KERN_WARNING "Sending nmi to CPU%d failed (rc:%d)\n", cpu, rc); | ||
1222 | return; | ||
1223 | } | ||
1224 | irq = per_cpu(ipi_to_irq, cpu)[vector]; | ||
1216 | BUG_ON(irq < 0); | 1225 | BUG_ON(irq < 0); |
1217 | notify_remote_via_irq(irq); | 1226 | notify_remote_via_irq(irq); |
1218 | } | 1227 | } |
diff --git a/include/xen/interface/vcpu.h b/include/xen/interface/vcpu.h index 87e6f8a48661..b05288ce3991 100644 --- a/include/xen/interface/vcpu.h +++ b/include/xen/interface/vcpu.h | |||
@@ -170,4 +170,6 @@ struct vcpu_register_vcpu_info { | |||
170 | }; | 170 | }; |
171 | DEFINE_GUEST_HANDLE_STRUCT(vcpu_register_vcpu_info); | 171 | DEFINE_GUEST_HANDLE_STRUCT(vcpu_register_vcpu_info); |
172 | 172 | ||
173 | /* Send an NMI to the specified VCPU. @extra_arg == NULL. */ | ||
174 | #define VCPUOP_send_nmi 11 | ||
173 | #endif /* __XEN_PUBLIC_VCPU_H__ */ | 175 | #endif /* __XEN_PUBLIC_VCPU_H__ */ |