[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/apic: Drop workarounds for Pentium/82489DX erratum
CONFIG_X86_GOOD_APIC is unconditionally selected for 64bit builds. Drop the related infrastructure including apic_{read,write}_around(), the former of which had no effect, and the latter which was an alias of apic_write(). No functional change, as confirmed by diffing the before/after disassembly. (Three __LINE__ numbers are different, but they are `mov $imm, %reg` as part of a dprintk() call.) Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- xen/arch/x86/apic.c | 72 ++++++++++++++++++------------------- xen/arch/x86/cpu/mcheck/mce_intel.c | 8 ++--- xen/arch/x86/cpu/vpmu.c | 5 ++- xen/arch/x86/genapic/delivery.c | 8 ++--- xen/arch/x86/io_apic.c | 14 ++++---- xen/arch/x86/smp.c | 10 +++--- xen/arch/x86/smpboot.c | 3 -- xen/include/asm-x86/apic.h | 19 +--------- xen/include/asm-x86/config.h | 1 - 9 files changed, 58 insertions(+), 82 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 1dd188a..a5ae4b6 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -157,7 +157,7 @@ void clear_local_APIC(void) maxlvt = get_maxlvt(); /* Work around AMD Erratum 411. This is a nice thing to do anyway. */ - apic_write_around(APIC_TMICT, 0); + apic_write(APIC_TMICT, 0); /* * Masking an LVT entry on a P6 can trigger a local APIC error @@ -165,52 +165,52 @@ void clear_local_APIC(void) */ if (maxlvt >= 3) { v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ - apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED); + apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); } /* * Careful: we have to set masks only first to deassert * any level-triggered sources. */ v = apic_read(APIC_LVTT); - apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); + apic_write(APIC_LVTT, v | APIC_LVT_MASKED); v = apic_read(APIC_LVT0); - apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); v = apic_read(APIC_LVT1); - apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED); + apic_write(APIC_LVT1, v | APIC_LVT_MASKED); if (maxlvt >= 4) { v = apic_read(APIC_LVTPC); - apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); + apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); } /* lets not touch this if we didn't frob it */ #ifdef CONFIG_X86_MCE_THERMAL if (maxlvt >= 5) { v = apic_read(APIC_LVTTHMR); - apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); + apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); } #endif if (maxlvt >= 6) { v = apic_read(APIC_CMCI); - apic_write_around(APIC_CMCI, v | APIC_LVT_MASKED); + apic_write(APIC_CMCI, v | APIC_LVT_MASKED); } /* * Clean APIC state for other OSs: */ - apic_write_around(APIC_LVTT, APIC_LVT_MASKED); - apic_write_around(APIC_LVT0, APIC_LVT_MASKED); - apic_write_around(APIC_LVT1, APIC_LVT_MASKED); + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_LVT0, APIC_LVT_MASKED); + apic_write(APIC_LVT1, APIC_LVT_MASKED); if (maxlvt >= 3) - apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); + apic_write(APIC_LVTERR, APIC_LVT_MASKED); if (maxlvt >= 4) - apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); + apic_write(APIC_LVTPC, APIC_LVT_MASKED); #ifdef CONFIG_X86_MCE_THERMAL if (maxlvt >= 5) - apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); + apic_write(APIC_LVTTHMR, APIC_LVT_MASKED); #endif if (maxlvt >= 6) - apic_write_around(APIC_CMCI, APIC_LVT_MASKED); + apic_write(APIC_CMCI, APIC_LVT_MASKED); if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */ apic_write(APIC_ESR, 0); @@ -259,7 +259,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) value &= ~APIC_VECTOR_MASK; value |= APIC_SPIV_APIC_ENABLED; value |= 0xf; - apic_write_around(APIC_SPIV, value); + apic_write(APIC_SPIV, value); if (!virt_wire_setup) { /* For LVT0 make it edge triggered, active high, external and enabled */ @@ -269,11 +269,11 @@ void disconnect_bsp_APIC(int virt_wire_setup) APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); - apic_write_around(APIC_LVT0, value); + apic_write(APIC_LVT0, value); } else { /* Disable LVT0 */ - apic_write_around(APIC_LVT0, APIC_LVT_MASKED); + apic_write(APIC_LVT0, APIC_LVT_MASKED); } /* For LVT1 make it edge triggered, active high, nmi and enabled */ @@ -284,7 +284,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); - apic_write_around(APIC_LVT1, value); + apic_write(APIC_LVT1, value); } } @@ -296,8 +296,7 @@ void disable_local_APIC(void) * Disable APIC (implies clearing of registers * for 82489DX!). */ - apic_write_around(APIC_SPIV, - apic_read(APIC_SPIV) & ~APIC_SPIV_APIC_ENABLED); + apic_write(APIC_SPIV, apic_read(APIC_SPIV) & ~APIC_SPIV_APIC_ENABLED); if (enabled_via_apicbase) { uint64_t msr_content; @@ -424,8 +423,7 @@ void __init sync_Arb_IDs(void) apic_wait_icr_idle(); apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); - apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG - | APIC_DM_INIT); + apic_write(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT); } /* @@ -460,13 +458,13 @@ void __init init_bsp_APIC(void) else value |= APIC_SPIV_FOCUS_DISABLED; value |= SPURIOUS_APIC_VECTOR; - apic_write_around(APIC_SPIV, value); + apic_write(APIC_SPIV, value); /* * Set up the virtual wire mode. */ - apic_write_around(APIC_LVT0, APIC_DM_EXTINT); - apic_write_around(APIC_LVT1, APIC_DM_NMI); + apic_write(APIC_LVT0, APIC_DM_EXTINT); + apic_write(APIC_LVT1, APIC_DM_NMI); } static void apic_pm_activate(void) @@ -551,7 +549,7 @@ void setup_local_APIC(void) /* * Set Task Priority to reject any interrupts below FIRST_DYNAMIC_VECTOR. */ - apic_write_around(APIC_TASKPRI, (FIRST_DYNAMIC_VECTOR & 0xF0) - 0x10); + apic_write(APIC_TASKPRI, (FIRST_DYNAMIC_VECTOR & 0xF0) - 0x10); /* * After a crash, we no longer service the interrupts and a pending @@ -623,7 +621,7 @@ void setup_local_APIC(void) smp_processor_id()); } - apic_write_around(APIC_SPIV, value); + apic_write(APIC_SPIV, value); /* * Set up LVT0, LVT1: @@ -645,7 +643,7 @@ void setup_local_APIC(void) apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", smp_processor_id()); } - apic_write_around(APIC_LVT0, value); + apic_write(APIC_LVT0, value); /* * only the BP should see the LINT1 NMI signal, obviously. @@ -654,7 +652,7 @@ void setup_local_APIC(void) value = APIC_DM_NMI; else value = APIC_DM_NMI | APIC_LVT_MASKED; - apic_write_around(APIC_LVT1, value); + apic_write(APIC_LVT1, value); if (!esr_disable) { maxlvt = get_maxlvt(); @@ -663,7 +661,7 @@ void setup_local_APIC(void) oldvalue = apic_read(APIC_ESR); value = ERROR_APIC_VECTOR; // enables sending errors - apic_write_around(APIC_LVTERR, value); + apic_write(APIC_LVTERR, value); /* * spec says clear errors after enabling vector. */ @@ -1075,12 +1073,12 @@ static void __setup_APIC_LVTT(unsigned int clocks) lvtt_value |= APIC_TIMER_MODE_TSC_DEADLINE; } - apic_write_around(APIC_LVTT, lvtt_value); + apic_write(APIC_LVTT, lvtt_value); tmp_value = apic_read(APIC_TDCR); - apic_write_around(APIC_TDCR, (tmp_value | APIC_TDR_DIV_1)); + apic_write(APIC_TDCR, tmp_value | APIC_TDR_DIV_1); - apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); + apic_write(APIC_TMICT, clocks / APIC_DIVISOR); } static void setup_APIC_timer(void) @@ -1206,10 +1204,10 @@ void disable_APIC_timer(void) unsigned long v; /* Work around AMD Erratum 411. This is a nice thing to do anyway. */ - apic_write_around(APIC_TMICT, 0); + apic_write(APIC_TMICT, 0); v = apic_read(APIC_LVTT); - apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); + apic_write(APIC_LVTT, v | APIC_LVT_MASKED); } } @@ -1219,7 +1217,7 @@ void enable_APIC_timer(void) unsigned long v; v = apic_read(APIC_LVTT); - apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED); + apic_write(APIC_LVTT, v & ~APIC_LVT_MASKED); } } diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index fdf57ce..4e976c4 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -158,7 +158,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) /* The temperature transition interrupt handler setup */ 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); + apic_write(APIC_LVTTHMR, val); rdmsrl(MSR_IA32_THERM_INTERRUPT, msr_content); wrmsrl(MSR_IA32_THERM_INTERRUPT, msr_content | 0x03); @@ -166,7 +166,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) rdmsrl(MSR_IA32_MISC_ENABLE, msr_content); wrmsrl(MSR_IA32_MISC_ENABLE, msr_content | (1ULL<<3)); - apic_write_around(APIC_LVTTHMR, val & ~APIC_LVT_MASKED); + apic_write(APIC_LVTTHMR, val & ~APIC_LVT_MASKED); if (opt_cpu_info) printk(KERN_INFO "CPU%u: Thermal monitoring enabled (%s)\n", cpu, tm2 ? "TM2" : "TM1"); @@ -673,10 +673,10 @@ static void intel_init_cmci(struct cpuinfo_x86 *c) apic = cmci_apic_vector; apic |= (APIC_DM_FIXED | APIC_LVT_MASKED); - apic_write_around(APIC_CMCI, apic); + apic_write(APIC_CMCI, apic); l = apic_read(APIC_CMCI); - apic_write_around(APIC_CMCI, l & ~APIC_LVT_MASKED); + apic_write(APIC_CMCI, l & ~APIC_LVT_MASKED); mce_set_owner(); } diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c index 1f7830b..21383d3 100644 --- a/xen/arch/x86/cpu/vpmu.c +++ b/xen/arch/x86/cpu/vpmu.c @@ -441,13 +441,12 @@ int vpmu_load(struct vcpu *v, bool_t from_guest) { int ret; - apic_write_around(APIC_LVTPC, vpmu->hw_lapic_lvtpc); + apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc); /* Arch code needs to set VPMU_CONTEXT_LOADED */ ret = vpmu->arch_vpmu_ops->arch_vpmu_load(v, from_guest); if ( ret ) { - apic_write_around(APIC_LVTPC, - vpmu->hw_lapic_lvtpc | APIC_LVT_MASKED); + apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc | APIC_LVT_MASKED); return ret; } } diff --git a/xen/arch/x86/genapic/delivery.c b/xen/arch/x86/genapic/delivery.c index 23ac361..ced92a1 100644 --- a/xen/arch/x86/genapic/delivery.c +++ b/xen/arch/x86/genapic/delivery.c @@ -19,10 +19,10 @@ void init_apic_ldr_flat(void) { unsigned long val; - apic_write_around(APIC_DFR, APIC_DFR_FLAT); + apic_write(APIC_DFR, APIC_DFR_FLAT); val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; val |= SET_xAPIC_LOGICAL_ID(1UL << smp_processor_id()); - apic_write_around(APIC_LDR, val); + apic_write(APIC_LDR, val); } void __init clustered_apic_check_flat(void) @@ -47,10 +47,10 @@ unsigned int cpu_mask_to_apicid_flat(const cpumask_t *cpumask) void init_apic_ldr_phys(void) { unsigned long val; - apic_write_around(APIC_DFR, APIC_DFR_FLAT); + apic_write(APIC_DFR, APIC_DFR_FLAT); /* A dummy logical ID should be fine. We only deliver in phys mode. */ val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - apic_write_around(APIC_LDR, val); + apic_write(APIC_LDR, val); } void __init clustered_apic_check_phys(void) diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index d180460..bd59e13 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -1062,7 +1062,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in disable_8259A_irq(irq_to_desc(0)); /* mask LVT0 */ - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); + apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); /* * We use logical delivery to get the timer IRQ @@ -1790,7 +1790,7 @@ static void enable_lapic_irq(struct irq_desc *desc) unsigned long v; v = apic_read(APIC_LVT0); - apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); + apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); } static void disable_lapic_irq(struct irq_desc *desc) @@ -1798,7 +1798,7 @@ static void disable_lapic_irq(struct irq_desc *desc) unsigned long v; v = apic_read(APIC_LVT0); - apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); } static void ack_lapic_irq(struct irq_desc *desc) @@ -1903,7 +1903,7 @@ static void __init check_timer(void) * the 8259A which implies the virtual wire has to be * disabled in the local APIC. */ - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); + apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); /* XEN: Ripped out the legacy missed-tick logic, so below is not needed. */ /*timer_ack = 1;*/ @@ -1963,7 +1963,7 @@ static void __init check_timer(void) disable_8259A_irq(irq_to_desc(0)); irq_desc[0].handler = &lapic_irq_type; - apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ + apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(irq_to_desc(0)); if (timer_irq_works()) { @@ -1971,7 +1971,7 @@ static void __init check_timer(void) printk(" works.\n"); return; } - apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); + apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); printk(" failed.\n"); printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); @@ -1979,7 +1979,7 @@ static void __init check_timer(void) /*timer_ack = 0;*/ init_8259A(0); make_8259A_irq(0); - apic_write_around(APIC_LVT0, APIC_DM_EXTINT); + apic_write(APIC_LVT0, APIC_DM_EXTINT); unlock_ExtINT_logic(); diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c index 70de53d..fd6d254 100644 --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -115,7 +115,7 @@ static void __default_send_IPI_shortcut(unsigned int shortcut, int vector, /* * Send the IPI. The write to APIC_ICR fires this off. */ - apic_write_around(APIC_ICR, cfg); + apic_write(APIC_ICR, cfg); } void send_IPI_self_legacy(uint8_t vector) @@ -145,7 +145,7 @@ void send_IPI_mask_flat(const cpumask_t *cpumask, int vector) * prepare target chip field */ cfg = __prepare_ICR2(mask); - apic_write_around(APIC_ICR2, cfg); + apic_write(APIC_ICR2, cfg); /* * program the ICR @@ -155,7 +155,7 @@ void send_IPI_mask_flat(const cpumask_t *cpumask, int vector) /* * Send the IPI. The write to APIC_ICR fires this off. */ - apic_write_around(APIC_ICR, cfg); + apic_write(APIC_ICR, cfg); local_irq_restore(flags); } @@ -181,7 +181,7 @@ void send_IPI_mask_phys(const cpumask_t *mask, int vector) * prepare target chip field */ cfg = __prepare_ICR2(cpu_physical_id(query_cpu)); - apic_write_around(APIC_ICR2, cfg); + apic_write(APIC_ICR2, cfg); /* * program the ICR @@ -191,7 +191,7 @@ void send_IPI_mask_phys(const cpumask_t *mask, int vector) /* * Send the IPI. The write to APIC_ICR fires this off. */ - apic_write_around(APIC_ICR, cfg); + apic_write(APIC_ICR, cfg); } local_irq_restore(flags); diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 92fe4f2..f375eb6 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -385,7 +385,6 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) /* * Be paranoid about clearing APIC errors. */ - apic_read_around(APIC_SPIV); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); @@ -439,7 +438,6 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) for ( i = 0; i < 2; i++ ) { Dprintk("Sending STARTUP #%d.\n", i+1); - apic_read_around(APIC_SPIV); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); Dprintk("After apic_write.\n"); @@ -472,7 +470,6 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) /* Due to the Pentium erratum 3AP. */ if ( maxlvt > 3 ) { - apic_read_around(APIC_SPIV); apic_write(APIC_ESR, 0); } accept_status = (apic_read(APIC_ESR) & 0xEF); diff --git a/xen/include/asm-x86/apic.h b/xen/include/asm-x86/apic.h index 9952039..d840ee5 100644 --- a/xen/include/asm-x86/apic.h +++ b/xen/include/asm-x86/apic.h @@ -161,27 +161,10 @@ void apic_wait_icr_idle(void); int get_physical_broadcast(void); -#ifdef CONFIG_X86_GOOD_APIC -# define FORCE_READ_AROUND_WRITE 0 -# define apic_read_around(x) -# define apic_write_around(x,y) apic_write((x),(y)) -#else -# define FORCE_READ_AROUND_WRITE 1 -# define apic_read_around(x) apic_read(x) -# define apic_write_around(x,y) apic_write_atomic((x),(y)) -#endif - static inline void ack_APIC_irq(void) { - /* - * ack_APIC_irq() actually gets compiled as a single instruction: - * - a single rmw on Pentium/82489DX - * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) - * ... yummie. - */ - /* Docs say use 0 for future compatibility */ - apic_write_around(APIC_EOI, 0); + apic_write(APIC_EOI, 0); } extern int get_maxlvt(void); diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index a199c3a..ba486d5 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -19,7 +19,6 @@ #define CONFIG_PAGING_ASSISTANCE 1 #define CONFIG_X86_LOCAL_APIC 1 -#define CONFIG_X86_GOOD_APIC 1 #define CONFIG_X86_IO_APIC 1 #define CONFIG_X86_PM_TIMER 1 #define CONFIG_HPET_TIMER 1 -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |