implement memory allocation in boot setup

This commit is contained in:
Alex Zenla
2024-01-10 16:07:57 -08:00
parent d46d0cf0c3
commit 153619a02c
11 changed files with 619 additions and 73 deletions

View File

@ -7,6 +7,9 @@ resolver = "2"
[lib]
path = "src/lib.rs"
[dependencies]
libc = "0.2"
[dependencies.uuid]
version = "1.6.1"
features = ["v4"]

View File

@ -1,12 +1,14 @@
pub mod domctl;
pub mod memory;
pub mod sys;
use crate::sys::{
Hypercall, Mmap, XenCapabilitiesInfo, HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES,
Hypercall, MmapBatch, XenCapabilitiesInfo, HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES,
};
use libc::{mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use nix::errno::Errno;
use std::error::Error;
use std::ffi::{c_long, c_ulong};
use std::ffi::{c_long, c_ulong, c_void};
use std::fmt::{Display, Formatter};
use std::fs::{File, OpenOptions};
use std::os::fd::AsRawFd;
@ -62,6 +64,24 @@ impl XenCall {
Ok(XenCall { handle: file })
}
pub fn mmap(&self, addr: u64, len: u64) -> Option<u64> {
unsafe {
let ptr = mmap(
addr as *mut c_void,
len as usize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
self.handle.as_raw_fd(),
0,
);
if ptr == MAP_FAILED {
None
} else {
Some(ptr as u64)
}
}
}
pub fn hypercall(&self, op: c_ulong, arg: [c_ulong; 5]) -> Result<c_long, XenCallError> {
unsafe {
let mut call = Hypercall { op, arg };
@ -120,10 +140,24 @@ impl XenCall {
self.hypercall(op, [arg1, arg2, arg3, arg4, arg5])
}
pub fn mmap(&self, mmap: Mmap) -> Result<c_long, XenCallError> {
pub fn mmap_batch(
&self,
domid: u32,
count: u64,
addr: u64,
mfns: Vec<u64>,
) -> Result<c_long, XenCallError> {
unsafe {
let mut mmap = mmap.clone();
let result = sys::mmap(self.handle.as_raw_fd(), &mut mmap)?;
let mut mfns = mfns.clone();
let mut errors = vec![0i32; mfns.len()];
let mut batch = MmapBatch {
num: count as u32,
domid: domid as u16,
addr,
mfns: mfns.as_mut_ptr(),
errors: errors.as_mut_ptr(),
};
let result = sys::mmapbatch(self.handle.as_raw_fd(), &mut batch)?;
Ok(result as c_long)
}
}

40
xencall/src/memory.rs Normal file
View File

@ -0,0 +1,40 @@
use crate::sys::{MemoryReservation, HYPERVISOR_MEMORY_OP, XEN_MEM_POPULATE_PHYSMAP};
use crate::{XenCall, XenCallError};
use std::ffi::c_ulong;
use std::ptr::addr_of;
pub struct MemoryControl<'a> {
call: &'a XenCall,
}
impl MemoryControl<'_> {
pub fn new(call: &XenCall) -> MemoryControl {
MemoryControl { call }
}
pub fn populate_physmap(
&self,
domid: u32,
nr_extents: u64,
extent_order: u32,
mem_flags: u32,
extent_starts: &[u64],
) -> Result<Vec<u64>, XenCallError> {
let extent_starts = extent_starts.to_vec();
let reservation = MemoryReservation {
extent_start: addr_of!(extent_starts) as c_ulong,
nr_extents,
extent_order,
mem_flags,
domid: domid as u16,
};
self.call.hypercall2(
HYPERVISOR_MEMORY_OP,
XEN_MEM_POPULATE_PHYSMAP as c_ulong,
addr_of!(reservation) as c_ulong,
)?;
Ok(extent_starts)
}
}

View File

@ -1,6 +1,6 @@
/// Handwritten hypercall bindings.
use nix::ioctl_readwrite_bad;
use std::ffi::{c_char, c_int, c_ulong};
use std::ffi::{c_char, c_int, c_uint, c_ulong};
use uuid::Uuid;
#[repr(C)]
@ -11,13 +11,23 @@ pub struct Hypercall {
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Default)]
pub struct MmapEntry {
pub va: u64,
pub mfn: u64,
pub npages: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MmapBatch {
pub num: u32,
pub domid: u16,
pub addr: u64,
pub mfns: *mut u64,
pub errors: *mut c_int,
}
#[repr(C)]
#[derive(Clone, Debug)]
pub struct Mmap {
@ -28,9 +38,11 @@ pub struct Mmap {
const IOCTL_PRIVCMD_HYPERCALL: u64 = 0x305000;
const IOCTL_PRIVCMD_MMAP: u64 = 0x105002;
const IOCTL_PRIVCMD_MMAPBATCH_V2: u64 = 0x205004;
ioctl_readwrite_bad!(hypercall, IOCTL_PRIVCMD_HYPERCALL, Hypercall);
ioctl_readwrite_bad!(mmap, IOCTL_PRIVCMD_MMAP, Mmap);
ioctl_readwrite_bad!(mmapbatch, IOCTL_PRIVCMD_MMAPBATCH_V2, MmapBatch);
pub const HYPERVISOR_SET_TRAP_TABLE: c_ulong = 0;
pub const HYPERVISOR_MMU_UPDATE: c_ulong = 1;
@ -295,3 +307,15 @@ pub struct XenCapabilitiesInfo {
}
pub const XENVER_CAPABILITIES: u64 = 3;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MemoryReservation {
pub extent_start: c_ulong,
pub nr_extents: c_ulong,
pub extent_order: c_uint,
pub mem_flags: c_uint,
pub domid: u16,
}
pub const XEN_MEM_POPULATE_PHYSMAP: u32 = 6;