diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 14:58:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-31 14:58:45 -0400 |
commit | 6ed7705167dd056c61b1954fe1366fcddb5bda98 (patch) | |
tree | d58f35c83a831b1b15c6cac8f07af6fe9d27924e | |
parent | 3a88fe3b748b5bcf1c2c739ad63dab8364fd5b9b (diff) | |
parent | ea7bdc65bca8cf837a63e0ff7b75daed83222511 (diff) |
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic changes from Ingo Molnar:
"An xAPIC CPU hotplug race fix, plus cleanups and minor fixes"
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/apic: Plug racy xAPIC access of CPU hotplug code
x86/apic: Always define nox2apic and define it as initdata
x86/apic: Remove unused function prototypes
x86/apic: Switch wait_for_init_deassert() to a bool flag
x86/apic: Only use default_wait_for_init_deassert()
-rw-r--r-- | arch/x86/include/asm/apic.h | 14 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_flat_64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_noop.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_numachip.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/bigsmp_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_phys.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 16 |
14 files changed, 36 insertions, 46 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 1d2091a226bc..19b0ebafcd3e 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -93,9 +93,6 @@ static inline int is_vsmp_box(void) | |||
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | #endif | 95 | #endif |
96 | extern void xapic_wait_icr_idle(void); | ||
97 | extern u32 safe_xapic_wait_icr_idle(void); | ||
98 | extern void xapic_icr_write(u32, u32); | ||
99 | extern int setup_profiling_timer(unsigned int); | 96 | extern int setup_profiling_timer(unsigned int); |
100 | 97 | ||
101 | static inline void native_apic_mem_write(u32 reg, u32 v) | 98 | static inline void native_apic_mem_write(u32 reg, u32 v) |
@@ -184,7 +181,6 @@ extern int x2apic_phys; | |||
184 | extern int x2apic_preenabled; | 181 | extern int x2apic_preenabled; |
185 | extern void check_x2apic(void); | 182 | extern void check_x2apic(void); |
186 | extern void enable_x2apic(void); | 183 | extern void enable_x2apic(void); |
187 | extern void x2apic_icr_write(u32 low, u32 id); | ||
188 | static inline int x2apic_enabled(void) | 184 | static inline int x2apic_enabled(void) |
189 | { | 185 | { |
190 | u64 msr; | 186 | u64 msr; |
@@ -221,7 +217,6 @@ static inline void x2apic_force_phys(void) | |||
221 | { | 217 | { |
222 | } | 218 | } |
223 | 219 | ||
224 | #define nox2apic 0 | ||
225 | #define x2apic_preenabled 0 | 220 | #define x2apic_preenabled 0 |
226 | #define x2apic_supported() 0 | 221 | #define x2apic_supported() 0 |
227 | #endif | 222 | #endif |
@@ -351,7 +346,7 @@ struct apic { | |||
351 | int trampoline_phys_low; | 346 | int trampoline_phys_low; |
352 | int trampoline_phys_high; | 347 | int trampoline_phys_high; |
353 | 348 | ||
354 | void (*wait_for_init_deassert)(atomic_t *deassert); | 349 | bool wait_for_init_deassert; |
355 | void (*smp_callin_clear_local_apic)(void); | 350 | void (*smp_callin_clear_local_apic)(void); |
356 | void (*inquire_remote_apic)(int apicid); | 351 | void (*inquire_remote_apic)(int apicid); |
357 | 352 | ||
@@ -517,13 +512,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu); | |||
517 | extern int default_check_phys_apicid_present(int phys_apicid); | 512 | extern int default_check_phys_apicid_present(int phys_apicid); |
518 | #endif | 513 | #endif |
519 | 514 | ||
520 | static inline void default_wait_for_init_deassert(atomic_t *deassert) | ||
521 | { | ||
522 | while (!atomic_read(deassert)) | ||
523 | cpu_relax(); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | extern void generic_bigsmp_probe(void); | 515 | extern void generic_bigsmp_probe(void); |
528 | 516 | ||
529 | 517 | ||
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 7f26c9a70a9e..53e20531470e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -133,6 +133,10 @@ static inline void imcr_apic_to_pic(void) | |||
133 | * +1=force-enable | 133 | * +1=force-enable |
134 | */ | 134 | */ |
135 | static int force_enable_local_apic __initdata; | 135 | static int force_enable_local_apic __initdata; |
136 | |||
137 | /* Control whether x2APIC mode is enabled or not */ | ||
138 | static bool nox2apic __initdata; | ||
139 | |||
136 | /* | 140 | /* |
137 | * APIC command line parameters | 141 | * APIC command line parameters |
138 | */ | 142 | */ |
@@ -162,8 +166,7 @@ int x2apic_mode; | |||
162 | /* x2apic enabled before OS handover */ | 166 | /* x2apic enabled before OS handover */ |
163 | int x2apic_preenabled; | 167 | int x2apic_preenabled; |
164 | static int x2apic_disabled; | 168 | static int x2apic_disabled; |
165 | static int nox2apic; | 169 | static int __init setup_nox2apic(char *str) |
166 | static __init int setup_nox2apic(char *str) | ||
167 | { | 170 | { |
168 | if (x2apic_enabled()) { | 171 | if (x2apic_enabled()) { |
169 | int apicid = native_apic_msr_read(APIC_ID); | 172 | int apicid = native_apic_msr_read(APIC_ID); |
@@ -178,7 +181,7 @@ static __init int setup_nox2apic(char *str) | |||
178 | } else | 181 | } else |
179 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | 182 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); |
180 | 183 | ||
181 | nox2apic = 1; | 184 | nox2apic = true; |
182 | 185 | ||
183 | return 0; | 186 | return 0; |
184 | } | 187 | } |
@@ -283,8 +286,12 @@ u32 native_safe_apic_wait_icr_idle(void) | |||
283 | 286 | ||
284 | void native_apic_icr_write(u32 low, u32 id) | 287 | void native_apic_icr_write(u32 low, u32 id) |
285 | { | 288 | { |
289 | unsigned long flags; | ||
290 | |||
291 | local_irq_save(flags); | ||
286 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); | 292 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); |
287 | apic_write(APIC_ICR, low); | 293 | apic_write(APIC_ICR, low); |
294 | local_irq_restore(flags); | ||
288 | } | 295 | } |
289 | 296 | ||
290 | u64 native_apic_icr_read(void) | 297 | u64 native_apic_icr_read(void) |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 2c621a6b901a..7c1b29479513 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -198,7 +198,7 @@ static struct apic apic_flat = { | |||
198 | 198 | ||
199 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 199 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
200 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 200 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
201 | .wait_for_init_deassert = NULL, | 201 | .wait_for_init_deassert = false, |
202 | .smp_callin_clear_local_apic = NULL, | 202 | .smp_callin_clear_local_apic = NULL, |
203 | .inquire_remote_apic = default_inquire_remote_apic, | 203 | .inquire_remote_apic = default_inquire_remote_apic, |
204 | 204 | ||
@@ -314,7 +314,7 @@ static struct apic apic_physflat = { | |||
314 | 314 | ||
315 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 315 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
316 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 316 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
317 | .wait_for_init_deassert = NULL, | 317 | .wait_for_init_deassert = false, |
318 | .smp_callin_clear_local_apic = NULL, | 318 | .smp_callin_clear_local_apic = NULL, |
319 | .inquire_remote_apic = default_inquire_remote_apic, | 319 | .inquire_remote_apic = default_inquire_remote_apic, |
320 | 320 | ||
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 191ce75c0e54..8c7c98249c20 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
@@ -172,8 +172,7 @@ struct apic apic_noop = { | |||
172 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 172 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
173 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 173 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
174 | 174 | ||
175 | .wait_for_init_deassert = NULL, | 175 | .wait_for_init_deassert = false, |
176 | |||
177 | .smp_callin_clear_local_apic = NULL, | 176 | .smp_callin_clear_local_apic = NULL, |
178 | .inquire_remote_apic = NULL, | 177 | .inquire_remote_apic = NULL, |
179 | 178 | ||
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 3e67f9e3d7ef..a5b45df8bc88 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -248,7 +248,7 @@ static const struct apic apic_numachip __refconst = { | |||
248 | .wakeup_secondary_cpu = numachip_wakeup_secondary, | 248 | .wakeup_secondary_cpu = numachip_wakeup_secondary, |
249 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 249 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
250 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 250 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
251 | .wait_for_init_deassert = NULL, | 251 | .wait_for_init_deassert = false, |
252 | .smp_callin_clear_local_apic = NULL, | 252 | .smp_callin_clear_local_apic = NULL, |
253 | .inquire_remote_apic = NULL, /* REMRD not supported */ | 253 | .inquire_remote_apic = NULL, /* REMRD not supported */ |
254 | 254 | ||
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index d50e3640d5ae..e4840aa7a255 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -199,8 +199,7 @@ static struct apic apic_bigsmp = { | |||
199 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 199 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
200 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 200 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
201 | 201 | ||
202 | .wait_for_init_deassert = default_wait_for_init_deassert, | 202 | .wait_for_init_deassert = true, |
203 | |||
204 | .smp_callin_clear_local_apic = NULL, | 203 | .smp_callin_clear_local_apic = NULL, |
205 | .inquire_remote_apic = default_inquire_remote_apic, | 204 | .inquire_remote_apic = default_inquire_remote_apic, |
206 | 205 | ||
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index c55224731b2d..6f8f8b348a39 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -394,12 +394,6 @@ static void es7000_enable_apic_mode(void) | |||
394 | WARN(1, "Command failed, status = %x\n", mip_status); | 394 | WARN(1, "Command failed, status = %x\n", mip_status); |
395 | } | 395 | } |
396 | 396 | ||
397 | static void es7000_wait_for_init_deassert(atomic_t *deassert) | ||
398 | { | ||
399 | while (!atomic_read(deassert)) | ||
400 | cpu_relax(); | ||
401 | } | ||
402 | |||
403 | static unsigned int es7000_get_apic_id(unsigned long x) | 397 | static unsigned int es7000_get_apic_id(unsigned long x) |
404 | { | 398 | { |
405 | return (x >> 24) & 0xFF; | 399 | return (x >> 24) & 0xFF; |
@@ -658,8 +652,7 @@ static struct apic __refdata apic_es7000_cluster = { | |||
658 | .trampoline_phys_low = 0x467, | 652 | .trampoline_phys_low = 0x467, |
659 | .trampoline_phys_high = 0x469, | 653 | .trampoline_phys_high = 0x469, |
660 | 654 | ||
661 | .wait_for_init_deassert = NULL, | 655 | .wait_for_init_deassert = false, |
662 | |||
663 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ | 656 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ |
664 | .smp_callin_clear_local_apic = NULL, | 657 | .smp_callin_clear_local_apic = NULL, |
665 | .inquire_remote_apic = default_inquire_remote_apic, | 658 | .inquire_remote_apic = default_inquire_remote_apic, |
@@ -722,8 +715,7 @@ static struct apic __refdata apic_es7000 = { | |||
722 | .trampoline_phys_low = 0x467, | 715 | .trampoline_phys_low = 0x467, |
723 | .trampoline_phys_high = 0x469, | 716 | .trampoline_phys_high = 0x469, |
724 | 717 | ||
725 | .wait_for_init_deassert = es7000_wait_for_init_deassert, | 718 | .wait_for_init_deassert = true, |
726 | |||
727 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ | 719 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ |
728 | .smp_callin_clear_local_apic = NULL, | 720 | .smp_callin_clear_local_apic = NULL, |
729 | .inquire_remote_apic = default_inquire_remote_apic, | 721 | .inquire_remote_apic = default_inquire_remote_apic, |
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 1e42e8f305ee..030ea1c04f72 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -505,8 +505,7 @@ static struct apic __refdata apic_numaq = { | |||
505 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, | 505 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, |
506 | 506 | ||
507 | /* We don't do anything here because we use NMI's to boot instead */ | 507 | /* We don't do anything here because we use NMI's to boot instead */ |
508 | .wait_for_init_deassert = NULL, | 508 | .wait_for_init_deassert = false, |
509 | |||
510 | .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, | 509 | .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, |
511 | .inquire_remote_apic = NULL, | 510 | .inquire_remote_apic = NULL, |
512 | 511 | ||
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index eb35ef9ee63f..cceb352c968c 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -119,8 +119,7 @@ static struct apic apic_default = { | |||
119 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 119 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
120 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 120 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
121 | 121 | ||
122 | .wait_for_init_deassert = default_wait_for_init_deassert, | 122 | .wait_for_init_deassert = true, |
123 | |||
124 | .smp_callin_clear_local_apic = NULL, | 123 | .smp_callin_clear_local_apic = NULL, |
125 | .inquire_remote_apic = default_inquire_remote_apic, | 124 | .inquire_remote_apic = default_inquire_remote_apic, |
126 | 125 | ||
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 00146f9b0254..b656128611cd 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -532,8 +532,7 @@ static struct apic apic_summit = { | |||
532 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 532 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
533 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 533 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
534 | 534 | ||
535 | .wait_for_init_deassert = default_wait_for_init_deassert, | 535 | .wait_for_init_deassert = true, |
536 | |||
537 | .smp_callin_clear_local_apic = NULL, | 536 | .smp_callin_clear_local_apic = NULL, |
538 | .inquire_remote_apic = default_inquire_remote_apic, | 537 | .inquire_remote_apic = default_inquire_remote_apic, |
539 | 538 | ||
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index cac85ee6913f..e66766bf1641 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -279,7 +279,7 @@ static struct apic apic_x2apic_cluster = { | |||
279 | 279 | ||
280 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 280 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
281 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 281 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
282 | .wait_for_init_deassert = NULL, | 282 | .wait_for_init_deassert = false, |
283 | .smp_callin_clear_local_apic = NULL, | 283 | .smp_callin_clear_local_apic = NULL, |
284 | .inquire_remote_apic = NULL, | 284 | .inquire_remote_apic = NULL, |
285 | 285 | ||
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index de231e328cae..6d600ebf6c12 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
@@ -133,7 +133,7 @@ static struct apic apic_x2apic_phys = { | |||
133 | 133 | ||
134 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 134 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
135 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 135 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
136 | .wait_for_init_deassert = NULL, | 136 | .wait_for_init_deassert = false, |
137 | .smp_callin_clear_local_apic = NULL, | 137 | .smp_callin_clear_local_apic = NULL, |
138 | .inquire_remote_apic = NULL, | 138 | .inquire_remote_apic = NULL, |
139 | 139 | ||
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d263b1307de1..7834389ba5be 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -396,7 +396,7 @@ static struct apic __refdata apic_x2apic_uv_x = { | |||
396 | .wakeup_secondary_cpu = uv_wakeup_secondary, | 396 | .wakeup_secondary_cpu = uv_wakeup_secondary, |
397 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 397 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
398 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 398 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
399 | .wait_for_init_deassert = NULL, | 399 | .wait_for_init_deassert = false, |
400 | .smp_callin_clear_local_apic = NULL, | 400 | .smp_callin_clear_local_apic = NULL, |
401 | .inquire_remote_apic = NULL, | 401 | .inquire_remote_apic = NULL, |
402 | 402 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a32da804252e..60179ec39d4c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -122,8 +122,9 @@ static void smp_callin(void) | |||
122 | * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. | 122 | * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. |
123 | */ | 123 | */ |
124 | cpuid = smp_processor_id(); | 124 | cpuid = smp_processor_id(); |
125 | if (apic->wait_for_init_deassert && cpuid != 0) | 125 | if (apic->wait_for_init_deassert && cpuid) |
126 | apic->wait_for_init_deassert(&init_deasserted); | 126 | while (!atomic_read(&init_deasserted)) |
127 | cpu_relax(); | ||
127 | 128 | ||
128 | /* | 129 | /* |
129 | * (This works even if the APIC is not enabled.) | 130 | * (This works even if the APIC is not enabled.) |
@@ -701,11 +702,15 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, | |||
701 | int id; | 702 | int id; |
702 | int boot_error; | 703 | int boot_error; |
703 | 704 | ||
705 | preempt_disable(); | ||
706 | |||
704 | /* | 707 | /* |
705 | * Wake up AP by INIT, INIT, STARTUP sequence. | 708 | * Wake up AP by INIT, INIT, STARTUP sequence. |
706 | */ | 709 | */ |
707 | if (cpu) | 710 | if (cpu) { |
708 | return wakeup_secondary_cpu_via_init(apicid, start_ip); | 711 | boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); |
712 | goto out; | ||
713 | } | ||
709 | 714 | ||
710 | /* | 715 | /* |
711 | * Wake up BSP by nmi. | 716 | * Wake up BSP by nmi. |
@@ -725,6 +730,9 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, | |||
725 | boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); | 730 | boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); |
726 | } | 731 | } |
727 | 732 | ||
733 | out: | ||
734 | preempt_enable(); | ||
735 | |||
728 | return boot_error; | 736 | return boot_error; |
729 | } | 737 | } |
730 | 738 | ||