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:
parent
8708a92e8d
commit
3fa048c0a6
@ -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"));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user