x86/apic: Prepare for unifying the interrupt delivery modes setup
There are three places which initialize the interrupt delivery modes: 1) init_bsp_APIC() which is called early might setup the through-local-APIC virtual wire mode on non SMP systems. 2) In an SMP-capable system, native_smp_prepare_cpus() tries to switch to symmetric I/O model. 3) In UP system with UP_LATE_INIT=y, the local APIC and I/O APIC are set up in smp_init(). There is no technical reason to make these initializations at random places and run the kernel with the potentially wrong mode through the early boot stage, but it has a problematic side effect: The late switch to symmetric I/O mode causes dump-capture kernel to hang when the kernel command line option 'notsc' is active. Provide a new function to unify that three positions. Preparatory patch to initialize an interrupt mode directly. Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: yinghai@kernel.org Cc: bhe@redhat.com Link: https://lkml.kernel.org/r/1505293975-26005-3-git-send-email-douly.fnst@cn.fujitsu.com
This commit is contained in:
parent
0114a8e877
commit
4b1669e8d1
|
@ -128,6 +128,7 @@ extern void disable_local_APIC(void);
|
||||||
extern void lapic_shutdown(void);
|
extern void lapic_shutdown(void);
|
||||||
extern void sync_Arb_IDs(void);
|
extern void sync_Arb_IDs(void);
|
||||||
extern void init_bsp_APIC(void);
|
extern void init_bsp_APIC(void);
|
||||||
|
extern void apic_intr_mode_init(void);
|
||||||
extern void setup_local_APIC(void);
|
extern void setup_local_APIC(void);
|
||||||
extern void init_apic_mappings(void);
|
extern void init_apic_mappings(void);
|
||||||
void register_lapic_address(unsigned long address);
|
void register_lapic_address(unsigned long address);
|
||||||
|
@ -170,6 +171,7 @@ static inline void disable_local_APIC(void) { }
|
||||||
# define setup_boot_APIC_clock x86_init_noop
|
# define setup_boot_APIC_clock x86_init_noop
|
||||||
# define setup_secondary_APIC_clock x86_init_noop
|
# define setup_secondary_APIC_clock x86_init_noop
|
||||||
static inline void lapic_update_tsc_freq(void) { }
|
static inline void lapic_update_tsc_freq(void) { }
|
||||||
|
static inline void apic_intr_mode_init(void) { }
|
||||||
#endif /* !CONFIG_X86_LOCAL_APIC */
|
#endif /* !CONFIG_X86_LOCAL_APIC */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
|
|
|
@ -1319,6 +1319,22 @@ void __init init_bsp_APIC(void)
|
||||||
apic_write(APIC_LVT1, value);
|
apic_write(APIC_LVT1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Init the interrupt delivery mode for the BSP */
|
||||||
|
void __init apic_intr_mode_init(void)
|
||||||
|
{
|
||||||
|
switch (apic_intr_mode_select()) {
|
||||||
|
case APIC_PIC:
|
||||||
|
pr_info("APIC: Keep in PIC mode(8259)\n");
|
||||||
|
return;
|
||||||
|
case APIC_VIRTUAL_WIRE:
|
||||||
|
pr_info("APIC: Switch to virtual wire mode setup\n");
|
||||||
|
return;
|
||||||
|
case APIC_SYMMETRIC_IO:
|
||||||
|
pr_info("APIC: Switch to symmectic I/O mode setup\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void lapic_setup_esr(void)
|
static void lapic_setup_esr(void)
|
||||||
{
|
{
|
||||||
unsigned int oldvalue, value, maxlvt;
|
unsigned int oldvalue, value, maxlvt;
|
||||||
|
|
Loading…
Reference in New Issue