use std::alloc::{Layout, alloc_zeroed, dealloc};
use crate::error::{Result, VmmError};
use super::PAGE_SIZE;
pub(super) struct GuestRam {
ptr: *mut u8,
layout: Layout,
}
unsafe impl Send for GuestRam {}
unsafe impl Sync for GuestRam {}
impl GuestRam {
pub fn new(size: usize) -> Result<Self> {
let layout = Layout::from_size_align(size, PAGE_SIZE)
.map_err(|e| VmmError::Memory(format!("invalid RAM layout: {e}")))?;
let ptr = unsafe { alloc_zeroed(layout) };
if ptr.is_null() {
return Err(VmmError::Memory(format!(
"failed to allocate {} bytes for guest RAM",
size
)));
}
Ok(Self { ptr, layout })
}
pub fn as_ptr(&self) -> *mut u8 {
self.ptr
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.ptr, self.layout.size()) }
}
pub fn size(&self) -> usize {
self.layout.size()
}
}
impl Drop for GuestRam {
fn drop(&mut self) {
unsafe { dealloc(self.ptr, self.layout) };
}
}