2024-03-11 09:48:56 -05:00
|
|
|
use {
|
2024-09-13 16:41:31 -05:00
|
|
|
crate::holeybytes::{kernel_services::block_read, Vm},
|
2024-09-16 14:15:51 -05:00
|
|
|
alloc::alloc::{alloc, dealloc},
|
2024-09-13 16:41:31 -05:00
|
|
|
core::alloc::Layout,
|
2024-05-04 12:41:47 -05:00
|
|
|
log::{debug, info},
|
2024-03-11 09:48:56 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
pub enum MemoryServiceError {
|
|
|
|
InvalidMemoryFormat,
|
|
|
|
}
|
2024-05-04 12:41:47 -05:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum MemoryQuotaType {
|
|
|
|
NoQuota = 0,
|
|
|
|
SoftQuota = 1,
|
|
|
|
HardQuota = 2,
|
|
|
|
KillQuota = 3,
|
|
|
|
}
|
2024-03-11 09:48:56 -05:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryServiceError> {
|
2024-10-19 13:45:41 -05:00
|
|
|
let ptr = unsafe { alloc(Layout::from_size_align_unchecked(4096, 8)) };
|
2024-09-13 16:41:31 -05:00
|
|
|
info!("Block address: {:?}", ptr);
|
|
|
|
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
2024-03-11 09:48:56 -05:00
|
|
|
vm.registers[2] = hbvm::value::Value(4096);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2024-10-14 12:54:53 -05:00
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) {
|
2024-10-19 13:45:41 -05:00
|
|
|
const BLOCK_SIZE: usize = 64;
|
2024-10-14 12:54:53 -05:00
|
|
|
let mut remaining = count * size;
|
|
|
|
|
|
|
|
if remaining < 16 {
|
|
|
|
src.copy_to_nonoverlapping(dest, remaining);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-10-19 13:45:41 -05:00
|
|
|
let mut buffer = [0u8; BLOCK_SIZE];
|
2024-10-14 12:54:53 -05:00
|
|
|
let mut buffer_size = size;
|
|
|
|
src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size);
|
|
|
|
|
2024-10-25 10:37:38 -05:00
|
|
|
while core::intrinsics::likely(buffer_size * 2 <= BLOCK_SIZE) {
|
2024-10-14 12:54:53 -05:00
|
|
|
buffer
|
|
|
|
.as_mut_ptr()
|
|
|
|
.copy_to_nonoverlapping(buffer.as_mut_ptr().add(buffer_size), buffer_size);
|
|
|
|
buffer_size *= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
let buffer_ptr = buffer.as_ptr() as *const u64;
|
2024-10-19 13:45:41 -05:00
|
|
|
|
|
|
|
while (dest as usize) & 7 != 0 && remaining >= 8 {
|
|
|
|
buffer.as_ptr().copy_to_nonoverlapping(dest, 1);
|
|
|
|
dest = dest.add(1);
|
|
|
|
remaining -= 1;
|
|
|
|
}
|
|
|
|
|
2024-10-25 10:37:38 -05:00
|
|
|
while core::intrinsics::likely(remaining >= 8) {
|
2024-10-19 13:45:41 -05:00
|
|
|
*(dest as *mut u64) = *buffer_ptr;
|
2024-10-14 12:54:53 -05:00
|
|
|
dest = dest.add(8);
|
|
|
|
remaining -= 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
if remaining > 0 {
|
|
|
|
buffer.as_ptr().copy_to_nonoverlapping(dest, remaining);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-13 19:31:23 -05:00
|
|
|
#[inline(always)]
|
2024-03-11 09:48:56 -05:00
|
|
|
pub fn memory_msg_handler(
|
|
|
|
vm: &mut Vm,
|
|
|
|
mem_addr: u64,
|
|
|
|
length: usize,
|
|
|
|
) -> Result<(), MemoryServiceError> {
|
2024-09-13 16:41:31 -05:00
|
|
|
let msg_vec = block_read(mem_addr, length);
|
2024-05-04 12:41:47 -05:00
|
|
|
let msg_type = msg_vec[0];
|
|
|
|
match msg_type {
|
2024-10-13 17:38:43 -05:00
|
|
|
0 => unsafe {
|
2024-09-13 16:41:31 -05:00
|
|
|
let page_count = msg_vec[1];
|
2024-05-04 12:41:47 -05:00
|
|
|
|
2024-10-13 17:38:43 -05:00
|
|
|
let ptr = alloc(Layout::from_size_align_unchecked(
|
|
|
|
page_count as usize * 4096,
|
2024-10-19 13:45:41 -05:00
|
|
|
8,
|
2024-10-13 17:38:43 -05:00
|
|
|
));
|
2024-09-13 16:41:31 -05:00
|
|
|
|
2024-10-23 15:22:28 -05:00
|
|
|
log::debug!("Allocating {} pages @ {:x}", page_count, ptr as u64);
|
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
|
|
|
log::debug!("Kernel ptr: {:x}", ptr as u64);
|
2024-10-13 17:38:43 -05:00
|
|
|
},
|
2024-09-13 16:41:31 -05:00
|
|
|
|
2024-10-13 17:38:43 -05:00
|
|
|
1 => unsafe {
|
2024-09-13 16:41:31 -05:00
|
|
|
let page_count = msg_vec[1];
|
2024-07-06 11:23:44 -05:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap();
|
2024-07-06 11:23:44 -05:00
|
|
|
let mptr: u64 = u64::from_le_bytes(mptr_raw);
|
|
|
|
log::debug!("Deallocating {} pages @ {:x}", page_count, mptr);
|
2024-10-13 17:38:43 -05:00
|
|
|
|
|
|
|
dealloc(
|
|
|
|
mptr as *mut u8,
|
2024-10-19 13:45:41 -05:00
|
|
|
Layout::from_size_align_unchecked(page_count as usize * 4096, 8),
|
2024-10-13 17:38:43 -05:00
|
|
|
)
|
|
|
|
},
|
2024-05-04 12:41:47 -05:00
|
|
|
2 => {
|
|
|
|
use MemoryQuotaType::*;
|
2024-10-13 17:38:43 -05:00
|
|
|
let quota_type = match msg_vec[1] {
|
2024-05-04 12:41:47 -05:00
|
|
|
0 => NoQuota,
|
|
|
|
1 => SoftQuota,
|
|
|
|
2 => HardQuota,
|
|
|
|
3 => KillQuota,
|
|
|
|
_ => NoQuota,
|
|
|
|
};
|
2024-09-13 16:41:31 -05:00
|
|
|
let hid_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap();
|
2024-05-04 12:41:47 -05:00
|
|
|
let hid: u64 = u64::from_le_bytes(hid_raw);
|
2024-09-13 16:41:31 -05:00
|
|
|
let pid_raw: [u8; 8] = msg_vec[10..18].try_into().unwrap();
|
|
|
|
let pid: u64 = u64::from_le_bytes(pid_raw);
|
2024-05-04 12:41:47 -05:00
|
|
|
debug!(
|
|
|
|
"Setting HID-{:x}:PID-{:x}'s quota type to {:?}",
|
|
|
|
hid, pid, quota_type
|
|
|
|
)
|
|
|
|
}
|
2024-07-06 09:24:23 -05:00
|
|
|
3 => {
|
2024-10-13 17:38:43 -05:00
|
|
|
let page_count = msg_vec[1];
|
2024-07-06 09:24:23 -05:00
|
|
|
log::debug!(" {} pages", page_count);
|
|
|
|
}
|
2024-10-13 17:38:43 -05:00
|
|
|
4 => unsafe {
|
2024-10-25 10:37:38 -05:00
|
|
|
let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
|
|
|
|
let src = u64::from_le_bytes(msg_vec[5..13].try_into().unwrap_unchecked()) as *const u8;
|
|
|
|
let dest = u64::from_le_bytes(msg_vec[13..21].try_into().unwrap_unchecked()) as *mut u8;
|
2024-10-13 19:31:23 -05:00
|
|
|
|
2024-10-19 13:45:41 -05:00
|
|
|
src.copy_to_nonoverlapping(dest, count);
|
2024-10-13 17:38:43 -05:00
|
|
|
},
|
|
|
|
5 => unsafe {
|
2024-10-25 10:37:38 -05:00
|
|
|
let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
|
|
|
|
let size = u32::from_le_bytes(msg_vec[5..9].try_into().unwrap_unchecked()) as usize;
|
|
|
|
let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
|
|
|
|
let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
|
2024-10-14 12:54:53 -05:00
|
|
|
|
|
|
|
memset(dest, src, count, size);
|
2024-10-13 17:38:43 -05:00
|
|
|
},
|
2024-07-06 09:24:23 -05:00
|
|
|
_ => {
|
|
|
|
log::debug!("Unknown memory service message type: {}", msg_type);
|
|
|
|
}
|
2024-05-04 12:41:47 -05:00
|
|
|
}
|
2024-03-11 09:48:56 -05:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|