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:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user