1
0
Fork 0
forked from koniifer/ableos

Zero alloc BMC!

This commit is contained in:
Erin 2023-07-22 01:03:09 +02:00
parent 1a53c80a62
commit ec7053a289

View file

@ -220,40 +220,28 @@ impl Memory {
/// - Addr-san claims it's fine but who knows is she isn't lying :ferrisSus:
pub unsafe fn block_copy(
&mut self,
src: u64,
dst: u64,
mut src: u64,
mut dst: u64,
count: usize,
traph: &mut impl HandlePageFault,
) -> Result<(), BlkCopyError> {
// Yea, i know it is possible to do this more efficiently, but I am too lazy.
const STACK_BUFFER_SIZE: usize = 512;
// Decide if to use stack-allocated buffer or to heap allocate
// Deallocation is again decided on size at the end of the function
let mut buf = MaybeUninit::<[u8; STACK_BUFFER_SIZE]>::uninit();
let buf = if count <= STACK_BUFFER_SIZE {
buf.as_mut_ptr().cast()
} else {
unsafe {
let layout = core::alloc::Layout::from_size_align_unchecked(count, 1);
let ptr = alloc::alloc::alloc(layout);
if ptr.is_null() {
alloc::alloc::handle_alloc_error(layout);
}
ptr
}
};
// Perform memory block transfer
let status = (|| {
// Load to buffer
impl Memory {
#[inline]
unsafe fn act(
&mut self,
src: u64,
dst: u64,
buf: *mut u8,
count: usize,
traph: &mut impl HandlePageFault,
) -> Result<(), BlkCopyError> {
self.memory_access(
MemoryAccessReason::Load,
src,
buf,
count,
STACK_BUFFER_SIZE,
|perm| {
matches!(
perm,
@ -268,7 +256,6 @@ impl Memory {
addr,
})?;
// Store from buffer
self.memory_access(
MemoryAccessReason::Store,
dst,
@ -283,18 +270,26 @@ impl Memory {
addr,
})?;
Ok::<_, BlkCopyError>(())
})();
// Deallocate if used heap-allocated array
if count > STACK_BUFFER_SIZE {
alloc::alloc::dealloc(
buf,
core::alloc::Layout::from_size_align_unchecked(count, 1),
);
Ok(())
}
}
status
const STACK_BUFFER_SIZE: usize = 4096;
// Decide if to use stack-allocated buffer or to heap allocate
// Deallocation is again decided on size at the end of the function
let mut buf = MaybeUninit::<[u8; STACK_BUFFER_SIZE]>::uninit();
let n_buffers = count / STACK_BUFFER_SIZE;
let rem = count % STACK_BUFFER_SIZE;
for _ in 0..n_buffers {
self.act(src, dst, buf.as_mut_ptr().cast(), STACK_BUFFER_SIZE, traph)?;
src += STACK_BUFFER_SIZE as u64;
dst += STACK_BUFFER_SIZE as u64;
}
self.act(src, dst, buf.as_mut_ptr().cast(), rem, traph)
}
/// Split address to pages, check their permissions and feed pointers with offset