Critical: kernel_ref() UB eliminated
- kernel_ref() returned &'static mut, creating aliasing mutable
references across trap handler + boot code (13+ call sites)
- Replaced with kernel_ptr() -> *mut Kernel, each use site does
explicit unsafe { &mut *kernel_ptr() }
- KernelCell: removed get_mut(), added as_ptr() -> *mut T
- UB is gone: raw pointer access makes the single-core invariant
explicit at every use site
Important: process cleanup on exit/fault
- New destroy_process() method consolidates cleanup:
- Removes all threads from scheduler and endpoints
- Clears pending messages and results
- Destroys process and frees ProcessMemory
- handle_exit and handle_fault both use destroy_process()
- handle_exit_thread uses destroy_process when last thread exits
IPC hardening:
- Added invariant comment on pending_messages[sender].take()
(sender in wait queue must have a pending message)
handle_release_pages:
- Now uses translate_va to convert VA→PA (was treating VA as PA)
53 lines
2.0 KiB
Rust
53 lines
2.0 KiB
Rust
use platform::Platform;
|
|
|
|
use crate::Kernel;
|
|
|
|
impl<P: Platform> Kernel<P> {
|
|
pub fn handle_fault(
|
|
&mut self,
|
|
tid: types::id::ThreadId,
|
|
fault: domain::fault::Fault,
|
|
fault_pc: usize,
|
|
) {
|
|
let pid = match self.threads.get(tid) {
|
|
Ok(t) => t.process(),
|
|
Err(_) => return,
|
|
};
|
|
|
|
// Try to deliver fault to a fault handler endpoint (if configured)
|
|
if let Ok(process) = self.processes.get(pid) {
|
|
if let Some(handler_slot) = process.fault_handler() {
|
|
if let Ok(cap) = process.capabilities().get(handler_slot) {
|
|
if let domain::resource::Resource::Endpoint(ep_id) = cap.resource() {
|
|
let msg = domain::message::Message::from_words([
|
|
pid.raw() as usize,
|
|
fault.code(),
|
|
fault.address(),
|
|
fault_pc,
|
|
]);
|
|
|
|
if let Some(ep) = self.endpoints.get_mut(*ep_id) {
|
|
if ep.has_waiting_receiver() {
|
|
if let Some(receiver_tid) = ep.dequeue_receiver() {
|
|
self.pending_results[receiver_tid.raw() as usize] =
|
|
Some(crate::SyscallResult::Message(msg));
|
|
|
|
if let Ok(receiver) = self.threads.get_mut(receiver_tid) {
|
|
let priority = receiver.priority();
|
|
let _ = receiver.unblock();
|
|
let core = self.platform.core_id();
|
|
use domain::scheduler::Scheduler;
|
|
self.scheduler.add(receiver_tid, priority, core);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
self.destroy_process(pid);
|
|
}
|
|
}
|