Change IPC to have kernel keep track of source
This commit is contained in:
parent
ef81ca1a6c
commit
87df5e76f2
@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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!(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user