Change IPC to have kernel keep track of source

This commit is contained in:
pjht 2024-11-25 10:32:08 -06:00
parent ef81ca1a6c
commit 87df5e76f2
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
2 changed files with 40 additions and 25 deletions

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
bootinfo::BOOTINFO, bootinfo::BOOTINFO,
print, println, print, println,
tasking::{InvalidPid, SleepReason}, tasking::{InvalidPid, IpcMessage, SleepReason},
virtual_memory::{ASpaceMutex, AddressSpace, PagingError, ACTIVE_SPACE, KERNEL_SPACE}, virtual_memory::{ASpaceMutex, AddressSpace, PagingError, ACTIVE_SPACE, KERNEL_SPACE},
TASKING, TASKING,
}; };
@ -163,7 +163,13 @@ pub fn send_ipc_to(
pid: usize, pid: usize,
buffer: Box<[u8], &'static ASpaceMutex>, buffer: Box<[u8], &'static ASpaceMutex>,
len: usize, len: usize,
from_kernel: bool,
) -> Result<(), SendIpcError> { ) -> Result<(), SendIpcError> {
let from = if from_kernel {
usize::MAX
} else {
TASKING.current_pid().unwrap()
};
#[cfg(feature = "log-rpc")] #[cfg(feature = "log-rpc")]
{ {
#[expect( #[expect(
@ -185,13 +191,14 @@ pub fn send_ipc_to(
clippy::arithmetic_side_effects, clippy::arithmetic_side_effects,
reason = "Can't overflow, as padded_len is no more than 4096 and 4096+24 < u32::MAX" 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(&[ SECOND_PORT.write_u32s(&[
0x3, // SPB type 0x3, // SPB type
total_len, // Total block length 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(&pid.to_ne_bytes());
SECOND_PORT.write_bytes(&from.to_ne_bytes());
#[expect( #[expect(
clippy::indexing_slicing, clippy::indexing_slicing,
reason = "The truncated length is always <= the buffer's length" reason = "The truncated length is always <= the buffer's length"
@ -225,7 +232,12 @@ pub fn send_ipc_to(
buffer buffer
}; };
let new_buffer_key = process.data_buffers().lock().insert(dest_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>(()) Ok::<_, PagingError>(())
})??; })??;
#[expect( #[expect(
@ -251,15 +263,13 @@ fn irq_handler(_stack_frame: InterruptStackFrame, index: u8, _error_code: Option
handler(irq_num, eoi_guard); handler(irq_num, eoi_guard);
} else if let Some(handler_task) = IRQ_TASKS.read()[usize(irq_num)] { } else if let Some(handler_task) = IRQ_TASKS.read()[usize(irq_num)] {
let pid = handler_task; let pid = handler_task;
let len: usize = 11; let mut buffer = Vec::new_in(&*ACTIVE_SPACE);
let rounded_size = len.next_multiple_of(4096); buffer.extend_from_slice(&2u16.to_le_bytes());
let mut buffer = Vec::with_capacity_in(rounded_size, &*ACTIVE_SPACE); buffer.push(irq_num);
buffer.resize(rounded_size, 0); let len = buffer.len();
let mut buffer = buffer.into_boxed_slice(); buffer.resize(len.next_multiple_of(4096), 0);
buffer[0..8].copy_from_slice(&u64::MAX.to_le_bytes()); let buffer = buffer.into_boxed_slice();
buffer[8..10].copy_from_slice(&2u16.to_le_bytes()); match send_ipc_to(pid, buffer, len, true) {
buffer[10] = irq_num;
match send_ipc_to(pid, buffer, len) {
Ok(()) => (), Ok(()) => (),
Err(SendIpcError::InvalidPid) => { Err(SendIpcError::InvalidPid) => {
IRQ_TASKS.write()[usize(irq_num)] = None; IRQ_TASKS.write()[usize(irq_num)] = None;
@ -394,6 +404,7 @@ extern "C" fn syscall_handler() {
let mut retval = 0; let mut retval = 0;
let mut retval2 = regs.rcx; let mut retval2 = regs.rcx;
let mut retval3 = regs.rdx; let mut retval3 = regs.rdx;
let mut retval4 = regs.rsi;
match regs.rax { match regs.rax {
0 => { 0 => {
let rval = if let Some(chr) = char::from_u32(regs.rcx.wrapping_cast()) { 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) { if let Some(buffer) = get_buffer(regs.rdx) {
let len = usize(regs.rsi); let len = usize(regs.rsi);
assert!(len <= buffer.len()); assert!(len <= buffer.len());
match send_ipc_to(pid, buffer, len) { match send_ipc_to(pid, buffer, len, false) {
Ok(()) => retval = 0, Ok(()) => retval = 0,
Err(e) => { Err(e) => {
println!("ipc_send: Error {e:?}"); println!("ipc_send: Error {e:?}");
@ -556,11 +567,12 @@ extern "C" fn syscall_handler() {
reason = "The message queue only contains valid buffer IDs" reason = "The message queue only contains valid buffer IDs"
)] )]
let buffer_addr = u64(TASKING 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()); .expose_provenance());
retval2 = u64(msg.1); retval2 = u64(msg.len);
retval = buffer_addr; retval = buffer_addr;
retval3 = u64(msg.0); retval3 = u64(msg.buffer_idx);
retval4 = u64(msg.from);
} else { } else {
retval = 0; retval = 0;
} }
@ -759,7 +771,6 @@ extern "C" fn syscall_handler() {
unsafe { unsafe {
asm!( asm!(
"mov rbx, [rip+SYSCALL_REGS+8]", "mov rbx, [rip+SYSCALL_REGS+8]",
"mov rsi, [rip+SYSCALL_REGS+32]",
"mov rdi, [rip+SYSCALL_REGS+40]", "mov rdi, [rip+SYSCALL_REGS+40]",
"mov rsp, [rip+SYSCALL_REGS+48]", "mov rsp, [rip+SYSCALL_REGS+48]",
"mov rbp, [rip+SYSCALL_REGS+56]", "mov rbp, [rip+SYSCALL_REGS+56]",
@ -772,7 +783,7 @@ extern "C" fn syscall_handler() {
"mov r14, [rip+SYSCALL_REGS+112]", "mov r14, [rip+SYSCALL_REGS+112]",
"mov r15, [rip+SYSCALL_REGS+120]", "mov r15, [rip+SYSCALL_REGS+120]",
"iretq", "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)
) )
} }
} }

View File

@ -92,10 +92,16 @@ pub struct Process {
kernel_esp_top: VirtAddr, kernel_esp_top: VirtAddr,
address_spaces: Mutex<Slab<AddressSpace>>, address_spaces: Mutex<Slab<AddressSpace>>,
data_buffers: Mutex<Slab<*mut [u8]>>, data_buffers: Mutex<Slab<*mut [u8]>>,
message_queue: Mutex<SegQueue<(usize, usize)>>, message_queue: Mutex<SegQueue<IpcMessage>>,
sleeping: RwLock<Option<SleepReason>>, sleeping: RwLock<Option<SleepReason>>,
} }
pub struct IpcMessage {
pub buffer_idx: usize,
pub len: usize,
pub from: usize,
}
impl Process { impl Process {
pub fn address_spaces(&self) -> &Mutex<Slab<AddressSpace>> { pub fn address_spaces(&self) -> &Mutex<Slab<AddressSpace>> {
&self.address_spaces &self.address_spaces
@ -105,7 +111,7 @@ impl Process {
&self.data_buffers &self.data_buffers
} }
pub fn message_queue(&self) -> &Mutex<SegQueue<(usize, usize)>> { pub fn message_queue(&self) -> &Mutex<SegQueue<IpcMessage>> {
&self.message_queue &self.message_queue
} }
@ -184,7 +190,6 @@ impl Tasking {
if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) { if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) {
let mut varint_buf = unsigned_varint::encode::u64_buffer(); let mut varint_buf = unsigned_varint::encode::u64_buffer();
let mut buffer = Vec::new_in(&*ACTIVE_SPACE); 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.extend_from_slice(&0u16.to_le_bytes());
buffer.push(0); buffer.push(0);
buffer.extend_from_slice(&0u64.to_le_bytes()); buffer.extend_from_slice(&0u64.to_le_bytes());
@ -207,7 +212,7 @@ impl Tasking {
clippy::expect_used, clippy::expect_used,
reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal." 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"); .expect("Failed to send exit message to proc_man");
} else { } else {
println!("[TASKING] No process manager when creating PID {pid}"); 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) { if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) {
let mut varint_buf = unsigned_varint::encode::u64_buffer(); let mut varint_buf = unsigned_varint::encode::u64_buffer();
let mut buffer = Vec::new_in(&*ACTIVE_SPACE); 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.extend_from_slice(&0u16.to_le_bytes());
buffer.push(0); buffer.push(0);
buffer.extend_from_slice(&0u64.to_le_bytes()); buffer.extend_from_slice(&0u64.to_le_bytes());
@ -307,7 +311,7 @@ impl Tasking {
clippy::expect_used, clippy::expect_used,
reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal." 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"); .expect("Failed to send exit message to proc_man");
} else { } else {
println!( println!(