Merge #1459
1459: rp/multicore: fix undefined behavior in multicore spawn. r=Dirbaio a=Dirbaio 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. bors r+ Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
commit
34a0c2172b
1 changed files with 8 additions and 3 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue