mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/smpboot: Allow making an INIT IPI conditional
A subsequent change is going to introduce SKINIT support, wherein the APs will be already be in the wait-for-SIPI state, and an INIT must not be sent. Introduce a send_INIT boolean, so we can control sending an INIT IPI separately from sending SIPIs. No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
1 parent
dbfee5918c
commit
f31029cc73
1 file changed
+43
-39
+43
-39
@@ -424,6 +424,7 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||
{
|
||||
unsigned long send_status = 0, accept_status = 0;
|
||||
int maxlvt, timeout, i;
|
||||
bool send_INIT = true;
|
||||
|
||||
/*
|
||||
* Some versions of tboot might be able to handle the entire wake sequence
|
||||
@@ -438,49 +439,52 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||
apic_write(APIC_ESR, 0);
|
||||
apic_read(APIC_ESR);
|
||||
|
||||
Dprintk("Asserting INIT.\n");
|
||||
|
||||
/*
|
||||
* Turn INIT on target chip via IPI
|
||||
*/
|
||||
apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
|
||||
phys_apicid);
|
||||
|
||||
if ( !x2apic_enabled )
|
||||
if ( send_INIT )
|
||||
{
|
||||
Dprintk("Waiting for send to finish...\n");
|
||||
timeout = 0;
|
||||
do {
|
||||
Dprintk("+");
|
||||
udelay(100);
|
||||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while ( send_status && (timeout++ < 1000) );
|
||||
Dprintk("Asserting INIT.\n");
|
||||
|
||||
mdelay(10);
|
||||
|
||||
Dprintk("Deasserting INIT.\n");
|
||||
|
||||
apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
|
||||
|
||||
Dprintk("Waiting for send to finish...\n");
|
||||
timeout = 0;
|
||||
do {
|
||||
Dprintk("+");
|
||||
udelay(100);
|
||||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while ( send_status && (timeout++ < 1000) );
|
||||
}
|
||||
else if ( tboot_in_measured_env() )
|
||||
{
|
||||
/*
|
||||
* With tboot AP is actually spinning in a mini-guest before
|
||||
* receiving INIT. Upon receiving INIT ipi, AP need time to VMExit,
|
||||
* update VMCS to tracking SIPIs and VMResume.
|
||||
*
|
||||
* While AP is in root mode handling the INIT the CPU will drop
|
||||
* any SIPIs
|
||||
* Turn INIT on target chip via IPI
|
||||
*/
|
||||
udelay(10);
|
||||
apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
|
||||
phys_apicid);
|
||||
|
||||
if ( !x2apic_enabled )
|
||||
{
|
||||
Dprintk("Waiting for send to finish...\n");
|
||||
timeout = 0;
|
||||
do {
|
||||
Dprintk("+");
|
||||
udelay(100);
|
||||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while ( send_status && (timeout++ < 1000) );
|
||||
|
||||
mdelay(10);
|
||||
|
||||
Dprintk("Deasserting INIT.\n");
|
||||
|
||||
apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
|
||||
|
||||
Dprintk("Waiting for send to finish...\n");
|
||||
timeout = 0;
|
||||
do {
|
||||
Dprintk("+");
|
||||
udelay(100);
|
||||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while ( send_status && (timeout++ < 1000) );
|
||||
}
|
||||
else if ( tboot_in_measured_env() )
|
||||
{
|
||||
/*
|
||||
* With tboot AP is actually spinning in a mini-guest before
|
||||
* receiving INIT. Upon receiving INIT ipi, AP need time to VMExit,
|
||||
* update VMCS to tracking SIPIs and VMResume.
|
||||
*
|
||||
* While AP is in root mode handling the INIT the CPU will drop
|
||||
* any SIPIs
|
||||
*/
|
||||
udelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
maxlvt = get_maxlvt();
|
||||
|
||||