|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |