@@ -32,18 +32,13 @@ static struct {
32
32
unsigned int nr_disabled_cpus ;
33
33
unsigned int nr_rejected_cpus ;
34
34
u32 boot_cpu_apic_id ;
35
+ u32 real_bsp_apic_id ;
35
36
} topo_info __read_mostly = {
36
37
.nr_assigned_cpus = 1 ,
37
38
.boot_cpu_apic_id = BAD_APICID ,
39
+ .real_bsp_apic_id = BAD_APICID ,
38
40
};
39
41
40
- /*
41
- * Processor to be disabled specified by kernel parameter
42
- * disable_cpu_apicid=<int>, mostly used for the kdump 2nd kernel to
43
- * avoid undefined behaviour caused by sending INIT from AP to BSP.
44
- */
45
- static u32 disabled_cpu_apicid __ro_after_init = BAD_APICID ;
46
-
47
42
bool arch_match_cpu_phys_id (int cpu , u64 phys_id )
48
43
{
49
44
return phys_id == (u64 )cpuid_to_apicid [cpu ];
@@ -123,6 +118,60 @@ static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id)
123
118
cpu_mark_primary_thread (cpu , apic_id );
124
119
}
125
120
121
+ static __init bool check_for_real_bsp (u32 apic_id )
122
+ {
123
+ /*
124
+ * There is no real good way to detect whether this a kdump()
125
+ * kernel, but except on the Voyager SMP monstrosity which is not
126
+ * longer supported, the real BSP APIC ID is the first one which is
127
+ * enumerated by firmware. That allows to detect whether the boot
128
+ * CPU is the real BSP. If it is not, then do not register the APIC
129
+ * because sending INIT to the real BSP would reset the whole
130
+ * system.
131
+ *
132
+ * The first APIC ID which is enumerated by firmware is detectable
133
+ * because the boot CPU APIC ID is registered before that without
134
+ * invoking this code.
135
+ */
136
+ if (topo_info .real_bsp_apic_id != BAD_APICID )
137
+ return false;
138
+
139
+ if (apic_id == topo_info .boot_cpu_apic_id ) {
140
+ topo_info .real_bsp_apic_id = apic_id ;
141
+ return false;
142
+ }
143
+
144
+ pr_warn ("Boot CPU APIC ID not the first enumerated APIC ID: %x > %x\n" ,
145
+ topo_info .boot_cpu_apic_id , apic_id );
146
+ pr_warn ("Crash kernel detected. Disabling real BSP to prevent machine INIT\n" );
147
+
148
+ topo_info .real_bsp_apic_id = apic_id ;
149
+ return true;
150
+ }
151
+
152
+ static __init void topo_register_apic (u32 apic_id , u32 acpi_id , bool present )
153
+ {
154
+ int cpu ;
155
+
156
+ if (present ) {
157
+ set_bit (apic_id , phys_cpu_present_map );
158
+
159
+ /*
160
+ * Double registration is valid in case of the boot CPU
161
+ * APIC because that is registered before the enumeration
162
+ * of the APICs via firmware parsers or VM guest
163
+ * mechanisms.
164
+ */
165
+ if (apic_id == topo_info .boot_cpu_apic_id )
166
+ cpu = 0 ;
167
+ else
168
+ cpu = topo_get_cpunr (apic_id );
169
+ topo_set_cpuids (cpu , apic_id , acpi_id );
170
+ } else {
171
+ topo_info .nr_disabled_cpus ++ ;
172
+ }
173
+ }
174
+
126
175
/**
127
176
* topology_register_apic - Register an APIC in early topology maps
128
177
* @apic_id: The APIC ID to set up
@@ -131,16 +180,13 @@ static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id)
131
180
*/
132
181
void __init topology_register_apic (u32 apic_id , u32 acpi_id , bool present )
133
182
{
134
- int cpu ;
135
-
136
183
if (apic_id >= MAX_LOCAL_APIC ) {
137
184
pr_err_once ("APIC ID %x exceeds kernel limit of: %x\n" , apic_id , MAX_LOCAL_APIC - 1 );
138
185
topo_info .nr_rejected_cpus ++ ;
139
186
return ;
140
187
}
141
188
142
- if (disabled_cpu_apicid == apic_id ) {
143
- pr_info ("Disabling CPU as requested via 'disable_cpu_apicid=0x%x'.\n" , apic_id );
189
+ if (check_for_real_bsp (apic_id )) {
144
190
topo_info .nr_rejected_cpus ++ ;
145
191
return ;
146
192
}
@@ -152,23 +198,7 @@ void __init topology_register_apic(u32 apic_id, u32 acpi_id, bool present)
152
198
return ;
153
199
}
154
200
155
- if (present ) {
156
- set_bit (apic_id , phys_cpu_present_map );
157
-
158
- /*
159
- * Double registration is valid in case of the boot CPU
160
- * APIC because that is registered before the enumeration
161
- * of the APICs via firmware parsers or VM guest
162
- * mechanisms.
163
- */
164
- if (apic_id == topo_info .boot_cpu_apic_id )
165
- cpu = 0 ;
166
- else
167
- cpu = topo_get_cpunr (apic_id );
168
- topo_set_cpuids (cpu , apic_id , acpi_id );
169
- } else {
170
- topo_info .nr_disabled_cpus ++ ;
171
- }
201
+ topo_register_apic (apic_id , acpi_id , present );
172
202
}
173
203
174
204
/**
@@ -182,7 +212,7 @@ void __init topology_register_boot_apic(u32 apic_id)
182
212
WARN_ON_ONCE (topo_info .boot_cpu_apic_id != BAD_APICID );
183
213
184
214
topo_info .boot_cpu_apic_id = apic_id ;
185
- topology_register_apic (apic_id , CPU_ACPIID_INVALID , true);
215
+ topo_register_apic (apic_id , CPU_ACPIID_INVALID , true);
186
216
}
187
217
188
218
#ifdef CONFIG_ACPI_HOTPLUG_CPU
@@ -335,12 +365,3 @@ static int __init setup_possible_cpus(char *str)
335
365
}
336
366
early_param ("possible_cpus" , setup_possible_cpus );
337
367
#endif
338
-
339
- static int __init apic_set_disabled_cpu_apicid (char * arg )
340
- {
341
- if (!arg || !get_option (& arg , & disabled_cpu_apicid ))
342
- return - EINVAL ;
343
-
344
- return 0 ;
345
- }
346
- early_param ("disable_cpu_apicid" , apic_set_disabled_cpu_apicid );
0 commit comments