diff --git a/xencall/src/lib.rs b/xencall/src/lib.rs index 7338362..74ad89b 100644 --- a/xencall/src/lib.rs +++ b/xencall/src/lib.rs @@ -3,7 +3,8 @@ pub mod memory; pub mod sys; use crate::sys::{ - Hypercall, MmapBatch, XenCapabilitiesInfo, HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES, + Hypercall, MmapBatch, MultiCallEntry, XenCapabilitiesInfo, HYPERVISOR_MULTICALL, + HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES, }; use libc::{mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; use nix::errno::Errno; @@ -128,6 +129,15 @@ impl XenCall { self.hypercall(op, [arg1, arg2, arg3, arg4, 0]) } + pub fn multicall(&self, calls: &mut [MultiCallEntry]) -> Result<(), XenCallError> { + self.hypercall2( + HYPERVISOR_MULTICALL, + calls.as_mut_ptr() as c_ulong, + calls.len() as c_ulong, + )?; + Ok(()) + } + pub fn hypercall5( &self, op: c_ulong, diff --git a/xencall/src/memory.rs b/xencall/src/memory.rs index 4b35561..506af63 100644 --- a/xencall/src/memory.rs +++ b/xencall/src/memory.rs @@ -1,8 +1,11 @@ -use crate::sys::{MemoryReservation, HYPERVISOR_MEMORY_OP, XEN_MEM_POPULATE_PHYSMAP}; +use crate::sys::{ + MemoryReservation, MultiCallEntry, HYPERVISOR_MEMORY_OP, XEN_MEM_POPULATE_PHYSMAP, +}; use crate::{XenCall, XenCallError}; use std::ffi::c_ulong; +use libc::c_long; use std::ptr::addr_of_mut; pub struct MemoryControl<'a> { @@ -30,12 +33,21 @@ impl MemoryControl<'_> { mem_flags, domid: domid as u16, }; - let code = self.call.hypercall2( - HYPERVISOR_MEMORY_OP, - XEN_MEM_POPULATE_PHYSMAP as c_ulong, - addr_of_mut!(reservation) as c_ulong, - )?; + let calls = &mut [MultiCallEntry { + op: HYPERVISOR_MEMORY_OP, + result: 0, + args: [ + XEN_MEM_POPULATE_PHYSMAP as c_ulong, + addr_of_mut!(reservation) as c_ulong, + 0, + 0, + 0, + 0, + ], + }]; + self.call.multicall(calls)?; + let code = calls[0].result as c_long; if code < 0 { return Err(XenCallError::new("failed to populate physmap")); } diff --git a/xencall/src/sys.rs b/xencall/src/sys.rs index 4aab3ca..979ff13 100644 --- a/xencall/src/sys.rs +++ b/xencall/src/sys.rs @@ -318,4 +318,12 @@ pub struct MemoryReservation { pub domid: u16, } +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MultiCallEntry { + pub op: c_ulong, + pub result: c_ulong, + pub args: [c_ulong; 6], +} + pub const XEN_MEM_POPULATE_PHYSMAP: u32 = 6; diff --git a/xenclient/src/boot.rs b/xenclient/src/boot.rs index 2428aa3..741f5bb 100644 --- a/xenclient/src/boot.rs +++ b/xenclient/src/boot.rs @@ -34,6 +34,7 @@ pub struct BootSetup<'a> { pfn_alloc_end: u64, } +#[derive(Debug)] struct DomainSegment { _vstart: u64, _vend: u64, @@ -143,10 +144,14 @@ impl BootSetup<'_> { let allocsz = (1024 * 1024).min(pages - j); let p2m_idx = (pfn_base + j) as usize; - let extent_start = p2m[p2m_idx]; - let result = - self.memctl - .populate_physmap(self.domid, allocsz, 0, 0, &[extent_start])?; + let p2m_end_idx = p2m_idx + allocsz as usize; + let result = self.memctl.populate_physmap( + self.domid, + allocsz, + 0, + 0, + &p2m[p2m_idx..p2m_end_idx], + )?; if result.len() != allocsz as usize { return Err(XenClientError::new( @@ -163,7 +168,7 @@ impl BootSetup<'_> { Ok(()) } - fn initialize_hypercall(&mut self, image_info: BootImageInfo) -> Result<(), XenClientError> { + fn _initialize_hypercall(&mut self, image_info: BootImageInfo) -> Result<(), XenClientError> { if image_info.virt_hypercall != XEN_UNSET_ADDR { self.domctl .hypercall_init(self.domid, image_info.virt_hypercall)?; @@ -178,8 +183,8 @@ impl BootSetup<'_> { ) -> Result<(), XenClientError> { self.domctl.set_max_mem(self.domid, memkb)?; self.initialize_memory(memkb)?; - let _kernel_segment = self.alloc_segment(image_info.virt_kend - image_info.virt_kstart)?; - self.initialize_hypercall(image_info)?; + let kernel_segment = self.alloc_segment(image_info.virt_kend - image_info.virt_kstart)?; + println!("kernel_segment: {:?}", kernel_segment); Ok(()) }