[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 |