aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorJan H. Schönherr <jschoenh@amazon.de>2015-05-04 05:42:34 -0400
committerIngo Molnar <mingo@kernel.org>2015-05-06 04:24:51 -0400
commitf5d6a52f511157c7476590532a23b5664b1ed877 (patch)
tree03795d9ff6c1f9656baf035ac5657231f5190a40 /arch/x86/kernel/smpboot.c
parent19e3d60d49f05a9de0ef06c60703f31d4acd5f17 (diff)
x86/smpboot: Skip delays during SMP initialization similar to Xen
Remove the per-CPU delays during SMP initialization, which seems to be possible on newer architectures with an x2APIC. Xen does this since 2011. In fact, this commit is basically a combination of the following Xen commits. The first removes the delays, the second fixes an issue with the removal: commit 68fce206f6dba9981e8322269db49692c95ce250 Author: Tim Deegan <Tim.Deegan@citrix.com> Date: Tue Jul 19 14:13:01 2011 +0100 x86: Remove timeouts from INIT-SIPI-SIPI sequence when using x2apic. Some of the timeouts are pointless since they're waiting for the ICR to ack the IPI delivery and that doesn't happen on x2apic. The others should be benign (and are suggested in the SDM) but removing them makes AP bringup much more reliable on some test boxes. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com> commit f12ee533150761df5a7099c83f2a5fa6c07d1187 Author: Gang Wei <gang.wei@intel.com> Date: Thu Dec 29 10:07:54 2011 +0000 X86: Add a delay between INIT & SIPIs for tboot AP bring-up in X2APIC case Without this delay, Xen could not bring APs up while working with TXT/tboot, because tboot needs some time in APs to handle INIT before becoming ready for receiving SIPIs (this delay was removed as part of c/s 23724 by Tim Deegan). Signed-off-by: Gang Wei <gang.wei@intel.com> Acked-by: Keir Fraser <keir@xen.org> Acked-by: Tim Deegan <tim@xen.org> Committed-by: Tim Deegan <tim@xen.org> Signed-off-by: Jan H. Schönherr <jschoenh@amazon.de> Cc: Anthony Liguori <aliguori@amazon.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Gang Wei <gang.wei@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Len Brown <len.brown@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tim Deegan <tim@xen.org> Link: http://lkml.kernel.org/r/1430732554-7294-1-git-send-email-jschoenh@amazon.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 50e547eac8cd..63b46414c80c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -555,7 +555,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip)
555static int 555static int
556wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) 556wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
557{ 557{
558 unsigned long send_status, accept_status = 0; 558 unsigned long send_status = 0, accept_status = 0;
559 int maxlvt, num_starts, j; 559 int maxlvt, num_starts, j;
560 560
561 maxlvt = lapic_get_maxlvt(); 561 maxlvt = lapic_get_maxlvt();
@@ -580,22 +580,34 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
580 apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT, 580 apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
581 phys_apicid); 581 phys_apicid);
582 582
583 pr_debug("Waiting for send to finish...\n"); 583 if (!cpu_has_x2apic) {
584 send_status = safe_apic_wait_icr_idle(); 584 pr_debug("Waiting for send to finish...\n");
585 send_status = safe_apic_wait_icr_idle();
585 586
586 mdelay(10); 587 mdelay(10);
587 588
588 pr_debug("Deasserting INIT\n"); 589 pr_debug("Deasserting INIT\n");
589 590
590 /* Target chip */ 591 /* Target chip */
591 /* Send IPI */ 592 /* Send IPI */
592 apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid); 593 apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
593 594
594 pr_debug("Waiting for send to finish...\n"); 595 pr_debug("Waiting for send to finish...\n");
595 send_status = safe_apic_wait_icr_idle(); 596 send_status = safe_apic_wait_icr_idle();
596 597
597 mb(); 598 mb();
598 atomic_set(&init_deasserted, 1); 599 atomic_set(&init_deasserted, 1);
600 } else if (tboot_enabled()) {
601 /*
602 * With tboot AP is actually spinning in a mini-guest before
603 * receiving INIT. Upon receiving INIT ipi, AP need time to
604 * VMExit, update VMCS to tracking SIPIs and VMResume.
605 *
606 * While AP is in root mode handling the INIT the CPU will drop
607 * any SIPIs
608 */
609 udelay(10);
610 }
599 611
600 /* 612 /*
601 * Should we send STARTUP IPIs ? 613 * Should we send STARTUP IPIs ?
@@ -637,20 +649,23 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
637 apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12), 649 apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
638 phys_apicid); 650 phys_apicid);
639 651
640 /* 652 if (!cpu_has_x2apic) {
641 * Give the other CPU some time to accept the IPI. 653 /*
642 */ 654 * Give the other CPU some time to accept the IPI.
643 udelay(300); 655 */
656 udelay(300);
644 657
645 pr_debug("Startup point 1\n"); 658 pr_debug("Startup point 1\n");
646 659
647 pr_debug("Waiting for send to finish...\n"); 660 pr_debug("Waiting for send to finish...\n");
648 send_status = safe_apic_wait_icr_idle(); 661 send_status = safe_apic_wait_icr_idle();
662
663 /*
664 * Give the other CPU some time to accept the IPI.
665 */
666 udelay(200);
667 }
649 668
650 /*
651 * Give the other CPU some time to accept the IPI.
652 */
653 udelay(200);
654 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ 669 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
655 apic_write(APIC_ESR, 0); 670 apic_write(APIC_ESR, 0);
656 accept_status = (apic_read(APIC_ESR) & 0xEF); 671 accept_status = (apic_read(APIC_ESR) & 0xEF);