[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Allow direct vectored interrupts to be dynamically allocated.



# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1333095265 -3600
# Node ID 14609be41f369c26e759c5d63cc0d2be2fc5b9b6
# Parent  d698f46b4be9f149291d0955a07a4170352997d7
x86: Allow direct vectored interrupts to be dynamically allocated.

Use this for Intel's CMCI and thermal interrupts.

Signed-off-by: Keir Fraser <keir@xxxxxxx>
---


diff -r d698f46b4be9 -r 14609be41f36 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Fri Mar 30 08:52:19 2012 +0100
+++ b/xen/arch/x86/apic.c       Fri Mar 30 09:14:25 2012 +0100
@@ -128,14 +128,6 @@ void __init apic_intr_init(void)
 
     /* Performance Counters Interrupt */
     set_direct_apic_vector(PMU_APIC_VECTOR, pmu_apic_interrupt);
-
-    /* CMCI Correctable Machine Check Interrupt */
-    set_direct_apic_vector(CMCI_APIC_VECTOR, cmci_interrupt);
-
-    /* thermal monitor LVT interrupt, for P4 and latest Intel CPU*/
-#ifdef CONFIG_X86_MCE_THERMAL
-    set_direct_apic_vector(THERMAL_APIC_VECTOR, thermal_interrupt);
-#endif
 }
 
 /* Using APIC to generate smp_local_timer_interrupt? */
diff -r d698f46b4be9 -r 14609be41f36 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c       Fri Mar 30 08:52:19 2012 +0100
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c       Fri Mar 30 09:14:25 2012 +0100
@@ -46,22 +46,15 @@ static int __read_mostly nr_intel_ext_ms
 #define INTEL_SRAR_DATA_LOAD   0x134
 #define INTEL_SRAR_INSTR_FETCH 0x150
 
-/* Thermal Hanlding */
 #ifdef CONFIG_X86_MCE_THERMAL
-static void unexpected_thermal_interrupt(struct cpu_user_regs *regs)
-{
-    printk(KERN_ERR "Thermal: CPU%d: Unexpected LVT TMR interrupt!\n",
-                smp_processor_id());
-    add_taint(TAINT_MACHINE_CHECK);
-}
-
-/* P4/Xeon Thermal transition interrupt handler */
 static void intel_thermal_interrupt(struct cpu_user_regs *regs)
 {
     uint64_t msr_content;
     unsigned int cpu = smp_processor_id();
     static DEFINE_PER_CPU(s_time_t, next);
 
+    ack_APIC_irq();
+
     if (NOW() < per_cpu(next, cpu))
         return;
 
@@ -77,16 +70,6 @@ static void intel_thermal_interrupt(stru
     }
 }
 
