From d062ad2be5df7d43c186426927380b07c1059695 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 Jul 2026 11:48:57 +0200 Subject: [PATCH 1/3] Fix implicit_provenance_casts warnings on Xous --- library/std/src/os/xous/ffi.rs | 18 +++++++++--------- library/std/src/sys/thread/xous.rs | 4 ++-- library/std/src/sys/thread_local/key/xous.rs | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs index 9394f0a0496b2..e91b11cf17eec 100644 --- a/library/std/src/os/xous/ffi.rs +++ b/library/std/src/os/xous/ffi.rs @@ -24,7 +24,7 @@ fn lend_mut_impl( let mut a1: usize = connection.try_into().unwrap(); let mut a2 = InvokeType::LendMut as usize; let a3 = opcode; - let a4 = data.as_mut_ptr() as usize; + let a4 = data.as_mut_ptr().expose_provenance(); let a5 = data.len(); let a6 = arg1; let a7 = arg2; @@ -86,7 +86,7 @@ fn lend_impl( let a1: usize = connection.try_into().unwrap(); let a2 = InvokeType::Lend as usize; let a3 = opcode; - let a4 = data.as_ptr() as usize; + let a4 = data.as_ptr().expose_provenance(); let a5 = data.len(); let a6 = arg1; let a7 = arg2; @@ -360,14 +360,14 @@ pub(crate) fn do_yield() { /// the kernel will return an alias to the existing range. This violates Rust's /// pointer uniqueness guarantee. pub(crate) unsafe fn map_memory( - phys: Option>, + phys: Option, virt: Option>, count: usize, flags: MemoryFlags, ) -> Result<&'static mut [T], Error> { let mut a0 = Syscall::MapMemory as usize; - let mut a1 = phys.map(|p| p.as_ptr() as usize).unwrap_or_default(); - let mut a2 = virt.map(|p| p.as_ptr() as usize).unwrap_or_default(); + let mut a1 = phys.map_or(0, |p| p.get()); + let mut a2 = virt.map_or(0, |p| p.as_ptr().expose_provenance()); let a3 = count * size_of::(); let a4 = flags.bits(); let a5 = 0; @@ -408,7 +408,7 @@ pub(crate) unsafe fn map_memory( /// function returns, even if this function returns Err(). pub(crate) unsafe fn unmap_memory(range: *mut [T]) -> Result<(), Error> { let mut a0 = Syscall::UnmapMemory as usize; - let mut a1 = range.as_mut_ptr() as usize; + let mut a1 = range.as_mut_ptr().expose_provenance(); let a2 = range.len() * size_of::(); let a3 = 0; let a4 = 0; @@ -454,7 +454,7 @@ pub(crate) unsafe fn update_memory_flags( new_flags: MemoryFlags, ) -> Result<(), Error> { let mut a0 = Syscall::UpdateMemoryFlags as usize; - let mut a1 = range.as_mut_ptr() as usize; + let mut a1 = range.as_mut_ptr().expose_provenance(); let a2 = range.len() * size_of::(); let a3 = new_flags.bits(); let a4 = 0; // Process ID is currently None @@ -497,8 +497,8 @@ pub(crate) fn create_thread( arg3: usize, ) -> Result { let mut a0 = Syscall::CreateThread as usize; - let mut a1 = start as usize; - let a2 = stack.as_mut_ptr() as usize; + let mut a1 = start.expose_provenance(); + let a2 = stack.as_mut_ptr().expose_provenance(); let a3 = stack.len(); let a4 = arg0; let a5 = arg1; diff --git a/library/std/src/sys/thread/xous.rs b/library/std/src/sys/thread/xous.rs index 208d43bb2c065..1a32d87ed7162 100644 --- a/library/std/src/sys/thread/xous.rs +++ b/library/std/src/sys/thread/xous.rs @@ -58,11 +58,11 @@ impl Thread { .map_err(|code| io::Error::from_raw_os_error(code as i32))? }; - let guard_page_pre = stack_plus_guard_pages.as_ptr() as usize; + let guard_page_pre = stack_plus_guard_pages.as_ptr().expose_provenance(); let tid = create_thread( thread_start as *mut usize, &mut stack_plus_guard_pages[GUARD_PAGE_SIZE..(stack_size + GUARD_PAGE_SIZE)], - data as usize, + data.expose_provenance(), guard_page_pre, stack_size, 0, diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs index 5d9b71dd8a914..a37808a2d7824 100644 --- a/library/std/src/sys/thread_local/key/xous.rs +++ b/library/std/src/sys/thread_local/key/xous.rs @@ -97,7 +97,7 @@ fn tls_table() -> &'static mut [*mut u8] { fn tls_table_slow() -> &'static mut [*mut u8] { // If the TP register is `0`, then this thread hasn't initialized // its TLS yet. Allocate a new page to store this memory. - let tp = unsafe { + let tp: &mut [*mut u8] = unsafe { map_memory( None, None, @@ -108,14 +108,14 @@ fn tls_table_slow() -> &'static mut [*mut u8] { }; for val in tp.iter() { - assert!(*val as usize == 0); + assert!((*val).is_null()); } unsafe { // Set the thread's `$tp` register asm!( "mv tp, {}", - in(reg) tp.as_mut_ptr() as usize, + in(reg) tp.as_mut_ptr().expose_provenance(), ); } tp From d3e8e6b450b11d5e268bb9a585c0c38947b1a378 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 20 Jul 2026 16:13:20 +0200 Subject: [PATCH 2/3] Get rid of expose_provenance on Xous In favor of passing raw pointers to inline asm. --- library/std/src/os/xous/ffi.rs | 50 +++++++++++--------- library/std/src/sys/thread/xous.rs | 6 +-- library/std/src/sys/thread_local/key/xous.rs | 6 +-- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs index e91b11cf17eec..e5938b7bddb53 100644 --- a/library/std/src/os/xous/ffi.rs +++ b/library/std/src/os/xous/ffi.rs @@ -24,7 +24,7 @@ fn lend_mut_impl( let mut a1: usize = connection.try_into().unwrap(); let mut a2 = InvokeType::LendMut as usize; let a3 = opcode; - let a4 = data.as_mut_ptr().expose_provenance(); + let a4 = data.as_mut_ptr(); let a5 = data.len(); let a6 = arg1; let a7 = arg2; @@ -86,7 +86,7 @@ fn lend_impl( let a1: usize = connection.try_into().unwrap(); let a2 = InvokeType::Lend as usize; let a3 = opcode; - let a4 = data.as_ptr().expose_provenance(); + let a4 = data.as_ptr(); let a5 = data.len(); let a6 = arg1; let a7 = arg2; @@ -366,8 +366,10 @@ pub(crate) unsafe fn map_memory( flags: MemoryFlags, ) -> Result<&'static mut [T], Error> { let mut a0 = Syscall::MapMemory as usize; - let mut a1 = phys.map_or(0, |p| p.get()); - let mut a2 = virt.map_or(0, |p| p.as_ptr().expose_provenance()); + let a1 = phys.map_or(0, |p| p.get()); + let a1_out: *mut T; + let a2 = virt.map_or(core::ptr::null(), |p| p.as_ptr()); + let a2_out: usize; let a3 = count * size_of::(); let a4 = flags.bits(); let a5 = 0; @@ -378,8 +380,8 @@ pub(crate) unsafe fn map_memory( core::arch::asm!( "ecall", inlateout("a0") a0, - inlateout("a1") a1, - inlateout("a2") a2, + inlateout("a1") a1 => a1_out, + inlateout("a2") a2 => a2_out, inlateout("a3") a3 => _, inlateout("a4") a4 => _, inlateout("a5") a5 => _, @@ -391,12 +393,12 @@ pub(crate) unsafe fn map_memory( let result = a0; if result == SyscallResult::MemoryRange as usize { - let start = core::ptr::with_exposed_provenance_mut::(a1); - let len = a2 / size_of::(); + let start = a1_out; + let len = a2_out / size_of::(); let end = unsafe { start.add(len) }; Ok(unsafe { core::slice::from_raw_parts_mut(start, len) }) } else if result == SyscallResult::Error as usize { - Err(a1.into()) + Err(a1_out.addr().into()) } else { Err(Error::InternalError) } @@ -408,7 +410,7 @@ pub(crate) unsafe fn map_memory( /// function returns, even if this function returns Err(). pub(crate) unsafe fn unmap_memory(range: *mut [T]) -> Result<(), Error> { let mut a0 = Syscall::UnmapMemory as usize; - let mut a1 = range.as_mut_ptr().expose_provenance(); + let mut a1 = range.as_mut_ptr(); let a2 = range.len() * size_of::(); let a3 = 0; let a4 = 0; @@ -435,7 +437,7 @@ pub(crate) unsafe fn unmap_memory(range: *mut [T]) -> Result<(), Error> { if result == SyscallResult::Ok as usize { Ok(()) } else if result == SyscallResult::Error as usize { - Err(a1.into()) + Err(a1.addr().into()) } else { Err(Error::InternalError) } @@ -454,7 +456,8 @@ pub(crate) unsafe fn update_memory_flags( new_flags: MemoryFlags, ) -> Result<(), Error> { let mut a0 = Syscall::UpdateMemoryFlags as usize; - let mut a1 = range.as_mut_ptr().expose_provenance(); + let a1 = range.as_mut_ptr(); + let a1_out: usize; let a2 = range.len() * size_of::(); let a3 = new_flags.bits(); let a4 = 0; // Process ID is currently None @@ -466,7 +469,7 @@ pub(crate) unsafe fn update_memory_flags( core::arch::asm!( "ecall", inlateout("a0") a0, - inlateout("a1") a1, + inlateout("a1") a1 => a1_out, inlateout("a2") a2 => _, inlateout("a3") a3 => _, inlateout("a4") a4 => _, @@ -481,24 +484,25 @@ pub(crate) unsafe fn update_memory_flags( if result == SyscallResult::Ok as usize { Ok(()) } else if result == SyscallResult::Error as usize { - Err(a1.into()) + Err(a1_out.into()) } else { Err(Error::InternalError) } } /// Creates a thread with a given stack and up to four arguments. -pub(crate) fn create_thread( - start: *mut usize, +pub(crate) fn create_thread( + start: extern "C" fn(*mut usize, usize, usize) -> !, stack: *mut [u8], - arg0: usize, - arg1: usize, + arg0: *mut T, + arg1: *const u8, arg2: usize, arg3: usize, ) -> Result { let mut a0 = Syscall::CreateThread as usize; - let mut a1 = start.expose_provenance(); - let a2 = stack.as_mut_ptr().expose_provenance(); + let a1 = start; + let a1_out: usize; + let a2 = stack.as_mut_ptr(); let a3 = stack.len(); let a4 = arg0; let a5 = arg1; @@ -509,7 +513,7 @@ pub(crate) fn create_thread( core::arch::asm!( "ecall", inlateout("a0") a0, - inlateout("a1") a1, + inlateout("a1") a1 => a1_out, inlateout("a2") a2 => _, inlateout("a3") a3 => _, inlateout("a4") a4 => _, @@ -522,9 +526,9 @@ pub(crate) fn create_thread( let result = a0; if result == SyscallResult::ThreadId as usize { - Ok(a1.into()) + Ok(a1_out.into()) } else if result == SyscallResult::Error as usize { - Err(a1.into()) + Err(a1_out.into()) } else { Err(Error::InternalError) } diff --git a/library/std/src/sys/thread/xous.rs b/library/std/src/sys/thread/xous.rs index 1a32d87ed7162..002d1012d5604 100644 --- a/library/std/src/sys/thread/xous.rs +++ b/library/std/src/sys/thread/xous.rs @@ -58,11 +58,11 @@ impl Thread { .map_err(|code| io::Error::from_raw_os_error(code as i32))? }; - let guard_page_pre = stack_plus_guard_pages.as_ptr().expose_provenance(); + let guard_page_pre = stack_plus_guard_pages.as_ptr(); let tid = create_thread( - thread_start as *mut usize, + thread_start, &mut stack_plus_guard_pages[GUARD_PAGE_SIZE..(stack_size + GUARD_PAGE_SIZE)], - data.expose_provenance(), + data, guard_page_pre, stack_size, 0, diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs index a37808a2d7824..394d1b08ece3a 100644 --- a/library/std/src/sys/thread_local/key/xous.rs +++ b/library/std/src/sys/thread_local/key/xous.rs @@ -70,14 +70,14 @@ unsafe extern "Rust" { #[inline] fn tls_ptr_addr() -> *mut *mut u8 { - let mut tp: usize; + let tp: *mut *mut u8; unsafe { asm!( "mv {}, tp", out(reg) tp, ); } - core::ptr::with_exposed_provenance_mut::<*mut u8>(tp) + tp } /// Creates an area of memory that's unique per thread. This area will @@ -115,7 +115,7 @@ fn tls_table_slow() -> &'static mut [*mut u8] { // Set the thread's `$tp` register asm!( "mv tp, {}", - in(reg) tp.as_mut_ptr().expose_provenance(), + in(reg) tp.as_mut_ptr(), ); } tp From 7b0af9269df25e0268493f3da9bb585c42115350 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:35:51 +0200 Subject: [PATCH 3/3] Review comments --- library/std/src/os/xous/ffi.rs | 6 ++++-- library/std/src/sys/thread/xous.rs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs index e5938b7bddb53..8a499446e98d0 100644 --- a/library/std/src/os/xous/ffi.rs +++ b/library/std/src/os/xous/ffi.rs @@ -359,6 +359,8 @@ pub(crate) fn do_yield() { /// This function is safe unless a virtual address is specified. In that case, /// the kernel will return an alias to the existing range. This violates Rust's /// pointer uniqueness guarantee. +// The phys argument uses an integer rather than pointer type as pointer +// provenance only covers virtual memory, not physical memory. pub(crate) unsafe fn map_memory( phys: Option, virt: Option>, @@ -491,8 +493,8 @@ pub(crate) unsafe fn update_memory_flags( } /// Creates a thread with a given stack and up to four arguments. -pub(crate) fn create_thread( - start: extern "C" fn(*mut usize, usize, usize) -> !, +pub(crate) unsafe fn create_thread( + start: unsafe extern "C" fn(*mut usize, usize, usize) -> !, stack: *mut [u8], arg0: *mut T, arg1: *const u8, diff --git a/library/std/src/sys/thread/xous.rs b/library/std/src/sys/thread/xous.rs index 002d1012d5604..3ddd45851dde2 100644 --- a/library/std/src/sys/thread/xous.rs +++ b/library/std/src/sys/thread/xous.rs @@ -75,7 +75,7 @@ impl Thread { rust_start(); } - extern "C" fn thread_start( + unsafe extern "C" fn thread_start( data: *mut usize, guard_page_pre: usize, stack_size: usize,