@@ -30,8 +30,10 @@ static struct {
30
30
unsigned int nr_assigned_cpus ;
31
31
unsigned int nr_disabled_cpus ;
32
32
unsigned int nr_rejected_cpus ;
33
+ u32 boot_cpu_apic_id ;
33
34
} topo_info __read_mostly = {
34
35
.nr_assigned_cpus = 1 ,
36
+ .boot_cpu_apic_id = BAD_APICID ,
35
37
};
36
38
37
39
/*
@@ -83,78 +85,6 @@ early_initcall(smp_init_primary_thread_mask);
83
85
static inline void cpu_mark_primary_thread (unsigned int cpu , unsigned int apicid ) { }
84
86
#endif
85
87
86
- static int topo_lookup_cpuid (u32 apic_id )
87
- {
88
- int i ;
89
-
90
- /* CPU# to APICID mapping is persistent once it is established */
91
- for (i = 0 ; i < topo_info .nr_assigned_cpus ; i ++ ) {
92
- if (cpuid_to_apicid [i ] == apic_id )
93
- return i ;
94
- }
95
- return - ENODEV ;
96
- }
97
-
98
- /*
99
- * Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids
100
- * and cpuid_to_apicid[] synchronized.
101
- */
102
- static int allocate_logical_cpuid (u32 apic_id )
103
- {
104
- int cpu = topo_lookup_cpuid (apic_id );
105
-
106
- if (cpu >= 0 )
107
- return cpu ;
108
-
109
- return topo_info .nr_assigned_cpus ++ ;
110
- }
111
-
112
- static void cpu_update_apic (unsigned int cpu , u32 apic_id )
113
- {
114
- #if defined(CONFIG_SMP ) || defined(CONFIG_X86_64 )
115
- early_per_cpu (x86_cpu_to_apicid , cpu ) = apic_id ;
116
- #endif
117
- cpuid_to_apicid [cpu ] = apic_id ;
118
- set_cpu_possible (cpu , true);
119
- set_bit (apic_id , phys_cpu_present_map );
120
- set_cpu_present (cpu , true);
121
-
122
- if (system_state != SYSTEM_BOOTING )
123
- cpu_mark_primary_thread (cpu , apic_id );
124
- }
125
-
126
- static int generic_processor_info (int apicid )
127
- {
128
- int cpu ;
129
-
130
- /* The boot CPU must be set before MADT/MPTABLE parsing happens */
131
- if (cpuid_to_apicid [0 ] == BAD_APICID )
132
- panic ("Boot CPU APIC not registered yet\n" );
133
-
134
- if (apicid == boot_cpu_physical_apicid )
135
- return 0 ;
136
-
137
- if (disabled_cpu_apicid == apicid ) {
138
- int thiscpu = topo_info .nr_assigned_cpus + topo_info .nr_disabled_cpus ;
139
-
140
- pr_warn ("APIC: Disabling requested cpu. Processor %d/0x%x ignored.\n" ,
141
- thiscpu , apicid );
142
-
143
- topo_info .nr_rejected_cpus ++ ;
144
- return - ENODEV ;
145
- }
146
-
147
- if (topo_info .nr_assigned_cpus >= nr_cpu_ids ) {
148
- pr_warn_once ("APIC: CPU limit of %d reached. Ignoring further CPUs\n" , nr_cpu_ids );
149
- topo_info .nr_rejected_cpus ++ ;
150
- return - ENOSPC ;
151
- }
152
-
153
- cpu = allocate_logical_cpuid (apicid );
154
- cpu_update_apic (cpu , apicid );
155
- return cpu ;
156
- }
157
-
158
88
static int __initdata setup_possible_cpus = -1 ;
159
89
160
90
/*
@@ -222,6 +152,43 @@ __init void prefill_possible_map(void)
222
152
set_cpu_possible (i , true);
223
153
}
224
154
155
+ static int topo_lookup_cpuid (u32 apic_id )
156
+ {
157
+ int i ;
158
+
159
+ /* CPU# to APICID mapping is persistent once it is established */
160
+ for (i = 0 ; i < topo_info .nr_assigned_cpus ; i ++ ) {
161
+ if (cpuid_to_apicid [i ] == apic_id )
162
+ return i ;
163
+ }
164
+ return - ENODEV ;
165
+ }
166
+
167
+ static int topo_get_cpunr (u32 apic_id )
168
+ {
169
+ int cpu = topo_lookup_cpuid (apic_id );
170
+
171
+ if (cpu >= 0 )
172
+ return cpu ;
173
+
174
+ return topo_info .nr_assigned_cpus ++ ;
175
+ }
176
+
177
+ static void topo_set_cpuids (unsigned int cpu , u32 apic_id , u32 acpi_id )
178
+ {
179
+ #if defined(CONFIG_SMP ) || defined(CONFIG_X86_64 )
180
+ early_per_cpu (x86_cpu_to_apicid , cpu ) = apic_id ;
181
+ early_per_cpu (x86_cpu_to_acpiid , cpu ) = acpi_id ;
182
+ #endif
183
+ cpuid_to_apicid [cpu ] = apic_id ;
184
+
185
+ set_cpu_possible (cpu , true);
186
+ set_cpu_present (cpu , true);
187
+
188
+ if (system_state != SYSTEM_BOOTING )
189
+ cpu_mark_primary_thread (cpu , apic_id );
190
+ }
191
+
225
192
/**
226
193
* topology_register_apic - Register an APIC in early topology maps
227
194
* @apic_id: The APIC ID to set up
@@ -234,17 +201,40 @@ void __init topology_register_apic(u32 apic_id, u32 acpi_id, bool present)
234
201
235
202
if (apic_id >= MAX_LOCAL_APIC ) {
236
203
pr_err_once ("APIC ID %x exceeds kernel limit of: %x\n" , apic_id , MAX_LOCAL_APIC - 1 );
204
+ topo_info .nr_rejected_cpus ++ ;
237
205
return ;
238
206
}
239
207
240
- if (!present ) {
241
- topo_info .nr_disabled_cpus ++ ;
208
+ if (disabled_cpu_apicid == apic_id ) {
209
+ pr_info ("Disabling CPU as requested via 'disable_cpu_apicid=0x%x'.\n" , apic_id );
210
+ topo_info .nr_rejected_cpus ++ ;
242
211
return ;
243
212
}
244
213
245
- cpu = generic_processor_info (apic_id );
246
- if (cpu >= 0 )
247
- early_per_cpu (x86_cpu_to_acpiid , cpu ) = acpi_id ;
214
+ /* CPU numbers exhausted? */
215
+ if (apic_id != topo_info .boot_cpu_apic_id && topo_info .nr_assigned_cpus >= nr_cpu_ids ) {
216
+ pr_warn_once ("CPU limit of %d reached. Ignoring further CPUs\n" , nr_cpu_ids );
217
+ topo_info .nr_rejected_cpus ++ ;
218
+ return ;
219
+ }
220
+
221
+ if (present ) {
222
+ set_bit (apic_id , phys_cpu_present_map );
223
+
224
+ /*
225
+ * Double registration is valid in case of the boot CPU
226
+ * APIC because that is registered before the enumeration
227
+ * of the APICs via firmware parsers or VM guest
228
+ * mechanisms.
229
+ */
230
+ if (apic_id == topo_info .boot_cpu_apic_id )
231
+ cpu = 0 ;
232
+ else
233
+ cpu = topo_get_cpunr (apic_id );
234
+ topo_set_cpuids (cpu , apic_id , acpi_id );
235
+ } else {
236
+ topo_info .nr_disabled_cpus ++ ;
237
+ }
248
238
}
249
239
250
240
/**
@@ -255,8 +245,10 @@ void __init topology_register_apic(u32 apic_id, u32 acpi_id, bool present)
255
245
*/
256
246
void __init topology_register_boot_apic (u32 apic_id )
257
247
{
258
- cpuid_to_apicid [0 ] = apic_id ;
259
- cpu_update_apic (0 , apic_id );
248
+ WARN_ON_ONCE (topo_info .boot_cpu_apic_id != BAD_APICID );
249
+
250
+ topo_info .boot_cpu_apic_id = apic_id ;
251
+ topology_register_apic (apic_id , CPU_ACPIID_INVALID , true);
260
252
}
261
253
262
254
#ifdef CONFIG_ACPI_HOTPLUG_CPU
@@ -274,10 +266,13 @@ int topology_hotplug_apic(u32 apic_id, u32 acpi_id)
274
266
275
267
cpu = topo_lookup_cpuid (apic_id );
276
268
if (cpu < 0 ) {
277
- cpu = generic_processor_info (apic_id );
278
- if (cpu >= 0 )
279
- per_cpu (x86_cpu_to_acpiid , cpu ) = acpi_id ;
269
+ if (topo_info .nr_assigned_cpus >= nr_cpu_ids )
270
+ return - ENOSPC ;
271
+
272
+ cpu = topo_assign_cpunr (apic_id );
280
273
}
274
+ set_bit (apic_id , phys_cpu_present_map );
275
+ topo_set_cpuids (cpu , apic_id , acpi_id );
281
276
return cpu ;
282
277
}
283
278
0 commit comments