Change IPC to have kernel keep track of source
This commit is contained in:
parent
ef81ca1a6c
commit
87df5e76f2
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
bootinfo::BOOTINFO,
|
||||
print, println,
|
||||
tasking::{InvalidPid, SleepReason},
|
||||
tasking::{InvalidPid, IpcMessage, SleepReason},
|
||||
virtual_memory::{ASpaceMutex, AddressSpace, PagingError, ACTIVE_SPACE, KERNEL_SPACE},
|
||||
TASKING,
|
||||
};
|
||||
@ -163,7 +163,13 @@ pub fn send_ipc_to(
|
||||
pid: usize,
|
||||
buffer: Box<[u8], &'static ASpaceMutex>,
|
||||
len: usize,
|
||||
from_kernel: bool,
|
||||
) -> Result<(), SendIpcError> {
|
||||
let from = if from_kernel {
|
||||
usize::MAX
|
||||
} else {
|
||||
TASKING.current_pid().unwrap()
|
||||
};
|
||||
#[cfg(feature = "log-rpc")]
|
||||
{
|
||||
#[expect(
|
||||
@ -185,13 +191,14 @@ pub fn send_ipc_to(
|
||||
clippy::arithmetic_side_effects,
|
||||
reason = "Can't overflow, as padded_len is no more than 4096 and 4096+24 < u32::MAX"
|
||||
)]
|
||||
let total_len = padded_len + 8 + (4 * 4);
|
||||
let total_len = padded_len + 16 + (4 * 4);
|
||||
SECOND_PORT.write_u32s(&[
|
||||
0x3, // SPB type
|
||||
total_len, // Total block length
|
||||
len.saturating_cast::<u32>().saturating_add(8), // Packet length
|
||||
len.saturating_cast::<u32>().saturating_add(16), // Packet length
|
||||
]);
|
||||
SECOND_PORT.write_bytes(&pid.to_ne_bytes());
|
||||
SECOND_PORT.write_bytes(&from.to_ne_bytes());
|
||||
#[expect(
|
||||
clippy::indexing_slicing,
|
||||
reason = "The truncated length is always <= the buffer's length"
|
||||
@ -225,7 +232,12 @@ pub fn send_ipc_to(
|
||||
buffer
|
||||
};
|
||||
let new_buffer_key = process.data_buffers().lock().insert(dest_buffer);
|
||||
process.message_queue().lock().push((new_buffer_key, len));
|
||||
let message = IpcMessage {
|
||||
buffer_idx: new_buffer_key,
|
||||
len,
|
||||
from,
|
||||
};
|
||||
process.message_queue().lock().push(message);
|
||||
Ok::<_, PagingError>(())
|
||||
})??;
|
||||
#[expect(
|
||||
@ -251,15 +263,13 @@ fn irq_handler(_stack_frame: InterruptStackFrame, index: u8, _error_code: Option
|
||||
handler(irq_num, eoi_guard);
|
||||
} else if let Some(handler_task) = IRQ_TASKS.read()[usize(irq_num)] {
|
||||
let pid = handler_task;
|
||||
let len: usize = 11;
|
||||
let rounded_size = len.next_multiple_of(4096);
|
||||
let mut buffer = Vec::with_capacity_in(rounded_size, &*ACTIVE_SPACE);
|
||||
buffer.resize(rounded_size, 0);
|
||||
let mut buffer = buffer.into_boxed_slice();
|
||||
buffer[0..8].copy_from_slice(&u64::MAX.to_le_bytes());
|
||||
buffer[8..10].copy_from_slice(&2u16.to_le_bytes());
|
||||
buffer[10] = irq_num;
|
||||
match send_ipc_to(pid, buffer, len) {
|
||||
let mut buffer = Vec::new_in(&*ACTIVE_SPACE);
|
||||
buffer.extend_from_slice(&2u16.to_le_bytes());
|
||||
buffer.push(irq_num);
|
||||
let len = buffer.len();
|
||||
buffer.resize(len.next_multiple_of(4096), 0);
|
||||
let buffer = buffer.into_boxed_slice();
|
||||
match send_ipc_to(pid, buffer, len, true) {
|
||||
Ok(()) => (),
|
||||
Err(SendIpcError::InvalidPid) => {
|
||||
IRQ_TASKS.write()[usize(irq_num)] = None;
|
||||
@ -394,6 +404,7 @@ extern "C" fn syscall_handler() {
|
||||
let mut retval = 0;
|
||||
let mut retval2 = regs.rcx;
|
||||
let mut retval3 = regs.rdx;
|
||||
let mut retval4 = regs.rsi;
|
||||
match regs.rax {
|
||||
0 => {
|
||||
let rval = if let Some(chr) = char::from_u32(regs.rcx.wrapping_cast()) {
|
||||
@ -535,7 +546,7 @@ extern "C" fn syscall_handler() {
|
||||
if let Some(buffer) = get_buffer(regs.rdx) {
|
||||
let len = usize(regs.rsi);
|
||||
assert!(len <= buffer.len());
|
||||
match send_ipc_to(pid, buffer, len) {
|
||||
match send_ipc_to(pid, buffer, len, false) {
|
||||
Ok(()) => retval = 0,
|
||||
Err(e) => {
|
||||
println!("ipc_send: Error {e:?}");
|
||||
@ -556,11 +567,12 @@ extern "C" fn syscall_handler() {
|
||||
reason = "The message queue only contains valid buffer IDs"
|
||||
)]
|
||||
let buffer_addr = u64(TASKING
|
||||
.current_process(|process| *process.data_buffers().lock().get(msg.0).unwrap())
|
||||
.current_process(|process| *process.data_buffers().lock().get(msg.buffer_idx).unwrap())
|
||||
.expose_provenance());
|
||||
retval2 = u64(msg.1);
|
||||
retval2 = u64(msg.len);
|
||||
retval = buffer_addr;
|
||||
retval3 = u64(msg.0);
|
||||
retval3 = u64(msg.buffer_idx);
|
||||
retval4 = u64(msg.from);
|
||||
} else {
|
||||
retval = 0;
|
||||
}
|
||||
@ -759,7 +771,6 @@ extern "C" fn syscall_handler() {
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov rbx, [rip+SYSCALL_REGS+8]",
|
||||
"mov rsi, [rip+SYSCALL_REGS+32]",
|
||||
"mov rdi, [rip+SYSCALL_REGS+40]",
|
||||
"mov rsp, [rip+SYSCALL_REGS+48]",
|
||||
"mov rbp, [rip+SYSCALL_REGS+56]",
|
||||
@ -772,7 +783,7 @@ extern "C" fn syscall_handler() {
|
||||
"mov r14, [rip+SYSCALL_REGS+112]",
|
||||
"mov r15, [rip+SYSCALL_REGS+120]",
|
||||
"iretq",
|
||||
in("rax") retval, in("rcx") retval2, in("rdx") retval3, options(noreturn)
|
||||
in("rax") retval, in("rcx") retval2, in("rdx") retval3, in("rsi") retval4, options(noreturn)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -92,10 +92,16 @@ pub struct Process {
|
||||
kernel_esp_top: VirtAddr,
|
||||
address_spaces: Mutex<Slab<AddressSpace>>,
|
||||
data_buffers: Mutex<Slab<*mut [u8]>>,
|
||||
message_queue: Mutex<SegQueue<(usize, usize)>>,
|
||||
message_queue: Mutex<SegQueue<IpcMessage>>,
|
||||
sleeping: RwLock<Option<SleepReason>>,
|
||||
}
|
||||
|
||||
pub struct IpcMessage {
|
||||
pub buffer_idx: usize,
|
||||
pub len: usize,
|
||||
pub from: usize,
|
||||
}
|
||||
|
||||
impl Process {
|
||||
pub fn address_spaces(&self) -> &Mutex<Slab<AddressSpace>> {
|
||||
&self.address_spaces
|
||||
@ -105,7 +111,7 @@ impl Process {
|
||||
&self.data_buffers
|
||||
}
|
||||
|
||||
pub fn message_queue(&self) -> &Mutex<SegQueue<(usize, usize)>> {
|
||||
pub fn message_queue(&self) -> &Mutex<SegQueue<IpcMessage>> {
|
||||
&self.message_queue
|
||||
}
|
||||
|
||||
@ -184,7 +190,6 @@ impl Tasking {
|
||||
if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) {
|
||||
let mut varint_buf = unsigned_varint::encode::u64_buffer();
|
||||
let mut buffer = Vec::new_in(&*ACTIVE_SPACE);
|
||||
buffer.extend_from_slice(&u64::MAX.to_le_bytes());
|
||||
buffer.extend_from_slice(&0u16.to_le_bytes());
|
||||
buffer.push(0);
|
||||
buffer.extend_from_slice(&0u64.to_le_bytes());
|
||||
@ -207,7 +212,7 @@ impl Tasking {
|
||||
clippy::expect_used,
|
||||
reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal."
|
||||
)]
|
||||
send_ipc_to(usize(proc_man_pid), buffer, len)
|
||||
send_ipc_to(usize(proc_man_pid), buffer, len, true)
|
||||
.expect("Failed to send exit message to proc_man");
|
||||
} else {
|
||||
println!("[TASKING] No process manager when creating PID {pid}");
|
||||
@ -289,7 +294,6 @@ impl Tasking {
|
||||
if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) {
|
||||
let mut varint_buf = unsigned_varint::encode::u64_buffer();
|
||||
let mut buffer = Vec::new_in(&*ACTIVE_SPACE);
|
||||
buffer.extend_from_slice(&u64::MAX.to_le_bytes());
|
||||
buffer.extend_from_slice(&0u16.to_le_bytes());
|
||||
buffer.push(0);
|
||||
buffer.extend_from_slice(&0u64.to_le_bytes());
|
||||
@ -307,7 +311,7 @@ impl Tasking {
|
||||
clippy::expect_used,
|
||||
reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal."
|
||||
)]
|
||||
send_ipc_to(usize(proc_man_pid), buffer, len)
|
||||
send_ipc_to(usize(proc_man_pid), buffer, len, true)
|
||||
.expect("Failed to send exit message to proc_man");
|
||||
} else {
|
||||
println!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user