-/* Thermal interrupt handler for this CPU setup */
-static void (*__read_mostly vendor_thermal_interrupt)(
-    struct cpu_user_regs *regs) = unexpected_thermal_interrupt;
-
-void thermal_interrupt(struct cpu_user_regs *regs)
-{
-    ack_APIC_irq();
-    vendor_thermal_interrupt(regs);
-}
-
 /* Thermal monitoring depends on APIC, ACPI and clock modulation */
 static int intel_thermal_supported(struct cpuinfo_x86 *c)
 {
@@ -117,6 +100,7 @@ static void intel_init_thermal(struct cp
     uint32_t val;
     int tm2 = 0;
     unsigned int cpu = smp_processor_id();
+    static uint8_t thermal_apic_vector;
 
     if (!intel_thermal_supported(c))
         return; /* -ENODEV */
@@ -159,17 +143,16 @@ static void intel_init_thermal(struct cp
         return; /* -EBUSY */
     }
 
+    alloc_direct_apic_vector(&thermal_apic_vector, intel_thermal_interrupt);
+
     /* The temperature transition interrupt handler setup */
-    val = THERMAL_APIC_VECTOR;    /* our delivery vector */
+    val = thermal_apic_vector;    /* our delivery vector */
     val |= (APIC_DM_FIXED | APIC_LVT_MASKED);  /* we'll mask till we're ready 
*/
     apic_write_around(APIC_LVTTHMR, val);
 
     rdmsrl(MSR_IA32_THERM_INTERRUPT, msr_content);
     wrmsrl(MSR_IA32_THERM_INTERRUPT, msr_content | 0x03);
 
-    /* ok we're good to go... */
-    vendor_thermal_interrupt = intel_thermal_interrupt;
-
     rdmsrl(MSR_IA32_MISC_ENABLE, msr_content);
     wrmsrl(MSR_IA32_MISC_ENABLE, msr_content | (1ULL<<3));
 
@@ -1154,36 +1137,7 @@ static void cpu_mcheck_disable(void)
         clear_cmci();
 }
 
-static void intel_init_cmci(struct cpuinfo_x86 *c)
-{
-    u32 l, apic;
-    int cpu = smp_processor_id();
-
-    if (!mce_available(c) || !cmci_support) {
-        if (opt_cpu_info)
-            mce_printk(MCE_QUIET, "CMCI: CPU%d has no CMCI support\n", cpu);
-        return;
-    }
-
-    apic = apic_read(APIC_CMCI);
-    if ( apic & APIC_VECTOR_MASK )
-    {
-        mce_printk(MCE_QUIET, "CPU%d CMCI LVT vector (%#x) already 
installed\n",
-            cpu, ( apic & APIC_VECTOR_MASK ));
-        return;
-    }
-
-    apic = CMCI_APIC_VECTOR;
-    apic |= (APIC_DM_FIXED | APIC_LVT_MASKED);
-    apic_write_around(APIC_CMCI, apic);
-
-    l = apic_read(APIC_CMCI);
-    apic_write_around(APIC_CMCI, l & ~APIC_LVT_MASKED);
-
-    mce_set_owner();
-}
-
-void cmci_interrupt(struct cpu_user_regs *regs)
+static void cmci_interrupt(struct cpu_user_regs *regs)
 {
     mctelem_cookie_t mctc;
     struct mca_summary bs;
@@ -1206,6 +1160,38 @@ void cmci_interrupt(struct cpu_user_regs
         mctelem_dismiss(mctc);
 }
 
+static void intel_init_cmci(struct cpuinfo_x86 *c)
+{
+    u32 l, apic;
+    int cpu = smp_processor_id();
+    static uint8_t cmci_apic_vector;
+
+    if (!mce_available(c) || !cmci_support) {
+        if (opt_cpu_info)
+            mce_printk(MCE_QUIET, "CMCI: CPU%d has no CMCI support\n", cpu);
+        return;
+    }
+
+    apic = apic_read(APIC_CMCI);
+    if ( apic & APIC_VECTOR_MASK )
+    {
+        mce_printk(MCE_QUIET, "CPU%d CMCI LVT vector (%#x) already 
installed\n",
+            cpu, ( apic & APIC_VECTOR_MASK ));
+        return;
+    }
+
+    alloc_direct_apic_vector(&cmci_apic_vector, cmci_interrupt);
+
+    apic = cmci_apic_vector;
+    apic |= (APIC_DM_FIXED | APIC_LVT_MASKED);
+    apic_write_around(APIC_CMCI, apic);
+
+    l = apic_read(APIC_CMCI);
+    apic_write_around(APIC_CMCI, l & ~APIC_LVT_MASKED);
+
+    mce_set_owner();
+}
+
 /* MCA */
 
 static int mce_is_broadcast(struct cpuinfo_x86 *c)
diff -r d698f46b4be9 -r 14609be41f36 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Fri Mar 30 08:52:19 2012 +0100
+++ b/xen/arch/x86/irq.c        Fri Mar 30 09:14:25 2012 +0100
@@ -772,6 +772,21 @@ void set_direct_apic_vector(
     direct_apic_vector[vector] = handler;
 }
 
+void alloc_direct_apic_vector(
+    uint8_t *vector, void (*handler)(struct cpu_user_regs *))
+{
+    static uint8_t next = LAST_HIPRIORITY_VECTOR;
+    static DEFINE_SPINLOCK(lock);
+
+    spin_lock(&lock);
+    if (*vector == 0) {
+        BUG_ON(next == FIRST_HIPRIORITY_VECTOR);
+        set_direct_apic_vector(next, handler);
+        *vector = next--;
+    }
+    spin_unlock(&lock);
+}
+
 void do_IRQ(struct cpu_user_regs *regs)
 {
     struct irqaction *action;
diff -r d698f46b4be9 -r 14609be41f36 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Fri Mar 30 08:52:19 2012 +0100
+++ b/xen/include/asm-x86/irq.h Fri Mar 30 09:14:25 2012 +0100
@@ -86,12 +86,12 @@ void apic_timer_interrupt(struct cpu_use
 void error_interrupt(struct cpu_user_regs *regs);
 void pmu_apic_interrupt(struct cpu_user_regs *regs);
 void spurious_interrupt(struct cpu_user_regs *regs);
-void thermal_interrupt(struct cpu_user_regs *regs);
-void cmci_interrupt(struct cpu_user_regs *regs);
 void irq_move_cleanup_interrupt(struct cpu_user_regs *regs);
 
 void set_direct_apic_vector(
     uint8_t vector, void (*handler)(struct cpu_user_regs *));
+void alloc_direct_apic_vector(
+    uint8_t *vector, void (*handler)(struct cpu_user_regs *));
 
 void do_IRQ(struct cpu_user_regs *regs);
 
diff -r d698f46b4be9 -r 14609be41f36 
xen/include/asm-x86/mach-default/irq_vectors.h
--- a/xen/include/asm-x86/mach-default/irq_vectors.h    Fri Mar 30 08:52:19 
2012 +0100
+++ b/xen/include/asm-x86/mach-default/irq_vectors.h    Fri Mar 30 09:14:25 
2012 +0100
@@ -7,16 +7,14 @@
 #define INVALIDATE_TLB_VECTOR  0xfd
 #define EVENT_CHECK_VECTOR     0xfc
 #define CALL_FUNCTION_VECTOR   0xfb
-#define THERMAL_APIC_VECTOR    0xfa
-#define LOCAL_TIMER_VECTOR     0xf9
-#define PMU_APIC_VECTOR        0xf8
-#define CMCI_APIC_VECTOR       0xf7
+#define LOCAL_TIMER_VECTOR     0xfa
+#define PMU_APIC_VECTOR        0xf9
 /*
  * High-priority dynamically-allocated vectors. For interrupts that
  * must be higher priority than any guest-bound interrupt.
  */
 #define FIRST_HIPRIORITY_VECTOR        0xf0
-#define LAST_HIPRIORITY_VECTOR  0xf6
+#define LAST_HIPRIORITY_VECTOR  0xf8
 
 /* Legacy PIC uses vectors 0xe0-0xef. */
 #define FIRST_LEGACY_VECTOR    0xe0

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.