]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Youquan Song <youquan.song@intel.com> |
2 | Subject: x86: Fix APICID panic | |
3 | References: bnc#502026 | |
4 | ||
5 | Signed-off-by: Rafael J. Wysocki <rjw@suse.de> | |
6 | ||
7 | --- | |
8 | arch/x86/kernel/apic_64.c | 12 ++++++++++++ | |
9 | arch/x86/kernel/genapic_64.c | 10 ++++++++++ | |
10 | arch/x86/kernel/genx2apic_cluster.c | 5 +---- | |
11 | arch/x86/kernel/genx2apic_phys.c | 10 +++++----- | |
12 | include/asm-x86/apic.h | 10 +++++++++- | |
13 | 5 files changed, 37 insertions(+), 10 deletions(-) | |
14 | ||
15 | --- a/arch/x86/kernel/apic_64.c | |
16 | +++ b/arch/x86/kernel/apic_64.c | |
17 | @@ -928,6 +928,18 @@ void enable_x2apic(void) | |
18 | } | |
19 | } | |
20 | ||
21 | +int x2apic_enabled(void) | |
22 | +{ | |
23 | + int msr, msr2; | |
24 | + if (!cpu_has_x2apic) | |
25 | + return 0; | |
26 | + | |
27 | + rdmsr(MSR_IA32_APICBASE, msr, msr2); | |
28 | + if (msr & X2APIC_ENABLE) | |
29 | + return 1; | |
30 | + return 0; | |
31 | +} | |
32 | + | |
33 | void __init enable_IR_x2apic(void) | |
34 | { | |
35 | #ifdef CONFIG_INTR_REMAP | |
36 | --- a/arch/x86/kernel/genapic_64.c | |
37 | +++ b/arch/x86/kernel/genapic_64.c | |
38 | @@ -48,6 +48,16 @@ void __init setup_apic_routing(void) | |
39 | genapic = &apic_flat; | |
40 | } | |
41 | ||
42 | + if (x2apic && (genapic != &apic_x2apic_phys && | |
43 | + genapic != &apic_x2apic_uv_x && | |
44 | + genapic != &apic_x2apic_cluster)) { | |
45 | + if (x2apic_phys) | |
46 | + genapic = &apic_x2apic_phys; | |
47 | + else | |
48 | + genapic = &apic_x2apic_cluster; | |
49 | + printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); | |
50 | + } | |
51 | + | |
52 | if (genapic == &apic_flat) { | |
53 | if (max_physical_apicid >= 8) | |
54 | genapic = &apic_physflat; | |
55 | --- a/arch/x86/kernel/genx2apic_cluster.c | |
56 | +++ b/arch/x86/kernel/genx2apic_cluster.c | |
57 | @@ -14,10 +14,7 @@ DEFINE_PER_CPU(u32, x86_cpu_to_logical_a | |
58 | ||
59 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |
60 | { | |
61 | - if (cpu_has_x2apic) | |
62 | - return 1; | |
63 | - | |
64 | - return 0; | |
65 | + return x2apic_enabled(); | |
66 | } | |
67 | ||
68 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ | |
69 | --- a/arch/x86/kernel/genx2apic_phys.c | |
70 | +++ b/arch/x86/kernel/genx2apic_phys.c | |
71 | @@ -12,7 +12,7 @@ | |
72 | ||
73 | DEFINE_PER_CPU(int, x2apic_extra_bits); | |
74 | ||
75 | -static int x2apic_phys; | |
76 | +int x2apic_phys; | |
77 | ||
78 | static int set_x2apic_phys_mode(char *arg) | |
79 | { | |
80 | @@ -23,10 +23,10 @@ early_param("x2apic_phys", set_x2apic_ph | |
81 | ||
82 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |
83 | { | |
84 | - if (cpu_has_x2apic && x2apic_phys) | |
85 | - return 1; | |
86 | - | |
87 | - return 0; | |
88 | + if (x2apic_phys) | |
89 | + return x2apic_enabled(); | |
90 | + else | |
91 | + return 0; | |
92 | } | |
93 | ||
94 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ | |
95 | --- a/include/asm-x86/apic.h | |
96 | +++ b/include/asm-x86/apic.h | |
97 | @@ -90,11 +90,19 @@ static inline u32 native_apic_msr_read(u | |
98 | } | |
99 | ||
100 | #ifndef CONFIG_X86_32 | |
101 | - extern int x2apic, x2apic_preenabled; | |
102 | + extern int x2apic, x2apic_preenabled, x2apic_phys; | |
103 | extern void check_x2apic(void); | |
104 | extern void enable_x2apic(void); | |
105 | + extern int x2apic_enabled(void); | |
106 | extern void enable_IR_x2apic(void); | |
107 | extern void x2apic_icr_write(u32 low, u32 id); | |
108 | +#else | |
109 | + #define x2apic 0 | |
110 | + #define x2apic_phys 0 | |
111 | +static inline int x2apic_enabled(void) | |
112 | +{ | |
113 | + return 0; | |
114 | +} | |
115 | #endif | |
116 | ||
117 | struct apic_ops { |