diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 2d3a2fbd1..4b1497ac1 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -49,6 +49,7 @@ gdb-stub = ["gdbstub", "gdbstub_arch"] print-panics = [] report-memory = ["stats_alloc"] wrap-print = [] +big-heap = [] # Cause heaps to start at 12 MM instead of 512 kB v2p = ["xous-kernel/v2p"] # patches for simulation targets ONLY. Applying these flags will result in totally broken security. diff --git a/kernel/src/arch/riscv/mod.rs b/kernel/src/arch/riscv/mod.rs index fa97517a0..1c44c0c1b 100644 --- a/kernel/src/arch/riscv/mod.rs +++ b/kernel/src/arch/riscv/mod.rs @@ -10,8 +10,6 @@ pub mod panic; pub mod process; pub mod syscall; -pub use process::Thread; - #[cfg(any(feature = "precursor", feature = "renode"))] use crate::mem::MemoryManager; #[cfg(any(feature = "precursor", feature = "renode"))] diff --git a/kernel/src/arch/riscv/process.rs b/kernel/src/arch/riscv/process.rs index 28c4c939a..750dcbd0b 100644 --- a/kernel/src/arch/riscv/process.rs +++ b/kernel/src/arch/riscv/process.rs @@ -386,7 +386,7 @@ impl Process { } process.inner = Default::default(); - process.inner.pid = pid; + process.inner.pid = pid; // Mark the stack as "unallocated-but-free" let init_sp = (thread_init.stack.as_ptr() as usize) & !0xfff; @@ -414,11 +414,17 @@ impl Process { // Create the new context and set it to run in the new address space. let pid = self.pid.get(); let thread = self.thread_mut(new_tid); - // println!("Setting up thread {}, pid {}", new_tid, pid); let sp = setup.stack.as_ptr() as usize + setup.stack.len(); if sp <= 16 { return Err(xous_kernel::Error::BadAddress); } + // Zero out the thread registers, including special ones like `$tp`. + // This should already have been done by the destructor, but do it + // again anyway. + for val in &mut thread.registers { + *val = 0; + } + thread.sepc = 0; crate::arch::syscall::invoke( thread, pid == 1, diff --git a/kernel/src/mem.rs b/kernel/src/mem.rs index dd19ed165..5c38f90fe 100644 --- a/kernel/src/mem.rs +++ b/kernel/src/mem.rs @@ -451,7 +451,11 @@ impl MemoryManager { let virt = virt as *mut usize; // Zero-out the page - unsafe { virt.write_bytes(0, PAGE_SIZE / core::mem::size_of::()) }; + let range_start = virt; + let range_end = range_start.wrapping_add(PAGE_SIZE / core::mem::size_of::()); + unsafe { + crate::mem::bzero(range_start, range_end); + }; if is_user { crate::arch::mem::hand_page_to_user(virt as _)?; } @@ -739,9 +743,14 @@ impl MemoryManager { #[cfg(feature = "atsama5d27")] { let uart_base = crate::platform::atsama5d2::uart::HW_UART_BASE as usize; - if pid.get() != 1 && (addr == uart_base || addr == uart_base + 0x1000 || addr == uart_base + 0x2000 || addr == uart_base + 0x3000) { + if pid.get() != 1 + && (addr == uart_base + || addr == uart_base + 0x1000 + || addr == uart_base + 0x2000 + || addr == uart_base + 0x3000) + { klog!("[!] UART sharing workaround used for {:08x} address", addr); - return Ok(()) + return Ok(()); } } // ------------------------------- @@ -865,3 +874,14 @@ impl MemoryManager { Ok(()) } } + +pub unsafe fn bzero(mut start: *mut T, end: *mut T) +where + T: Copy, +{ + while start < end { + // NOTE(volatile) to prevent this from being transformed into `memclr` + core::ptr::write_volatile(start, core::mem::zeroed()); + start = start.offset(1); + } +} diff --git a/kernel/src/server.rs b/kernel/src/server.rs index f62220e10..104b0d03d 100644 --- a/kernel/src/server.rs +++ b/kernel/src/server.rs @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2020 Sean Cross // SPDX-License-Identifier: Apache-2.0 -pub use crate::arch::process::Thread; use crate::{mem::MemoryManager, services::SystemServices}; use core::mem; use xous_kernel::{MemoryAddress, MemoryRange, MemorySize, Message, MessageSender, PID, SID, TID}; diff --git a/kernel/src/services.rs b/kernel/src/services.rs index acd828aed..2042968e5 100644 --- a/kernel/src/services.rs +++ b/kernel/src/services.rs @@ -219,7 +219,11 @@ impl Default for ProcessInner { mem_message_last: arch::mem::DEFAULT_MESSAGE_BASE, mem_heap_base: arch::mem::DEFAULT_HEAP_BASE, mem_heap_size: 0, - mem_heap_max: 524_288, + mem_heap_max: if cfg!("big-heap") { + 1024 * 1024 * 12 + } else { + 1024 * 512 + }, connection_map: [None; 32], pid: unsafe { PID::new_unchecked(1) }, _reserved: [0; 1], diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index c08f9b14c..761b5fa46 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -475,9 +475,7 @@ fn return_result( return Err(xous_kernel::Error::DoubleFree); } WaitingMessage::MovedMemory => { - klog!( - "WARNING: Tried to wait on a scalar message that was actually moved memory" - ); + klog!("WARNING: Tried to wait on a scalar message that was actually moved memory"); return Err(xous_kernel::Error::DoubleFree); } WaitingMessage::None => { @@ -605,9 +603,7 @@ fn reply_and_receive_next( } } WaitingMessage::MovedMemory => { - klog!( - "WARNING: Tried to wait on a scalar message that was actually moved memory" - ); + klog!("WARNING: Tried to wait on a scalar message that was actually moved memory"); return Err(xous_kernel::Error::DoubleFree); } WaitingMessage::None => { @@ -745,12 +741,21 @@ fn receive_message(pid: PID, tid: TID, sid: SID, blocking: ExecutionType) -> Sys } pub fn handle(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallResult { - klog!("KERNEL({}:{}): Syscall {:x?}, in_irq={}", pid, tid, call, in_irq); + klog!( + "KERNEL({}:{}): Syscall {:x?}, in_irq={}", + pid, + tid, + call, + in_irq + ); // let call_string = format!("{:x?}", call); // let start_time = std::time::Instant::now(); #[allow(clippy::let_and_return)] let result = if in_irq && !call.can_call_from_interrupt() { - klog!("[!] Called {:?} that's cannot be called from the interrupt handler!", call); + klog!( + "[!] Called {:?} that's cannot be called from the interrupt handler!", + call + ); Err(xous_kernel::Error::InvalidSyscall) } else { handle_inner(pid, tid, in_irq, call) @@ -828,10 +833,11 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR if !phys_ptr.is_null() { if mm.is_main_memory(phys_ptr) { + let range_start = range.as_mut_ptr() as *mut usize; + let range_end = + range_start.wrapping_add(range.len() / core::mem::size_of::()); unsafe { - range - .as_mut_ptr() - .write_bytes(0, range.len() / core::mem::size_of::()) + crate::mem::bzero(range_start, range_end); }; } for offset in (range.as_ptr() as usize..(range.as_ptr() as usize + range.len()))