xcp-1.6-updates/xen-4.1.hg

changeset 23215:2fb706161c09

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>
xen-unstable changeset: 23724:b3434f24b082
xen-unstable date: Tue Jul 19 14:13:01 2011 +0100

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>
xen-unstable changeset: 24447:a7b2610b8e5c
xen-unstable date: Thu Dec 29 10:07:54 2011 +0000
author Tim Deegan <Tim.Deegan@citrix.com>
date Tue Jan 17 11:30:37 2012 +0000 (2012-01-17)
parents e29b7691fefc
children c358c4213d23
files xen/arch/x86/smpboot.c
line diff
     1.1 --- a/xen/arch/x86/smpboot.c	Sun Jan 15 22:08:13 2012 +0000
     1.2 +++ b/xen/arch/x86/smpboot.c	Tue Jan 17 11:30:37 2012 +0000
     1.3 @@ -42,6 +42,7 @@
     1.4  #include <asm/msr.h>
     1.5  #include <asm/mtrr.h>
     1.6  #include <asm/time.h>
     1.7 +#include <asm/tboot.h>
     1.8  #include <mach_apic.h>
     1.9  #include <mach_wakecpu.h>
    1.10  #include <smpboot_hooks.h>
    1.11 @@ -445,29 +446,42 @@ static int wakeup_secondary_cpu(int phys
    1.12      apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
    1.13                     phys_apicid);
    1.14  
    1.15 -    Dprintk("Waiting for send to finish...\n");
    1.16 -    timeout = 0;
    1.17 -    do {
    1.18 -        Dprintk("+");
    1.19 -        udelay(100);
    1.20 -        if ( !x2apic_enabled )
    1.21 +    if ( !x2apic_enabled )
    1.22 +    {
    1.23 +        Dprintk("Waiting for send to finish...\n");
    1.24 +        timeout = 0;
    1.25 +        do {
    1.26 +            Dprintk("+");
    1.27 +            udelay(100);
    1.28              send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
    1.29 -    } while ( send_status && (timeout++ < 1000) );
    1.30 +        } while ( send_status && (timeout++ < 1000) );
    1.31 +
    1.32 +        mdelay(10);
    1.33  
    1.34 -    mdelay(10);
    1.35 +        Dprintk("Deasserting INIT.\n");
    1.36 +
    1.37 +        apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
    1.38  
    1.39 -    Dprintk("Deasserting INIT.\n");
    1.40 -
    1.41 -    apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
    1.42 -
    1.43 -    Dprintk("Waiting for send to finish...\n");
    1.44 -    timeout = 0;
    1.45 -    do {
    1.46 -        Dprintk("+");
    1.47 -        udelay(100);
    1.48 -        if ( !x2apic_enabled )
    1.49 +        Dprintk("Waiting for send to finish...\n");
    1.50 +        timeout = 0;
    1.51 +        do {
    1.52 +            Dprintk("+");
    1.53 +            udelay(100);
    1.54              send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
    1.55 -    } while ( send_status && (timeout++ < 1000) );
    1.56 +        } while ( send_status && (timeout++ < 1000) );
    1.57 +    }
    1.58 +    else if ( tboot_in_measured_env() )
    1.59 +    {
    1.60 +        /*
    1.61 +         * With tboot AP is actually spinning in a mini-guest before 
    1.62 +         * receiving INIT. Upon receiving INIT ipi, AP need time to VMExit, 
    1.63 +         * update VMCS to tracking SIPIs and VMResume.
    1.64 +         *
    1.65 +         * While AP is in root mode handling the INIT the CPU will drop
    1.66 +         * any SIPIs
    1.67 +         */
    1.68 +        udelay(10);
    1.69 +    }
    1.70  
    1.71      /*
    1.72       * Should we send STARTUP IPIs ?
    1.73 @@ -496,22 +510,24 @@ static int wakeup_secondary_cpu(int phys
    1.74           */
    1.75          apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12), phys_apicid);
    1.76  
    1.77 -        /* Give the other CPU some time to accept the IPI. */
    1.78 -        udelay(300);
    1.79 +        if ( !x2apic_enabled )
    1.80 +        {
    1.81 +            /* Give the other CPU some time to accept the IPI. */
    1.82 +            udelay(300);
    1.83  
    1.84 -        Dprintk("Startup point 1.\n");
    1.85 +            Dprintk("Startup point 1.\n");
    1.86  
    1.87 -        Dprintk("Waiting for send to finish...\n");
    1.88 -        timeout = 0;
    1.89 -        do {
    1.90 -            Dprintk("+");
    1.91 -            udelay(100);
    1.92 -            if ( !x2apic_enabled )
    1.93 -            send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
    1.94 -        } while ( send_status && (timeout++ < 1000) );
    1.95 +            Dprintk("Waiting for send to finish...\n");
    1.96 +            timeout = 0;
    1.97 +            do {
    1.98 +                Dprintk("+");
    1.99 +                udelay(100);
   1.100 +                send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
   1.101 +            } while ( send_status && (timeout++ < 1000) );
   1.102  
   1.103 -        /* Give the other CPU some time to accept the IPI. */
   1.104 -        udelay(200);
   1.105 +            /* Give the other CPU some time to accept the IPI. */
   1.106 +            udelay(200);
   1.107 +        }
   1.108  
   1.109          /* Due to the Pentium erratum 3AP. */
   1.110          if ( maxlvt > 3 )