rp/multicore: fix undefined behavior in multicore spawn.

It is UB to pass `entry` to core1 as `&mut`, because core0 keeps
an aliasing pointer to that memory region, and actually writes to
it (when `spawn_core1` returns, the stack frame gets deallocated and the memory
gets reused). This violates noalias requirements.

Added the fence just in case, een though it works without.
This commit is contained in:
Dario Nieuwenhuis 2023-05-16 01:21:28 +02:00
parent 1a87f7477a
commit 0c18a13cc0

View File

@ -122,11 +122,16 @@ where
extern "C" fn core1_startup<F: FnOnce() -> bad::Never>(
_: u64,
_: u64,
entry: &mut ManuallyDrop<F>,
entry: *mut ManuallyDrop<F>,
stack_bottom: *mut usize,
) -> ! {
core1_setup(stack_bottom);
let entry = unsafe { ManuallyDrop::take(entry) };
let entry = unsafe { ManuallyDrop::take(&mut *entry) };
// make sure the preceding read doesn't get reordered past the following fifo write
compiler_fence(Ordering::SeqCst);
// Signal that it's safe for core 0 to get rid of the original value now.
fifo_write(1);
@ -164,7 +169,7 @@ where
// Push `entry`.
stack_ptr = stack_ptr.sub(1);
stack_ptr.cast::<&mut ManuallyDrop<F>>().write(&mut entry);
stack_ptr.cast::<*mut ManuallyDrop<F>>().write(&mut entry);
}
// Make sure the compiler does not reorder the stack writes after to after the