forked from Minki/linux
Revert "x86/apic: Remove init_bsp_APIC()"
This reverts commit b371ae0d4a
. It causes
boot hangs on old P3/P4 systems when the local APIC is enforced in UP mode.
Reported-by: Meelis Roos <mroos@linux.ee>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Dou Liyang <douly.fnst@cn.fujitsu.com>
Cc: yinghai@kernel.org
Cc: bhe@redhat.com
Link: https://lkml.kernel.org/r/20171128145350.21560-1-ville.syrjala@linux.intel.com
This commit is contained in:
parent
beacd6f7ed
commit
fc90ccfd28
@ -136,6 +136,7 @@ extern void disconnect_bsp_APIC(int virt_wire_setup);
|
||||
extern void disable_local_APIC(void);
|
||||
extern void lapic_shutdown(void);
|
||||
extern void sync_Arb_IDs(void);
|
||||
extern void init_bsp_APIC(void);
|
||||
extern void apic_intr_mode_init(void);
|
||||
extern void setup_local_APIC(void);
|
||||
extern void init_apic_mappings(void);
|
||||
|
@ -1286,6 +1286,55 @@ static int __init apic_intr_mode_select(void)
|
||||
return APIC_SYMMETRIC_IO;
|
||||
}
|
||||
|
||||
/*
|
||||
* An initial setup of the virtual wire mode.
|
||||
*/
|
||||
void __init init_bsp_APIC(void)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
/*
|
||||
* Don't do the setup now if we have a SMP BIOS as the
|
||||
* through-I/O-APIC virtual wire mode might be active.
|
||||
*/
|
||||
if (smp_found_config || !boot_cpu_has(X86_FEATURE_APIC))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Do not trust the local APIC being empty at bootup.
|
||||
*/
|
||||
clear_local_APIC();
|
||||
|
||||
/*
|
||||
* Enable APIC.
|
||||
*/
|
||||
value = apic_read(APIC_SPIV);
|
||||
value &= ~APIC_VECTOR_MASK;
|
||||
value |= APIC_SPIV_APIC_ENABLED;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* This bit is reserved on P4/Xeon and should be cleared */
|
||||
if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
|
||||
(boot_cpu_data.x86 == 15))
|
||||
value &= ~APIC_SPIV_FOCUS_DISABLED;
|
||||
else
|
||||
#endif
|
||||
value |= APIC_SPIV_FOCUS_DISABLED;
|
||||
value |= SPURIOUS_APIC_VECTOR;
|
||||
apic_write(APIC_SPIV, value);
|
||||
|
||||
/*
|
||||
* Set up the virtual wire mode.
|
||||
*/
|
||||
apic_write(APIC_LVT0, APIC_DM_EXTINT);
|
||||
value = APIC_DM_NMI;
|
||||
if (!lapic_is_integrated()) /* 82489DX */
|
||||
value |= APIC_LVT_LEVEL_TRIGGER;
|
||||
if (apic_extnmi == APIC_EXTNMI_NONE)
|
||||
value |= APIC_LVT_MASKED;
|
||||
apic_write(APIC_LVT1, value);
|
||||
}
|
||||
|
||||
/* Init the interrupt delivery mode for the BSP */
|
||||
void __init apic_intr_mode_init(void)
|
||||
{
|
||||
|
@ -61,6 +61,9 @@ void __init init_ISA_irqs(void)
|
||||
struct irq_chip *chip = legacy_pic->chip;
|
||||
int i;
|
||||
|
||||
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
|
||||
init_bsp_APIC();
|
||||
#endif
|
||||
legacy_pic->init(0);
|
||||
|
||||
for (i = 0; i < nr_legacy_irqs(); i++)
|
||||
|
Loading…
Reference in New Issue
Block a user