When starting the other CPUs from the bootloader we did not wait for any

confirmation after sending off the startup IPIs. We simply moved on and setup
the temporary stack address for the next CPU to be started. With this it was
possible that the trampoline code did not manage to load the address before
we overwrote it. So for configurations with more than two CPUs it was possible
that two CPUs were setup to the same kernel stack which could have caused all
sorts of things - most likely a tripple fault and a reboot. On real hardware
this seems very unlikely but it was easily reproducible with QEMU and -smp >2.
We now use the shared trampoline stack to implement a notification mechanism.
The trampoline code will clear the stack location variable once it has loaded
everything it needs from the trampoline stack. On the other side
smp_boot_other_cpus() will wait for this variable to be cleared after it sent
the startup IPIs so that it knows when it can safely move on and overwrite the
area to boot the next CPU.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23800 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2008-01-31 22:15:52 +00:00
parent 8708a92e8d
commit 3fa048c0a6
2 changed files with 12 additions and 0 deletions

View File

@ -565,6 +565,13 @@ dprintf("wait for delivery\n");
while ((apic_read(APIC_INTR_COMMAND_1) & APIC_DELIVERY_STATUS) != 0)
asm volatile ("pause;");
}
// Wait for the trampoline code to clear the final stack location.
// This serves as a notification for us that it has loaded the address
// and it is safe for us to overwrite it to trampoline the next CPU.
tempStack++;
while (*tempStack != 0)
spin(1000);
}
TRACE(("done trampolining\n"));

View File

@ -47,6 +47,11 @@ trampoline_32:
movl %eax,%cr3 # set the page dir
popl %eax # get the final stack location
// Clear the final stack location to notify the startup code that
// we loaded the address and it is now safe to be overwritten.
pushl $0x00000000
movl %eax,%esp
// load an address for an indirect jump