refactor: Replace addr_of_mut with MaybeUninit::as_mut_ptr

Use MaybeUninit::as_mut_ptr as it's a more safer option to
avoid any potential bugs with respect to uninitialized memory.

Signed-off-by: Vaishali Thakkar <me.vaishalithakkar@gmail.com>
This commit is contained in:
Vaishali Thakkar
2024-09-03 19:56:44 +02:00
parent a320efad6b
commit 4547340d54
4 changed files with 177 additions and 134 deletions

View File

@ -1,6 +1,6 @@
use std::{ use std::{
mem::MaybeUninit,
os::fd::{AsRawFd, FromRawFd, OwnedFd}, os::fd::{AsRawFd, FromRawFd, OwnedFd},
ptr::addr_of_mut,
}; };
use anyhow::Result; use anyhow::Result;
@ -70,9 +70,10 @@ impl EthtoolHandle {
fn set_value(&mut self, interface: &str, cmd: u32, value: u32) -> Result<()> { fn set_value(&mut self, interface: &str, cmd: u32, value: u32) -> Result<()> {
let mut ifreq = EthtoolIfreq::new(interface); let mut ifreq = EthtoolIfreq::new(interface);
let mut value = EthtoolValue { cmd, data: value }; let mut value = MaybeUninit::new(EthtoolValue { cmd, data: value });
ifreq.set_value(addr_of_mut!(value) as *mut libc::c_void); ifreq.set_value(value.as_mut_ptr() as *mut libc::c_void);
let result = unsafe { ioctl(self.fd.as_raw_fd(), SIOCETHTOOL, addr_of_mut!(ifreq) as u64) }; let mut ifreq = MaybeUninit::new(ifreq);
let result = unsafe { ioctl(self.fd.as_raw_fd(), SIOCETHTOOL, ifreq.as_mut_ptr() as u64) };
if result == -1 { if result == -1 {
return Err(std::io::Error::last_os_error().into()); return Err(std::io::Error::last_os_error().into());
} }

View File

@ -37,8 +37,9 @@ use tokio::sync::Semaphore;
use tokio::time::sleep; use tokio::time::sleep;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::mem::MaybeUninit;
use std::os::fd::AsRawFd; use std::os::fd::AsRawFd;
use std::ptr::{addr_of_mut, null_mut}; use std::ptr::null_mut;
use std::slice; use std::slice;
#[derive(Clone)] #[derive(Clone)]
@ -68,18 +69,18 @@ impl XenCall {
fn detect_domctl_interface_version(handle: &File, current_domid: u32) -> Result<u32> { fn detect_domctl_interface_version(handle: &File, current_domid: u32) -> Result<u32> {
for version in XEN_DOMCTL_MIN_INTERFACE_VERSION..XEN_DOMCTL_MAX_INTERFACE_VERSION + 1 { for version in XEN_DOMCTL_MIN_INTERFACE_VERSION..XEN_DOMCTL_MAX_INTERFACE_VERSION + 1 {
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_GETDOMAININFO, cmd: XEN_DOMCTL_GETDOMAININFO,
interface_version: version, interface_version: version,
domid: current_domid, domid: current_domid,
value: DomCtlValue { value: DomCtlValue {
get_domain_info: GetDomainInfo::default(), get_domain_info: GetDomainInfo::default(),
}, },
}; });
unsafe { unsafe {
let mut call = Hypercall { let mut call = Hypercall {
op: HYPERVISOR_DOMCTL, op: HYPERVISOR_DOMCTL,
arg: [addr_of_mut!(domctl) as u64, 0, 0, 0, 0], arg: [domctl.as_mut_ptr() as u64, 0, 0, 0, 0],
}; };
let result = sys::hypercall(handle.as_raw_fd(), &mut call).unwrap_or(-1); let result = sys::hypercall(handle.as_raw_fd(), &mut call).unwrap_or(-1);
if result == 0 { if result == 0 {
@ -92,7 +93,7 @@ impl XenCall {
fn detect_sysctl_interface_version(handle: &File) -> Result<u32> { fn detect_sysctl_interface_version(handle: &File) -> Result<u32> {
for version in XEN_SYSCTL_MIN_INTERFACE_VERSION..XEN_SYSCTL_MAX_INTERFACE_VERSION + 1 { for version in XEN_SYSCTL_MIN_INTERFACE_VERSION..XEN_SYSCTL_MAX_INTERFACE_VERSION + 1 {
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_CPUTOPOINFO, cmd: XEN_SYSCTL_CPUTOPOINFO,
interface_version: version, interface_version: version,
value: SysctlValue { value: SysctlValue {
@ -101,11 +102,11 @@ impl XenCall {
handle: 0, handle: 0,
}, },
}, },
}; });
unsafe { unsafe {
let mut call = Hypercall { let mut call = Hypercall {
op: HYPERVISOR_SYSCTL, op: HYPERVISOR_SYSCTL,
arg: [addr_of_mut!(sysctl) as u64, 0, 0, 0, 0], arg: [sysctl.as_mut_ptr() as u64, 0, 0, 0, 0],
}; };
let result = sys::hypercall(handle.as_raw_fd(), &mut call).unwrap_or(-1); let result = sys::hypercall(handle.as_raw_fd(), &mut call).unwrap_or(-1);
if result == 0 { if result == 0 {
@ -337,16 +338,16 @@ impl XenCall {
"call fd={} get_version_capabilities", "call fd={} get_version_capabilities",
self.handle.as_raw_fd() self.handle.as_raw_fd()
); );
let mut info = XenCapabilitiesInfo { let mut info = MaybeUninit::new(XenCapabilitiesInfo {
capabilities: [0; 1024], capabilities: [0; 1024],
}; });
self.hypercall2( self.hypercall2(
HYPERVISOR_XEN_VERSION, HYPERVISOR_XEN_VERSION,
XENVER_CAPABILITIES, XENVER_CAPABILITIES,
addr_of_mut!(info) as c_ulong, info.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
Ok(info) Ok(unsafe { info.assume_init() })
} }
pub async fn evtchn_op(&self, cmd: c_int, arg: u64) -> Result<()> { pub async fn evtchn_op(&self, cmd: c_int, arg: u64) -> Result<()> {
@ -356,13 +357,14 @@ impl XenCall {
} }
pub async fn evtchn_alloc_unbound(&self, domid: u32, remote_domid: u32) -> Result<u32> { pub async fn evtchn_alloc_unbound(&self, domid: u32, remote_domid: u32) -> Result<u32> {
let mut alloc_unbound = EvtChnAllocUnbound { let mut alloc_unbound = MaybeUninit::new(EvtChnAllocUnbound {
dom: domid as u16, dom: domid as u16,
remote_dom: remote_domid as u16, remote_dom: remote_domid as u16,
port: 0, port: 0,
}; });
self.evtchn_op(6, addr_of_mut!(alloc_unbound) as c_ulong) self.evtchn_op(6, alloc_unbound.as_mut_ptr() as c_ulong)
.await?; .await?;
let alloc_unbound = unsafe { alloc_unbound.assume_init() };
Ok(alloc_unbound.port) Ok(alloc_unbound.port)
} }
@ -372,17 +374,19 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid domid
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_GETDOMAININFO, cmd: XEN_DOMCTL_GETDOMAININFO,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
get_domain_info: GetDomainInfo::default(), get_domain_info: GetDomainInfo::default(),
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
Ok(unsafe { domctl.value.get_domain_info }) let domctl = unsafe { domctl.assume_init() };
let get_domain_info = unsafe { domctl.value.get_domain_info };
Ok(get_domain_info)
} }
pub async fn create_domain(&self, create_domain: CreateDomain) -> Result<u32> { pub async fn create_domain(&self, create_domain: CreateDomain) -> Result<u32> {
@ -391,15 +395,15 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
create_domain create_domain
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_CREATEDOMAIN, cmd: XEN_DOMCTL_CREATEDOMAIN,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid: 0, domid: 0,
value: DomCtlValue { create_domain }, value: DomCtlValue { create_domain },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
Ok(domctl.domid) Ok(unsafe { domctl.assume_init() }.domid)
} }
pub async fn pause_domain(&self, domid: u32) -> Result<()> { pub async fn pause_domain(&self, domid: u32) -> Result<()> {
@ -408,14 +412,15 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid, domid,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_PAUSEDOMAIN, cmd: XEN_DOMCTL_PAUSEDOMAIN,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { pad: [0; 128] }, value: DomCtlValue { pad: [0; 128] },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -425,14 +430,15 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid, domid,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_UNPAUSEDOMAIN, cmd: XEN_DOMCTL_UNPAUSEDOMAIN,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { pad: [0; 128] }, value: DomCtlValue { pad: [0; 128] },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -443,16 +449,17 @@ impl XenCall {
domid, domid,
memkb memkb
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_MAX_MEM, cmd: XEN_DOMCTL_MAX_MEM,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
max_mem: MaxMem { max_memkb: memkb }, max_mem: MaxMem { max_memkb: memkb },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -463,16 +470,17 @@ impl XenCall {
domid, domid,
max_vcpus max_vcpus
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_MAX_VCPUS, cmd: XEN_DOMCTL_MAX_VCPUS,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
max_cpus: MaxVcpus { max_vcpus }, max_cpus: MaxVcpus { max_vcpus },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -483,16 +491,17 @@ impl XenCall {
domid, domid,
size, size,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_SET_ADDRESS_SIZE, cmd: XEN_DOMCTL_SET_ADDRESS_SIZE,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
address_size: AddressSize { size }, address_size: AddressSize { size },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -500,7 +509,7 @@ impl XenCall {
&self, &self,
domid: u32, domid: u32,
vcpu: u32, vcpu: u32,
mut context: VcpuGuestContextAny, context: VcpuGuestContextAny,
) -> Result<()> { ) -> Result<()> {
trace!( trace!(
"domctl fd={} set_vcpu_context domid={} context={:?}", "domctl fd={} set_vcpu_context domid={} context={:?}",
@ -509,25 +518,28 @@ impl XenCall {
unsafe { context.value } unsafe { context.value }
); );
let mut domctl = DomCtl { let mut context = MaybeUninit::new(context);
let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_SETVCPUCONTEXT, cmd: XEN_DOMCTL_SETVCPUCONTEXT,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
vcpu_context: DomCtlVcpuContext { vcpu_context: DomCtlVcpuContext {
vcpu, vcpu,
ctx: addr_of_mut!(context) as c_ulong, ctx: context.as_mut_ptr() as c_ulong,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
pub async fn get_page_frame_info(&self, domid: u32, frames: &[u64]) -> Result<Vec<u64>> { pub async fn get_page_frame_info(&self, domid: u32, frames: &[u64]) -> Result<Vec<u64>> {
let mut buffer: Vec<u64> = frames.to_vec(); let mut buffer: Vec<u64> = frames.to_vec();
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_GETPAGEFRAMEINFO3, cmd: XEN_DOMCTL_GETPAGEFRAMEINFO3,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -537,9 +549,10 @@ impl XenCall {
array: buffer.as_mut_ptr() as c_ulong, array: buffer.as_mut_ptr() as c_ulong,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let domctl = unsafe { domctl.assume_init() };
let slice = unsafe { let slice = unsafe {
slice::from_raw_parts_mut( slice::from_raw_parts_mut(
domctl.value.get_page_frame_info.array as *mut u64, domctl.value.get_page_frame_info.array as *mut u64,
@ -556,16 +569,17 @@ impl XenCall {
domid, domid,
gmfn gmfn
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_HYPERCALL_INIT, cmd: XEN_DOMCTL_HYPERCALL_INIT,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
hypercall_init: HypercallInit { gmfn }, hypercall_init: HypercallInit { gmfn },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -575,31 +589,32 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid domid
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_DESTROYDOMAIN, cmd: XEN_DOMCTL_DESTROYDOMAIN,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { pad: [0; 128] }, value: DomCtlValue { pad: [0; 128] },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
pub async fn get_memory_map(&self, max_entries: u32) -> Result<Vec<E820Entry>> { pub async fn get_memory_map(&self, max_entries: u32) -> Result<Vec<E820Entry>> {
let mut memory_map = MemoryMap {
count: max_entries,
buffer: 0,
};
let mut entries = vec![E820Entry::default(); max_entries as usize]; let mut entries = vec![E820Entry::default(); max_entries as usize];
memory_map.buffer = entries.as_mut_ptr() as c_ulong; let mut memory_map = MaybeUninit::new(MemoryMap {
count: max_entries,
buffer: entries.as_mut_ptr() as c_ulong,
});
self.hypercall2( self.hypercall2(
HYPERVISOR_MEMORY_OP, HYPERVISOR_MEMORY_OP,
XEN_MEM_MEMORY_MAP as c_ulong, XEN_MEM_MEMORY_MAP as c_ulong,
addr_of_mut!(memory_map) as c_ulong, memory_map.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
entries.truncate(memory_map.count as usize); unsafe { memory_map.assume_init() };
entries.truncate(max_entries as usize);
Ok(entries) Ok(entries)
} }
@ -614,19 +629,20 @@ impl XenCall {
domid, domid,
entries entries
); );
let mut memory_map = ForeignMemoryMap { let mut memory_map = MaybeUninit::new(ForeignMemoryMap {
domid: domid as u16, domid: domid as u16,
map: MemoryMap { map: MemoryMap {
count: entries.len() as u32, count: entries.len() as u32,
buffer: entries.as_ptr() as u64, buffer: entries.as_ptr() as u64,
}, },
}; });
self.hypercall2( self.hypercall2(
HYPERVISOR_MEMORY_OP, HYPERVISOR_MEMORY_OP,
XEN_MEM_SET_MEMORY_MAP as c_ulong, XEN_MEM_SET_MEMORY_MAP as c_ulong,
addr_of_mut!(memory_map) as c_ulong, memory_map.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
unsafe { memory_map.assume_init() };
Ok(entries) Ok(entries)
} }
@ -642,24 +658,25 @@ impl XenCall {
let mut extent_starts = extent_starts.to_vec(); let mut extent_starts = extent_starts.to_vec();
let ptr = extent_starts.as_mut_ptr(); let ptr = extent_starts.as_mut_ptr();
let mut reservation = MemoryReservation { let mut reservation = MaybeUninit::new(MemoryReservation {
extent_start: ptr as c_ulong, extent_start: ptr as c_ulong,
nr_extents, nr_extents,
extent_order, extent_order,
mem_flags, mem_flags,
domid: domid as u16, domid: domid as u16,
}; });
let code = self let code = self
.hypercall2( .hypercall2(
HYPERVISOR_MEMORY_OP, HYPERVISOR_MEMORY_OP,
XEN_MEM_POPULATE_PHYSMAP as c_ulong, XEN_MEM_POPULATE_PHYSMAP as c_ulong,
addr_of_mut!(reservation) as c_ulong, reservation.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
if code as usize != extent_starts.len() { if code as usize != extent_starts.len() {
return Err(Error::PopulatePhysmapFailed); return Err(Error::PopulatePhysmapFailed);
} }
unsafe { reservation.assume_init() };
let extents = extent_starts[0..code as usize].to_vec(); let extents = extent_starts[0..code as usize].to_vec();
Ok(extents) Ok(extents)
} }
@ -671,19 +688,20 @@ impl XenCall {
domid, domid,
pages pages
); );
let mut reservation = MemoryReservation { let mut reservation = MaybeUninit::new(MemoryReservation {
extent_start: 0, extent_start: 0,
nr_extents: pages, nr_extents: pages,
extent_order: 0, extent_order: 0,
mem_flags: 0, mem_flags: 0,
domid: domid as u16, domid: domid as u16,
}; });
self.hypercall2( self.hypercall2(
HYPERVISOR_MEMORY_OP, HYPERVISOR_MEMORY_OP,
XEN_MEM_CLAIM_PAGES as c_ulong, XEN_MEM_CLAIM_PAGES as c_ulong,
addr_of_mut!(reservation) as c_ulong, reservation.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
unsafe { reservation.assume_init() };
Ok(()) Ok(())
} }
@ -696,34 +714,36 @@ impl XenCall {
idx, idx,
pfn, pfn,
); );
let mut add = AddToPhysmap { let mut add = MaybeUninit::new(AddToPhysmap {
domid: domid as u16, domid: domid as u16,
size: 0, size: 0,
space, space,
idx, idx,
gpfn: pfn, gpfn: pfn,
}; });
self.hypercall2( self.hypercall2(
HYPERVISOR_MEMORY_OP, HYPERVISOR_MEMORY_OP,
XEN_MEM_ADD_TO_PHYSMAP as c_ulong, XEN_MEM_ADD_TO_PHYSMAP as c_ulong,
addr_of_mut!(add) as c_ulong, add.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
unsafe { add.assume_init() };
Ok(()) Ok(())
} }
pub async fn mmuext(&self, domid: u32, cmd: c_uint, arg1: u64, arg2: u64) -> Result<()> { pub async fn mmuext(&self, domid: u32, cmd: c_uint, arg1: u64, arg2: u64) -> Result<()> {
let mut ops = MmuExtOp { cmd, arg1, arg2 }; let mut ops = MaybeUninit::new(MmuExtOp { cmd, arg1, arg2 });
self.hypercall4( self.hypercall4(
HYPERVISOR_MMUEXT_OP, HYPERVISOR_MMUEXT_OP,
addr_of_mut!(ops) as c_ulong, ops.as_mut_ptr() as c_ulong,
1, 1,
0, 0,
domid as c_ulong, domid as c_ulong,
) )
.await .await?;
.map(|_| ()) unsafe { ops.assume_init() };
Ok(())
} }
pub async fn iomem_permission( pub async fn iomem_permission(
@ -741,7 +761,7 @@ impl XenCall {
nr_mfns, nr_mfns,
allow, allow,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_IOMEM_PERMISSION, cmd: XEN_DOMCTL_IOMEM_PERMISSION,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -752,9 +772,10 @@ impl XenCall {
allow: if allow { 1 } else { 0 }, allow: if allow { 1 } else { 0 },
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -773,7 +794,7 @@ impl XenCall {
nr_ports, nr_ports,
allow, allow,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_IOPORT_PERMISSION, cmd: XEN_DOMCTL_IOPORT_PERMISSION,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -784,9 +805,10 @@ impl XenCall {
allow: if allow { 1 } else { 0 }, allow: if allow { 1 } else { 0 },
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -798,7 +820,7 @@ impl XenCall {
irq, irq,
allow, allow,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_IRQ_PERMISSION, cmd: XEN_DOMCTL_IRQ_PERMISSION,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -809,9 +831,10 @@ impl XenCall {
pad: [0; 3], pad: [0; 3],
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -824,23 +847,20 @@ impl XenCall {
index, index,
pirq, pirq,
); );
let mut physdev = PhysdevMapPirq { let mut physdev = MaybeUninit::new(PhysdevMapPirq {
domid: domid as u16, domid: domid as u16,
typ: 0x1, typ: 0x1,
index: index as c_int, index: index as c_int,
pirq: pirq.map(|x| x as c_int).unwrap_or(index as c_int), pirq: pirq.map(|x| x as c_int).unwrap_or(index as c_int),
..Default::default() ..Default::default()
}; });
physdev.domid = domid as u16;
physdev.typ = 0x1;
physdev.index = index as c_int;
physdev.pirq = pirq.map(|x| x as c_int).unwrap_or(index as c_int);
self.hypercall2( self.hypercall2(
HYPERVISOR_PHYSDEV_OP, HYPERVISOR_PHYSDEV_OP,
PHYSDEVOP_MAP_PIRQ, PHYSDEVOP_MAP_PIRQ,
addr_of_mut!(physdev) as c_ulong, physdev.as_mut_ptr() as c_ulong,
) )
.await?; .await?;
let physdev = unsafe { physdev.assume_init() };
Ok(physdev.pirq as u32) Ok(physdev.pirq as u32)
} }
@ -852,7 +872,7 @@ impl XenCall {
sbdf, sbdf,
flags, flags,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_ASSIGN_DEVICE, cmd: XEN_DOMCTL_ASSIGN_DEVICE,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -863,9 +883,10 @@ impl XenCall {
pci_assign_device: PciAssignDevice { sbdf, padding: 0 }, pci_assign_device: PciAssignDevice { sbdf, padding: 0 },
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
@ -878,12 +899,11 @@ impl XenCall {
index, index,
value, value,
); );
let mut param = HvmParam::default();
param.domid = domid as u16; let mut param = MaybeUninit::new(HvmParam::new(domid as u16, index, value));
param.index = index; self.hypercall2(HYPERVISOR_HVM_OP, 0, param.as_mut_ptr() as c_ulong)
param.value = value;
self.hypercall2(HYPERVISOR_HVM_OP, 0, addr_of_mut!(param) as c_ulong)
.await?; .await?;
unsafe { param.assume_init() };
Ok(()) Ok(())
} }
@ -893,7 +913,7 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid, domid,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_GETHVMCONTEXT, cmd: XEN_DOMCTL_GETHVMCONTEXT,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -903,9 +923,10 @@ impl XenCall {
buffer: buffer.map(|x| x.as_mut_ptr()).unwrap_or(null_mut()) as u64, buffer: buffer.map(|x| x.as_mut_ptr()).unwrap_or(null_mut()) as u64,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let domctl = unsafe { domctl.assume_init() };
Ok(unsafe { domctl.value.hvm_context.size }) Ok(unsafe { domctl.value.hvm_context.size })
} }
@ -915,7 +936,7 @@ impl XenCall {
self.handle.as_raw_fd(), self.handle.as_raw_fd(),
domid, domid,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_SETHVMCONTEXT, cmd: XEN_DOMCTL_SETHVMCONTEXT,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
@ -925,9 +946,10 @@ impl XenCall {
buffer: buffer.as_ptr() as u64, buffer: buffer.as_ptr() as u64,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let domctl = unsafe { domctl.assume_init() };
Ok(unsafe { domctl.value.hvm_context.size }) Ok(unsafe { domctl.value.hvm_context.size })
} }
@ -938,21 +960,22 @@ impl XenCall {
domid, domid,
size, size,
); );
let mut domctl = DomCtl { let mut domctl = MaybeUninit::new(DomCtl {
cmd: XEN_DOMCTL_SET_PAGING_MEMPOOL_SIZE, cmd: XEN_DOMCTL_SET_PAGING_MEMPOOL_SIZE,
interface_version: self.domctl_interface_version, interface_version: self.domctl_interface_version,
domid, domid,
value: DomCtlValue { value: DomCtlValue {
paging_mempool: PagingMempool { size }, paging_mempool: PagingMempool { size },
}, },
}; });
self.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong) self.hypercall1(HYPERVISOR_DOMCTL, domctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { domctl.assume_init() };
Ok(()) Ok(())
} }
pub async fn cpu_topology(&self) -> Result<Vec<SysctlCputopo>> { pub async fn cpu_topology(&self) -> Result<Vec<SysctlCputopo>> {
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_CPUTOPOINFO, cmd: XEN_SYSCTL_CPUTOPOINFO,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
@ -961,9 +984,10 @@ impl XenCall {
handle: 0, handle: 0,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let sysctl = unsafe { sysctl.assume_init() };
let cpus = unsafe { sysctl.value.cputopoinfo.num_cpus }; let cpus = unsafe { sysctl.value.cputopoinfo.num_cpus };
let mut topos = vec![ let mut topos = vec![
SysctlCputopo { SysctlCputopo {
@ -973,7 +997,7 @@ impl XenCall {
}; };
cpus as usize cpus as usize
]; ];
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_CPUTOPOINFO, cmd: XEN_SYSCTL_CPUTOPOINFO,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
@ -982,22 +1006,24 @@ impl XenCall {
handle: topos.as_mut_ptr() as c_ulong, handle: topos.as_mut_ptr() as c_ulong,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { sysctl.assume_init() };
Ok(topos) Ok(topos)
} }
pub async fn phys_info(&self) -> Result<SysctlPhysinfo> { pub async fn phys_info(&self) -> Result<SysctlPhysinfo> {
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_PHYSINFO, cmd: XEN_SYSCTL_PHYSINFO,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
phys_info: SysctlPhysinfo::default(), phys_info: SysctlPhysinfo::default(),
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let sysctl = unsafe { sysctl.assume_init() };
Ok(unsafe { sysctl.value.phys_info }) Ok(unsafe { sysctl.value.phys_info })
} }
@ -1033,7 +1059,7 @@ impl XenCall {
scaling_governor[i] = governor[i]; scaling_governor[i] = governor[i];
} }
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_PM_OP, cmd: XEN_SYSCTL_PM_OP,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
@ -1045,9 +1071,10 @@ impl XenCall {
}, },
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { sysctl.assume_init() };
Ok(()) Ok(())
} }
@ -1068,7 +1095,7 @@ impl XenCall {
} }
async fn do_set_turbo_mode(&self, cpuid: u32, enable: bool) -> Result<()> { async fn do_set_turbo_mode(&self, cpuid: u32, enable: bool) -> Result<()> {
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_PM_OP, cmd: XEN_SYSCTL_PM_OP,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
@ -1082,9 +1109,10 @@ impl XenCall {
value: SysctlPmOpValue { pad: [0u8; 128] }, value: SysctlPmOpValue { pad: [0u8; 128] },
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
unsafe { sysctl.assume_init() };
Ok(()) Ok(())
} }
@ -1093,8 +1121,8 @@ impl XenCall {
clear: bool, clear: bool,
index: u32, index: u32,
) -> Result<([u8; 16384], u32)> { ) -> Result<([u8; 16384], u32)> {
let mut u8buf = [0u8; 16384]; let mut u8buf = MaybeUninit::new([0u8; 16384]);
let mut sysctl = Sysctl { let mut sysctl = MaybeUninit::new(Sysctl {
cmd: XEN_SYSCTL_READCONSOLE, cmd: XEN_SYSCTL_READCONSOLE,
interface_version: self.sysctl_interface_version, interface_version: self.sysctl_interface_version,
value: SysctlValue { value: SysctlValue {
@ -1103,16 +1131,18 @@ impl XenCall {
incremental: 1, incremental: 1,
pad: 0, pad: 0,
index, index,
buffer: addr_of_mut!(u8buf) as u64, buffer: u8buf.as_mut_ptr() as u64,
count: 16384, count: 16384,
}, },
}, },
}; });
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) self.hypercall1(HYPERVISOR_SYSCTL, sysctl.as_mut_ptr() as c_ulong)
.await?; .await?;
let sysctl = unsafe { sysctl.assume_init() };
// Safety: We are passing a SysctlReadconsole struct as part of the hypercall, and // Safety: We are passing a SysctlReadconsole struct as part of the hypercall, and
// calling the hypercall is known to not change the underlying value outside changing // calling the hypercall is known to not change the underlying value outside changing
// the values on some SysctlReadconsole fields. // the values on some SysctlReadconsole fields.
let u8buf = unsafe { u8buf.assume_init() };
let newindex = unsafe { sysctl.value.console.index }; let newindex = unsafe { sysctl.value.console.index };
Ok((u8buf, newindex)) Ok((u8buf, newindex))
} }

View File

@ -700,6 +700,17 @@ pub struct HvmParam {
pub value: u64, pub value: u64,
} }
impl HvmParam {
pub fn new(domid: u16, index: u32, value: u64) -> Self {
Self {
domid,
pad: 0,
index,
value,
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HvmContext { pub struct HvmContext {

View File

@ -5,7 +5,7 @@ use nix::unistd::Pid;
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use std::{ use std::{
ptr::addr_of_mut, mem::MaybeUninit,
sync::{ sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
Arc, Arc,
@ -65,8 +65,8 @@ struct ChildWaitTask {
impl ChildWaitTask { impl ChildWaitTask {
fn process(&mut self) -> Result<()> { fn process(&mut self) -> Result<()> {
loop { loop {
let mut status: c_int = 0; let mut status = MaybeUninit::<c_int>::new(0);
let pid = unsafe { waitpid(-1, addr_of_mut!(status), 0) }; let pid = unsafe { waitpid(-1, status.as_mut_ptr(), 0) };
// pid being -1 indicates an error occurred, wait 100 microseconds to avoid // pid being -1 indicates an error occurred, wait 100 microseconds to avoid
// overloading the channel. Right now we don't consider any other errors // overloading the channel. Right now we don't consider any other errors
// but that is fine for now, as waitpid shouldn't ever stop anyway. // but that is fine for now, as waitpid shouldn't ever stop anyway.
@ -74,6 +74,7 @@ impl ChildWaitTask {
sleep(Duration::from_micros(100)); sleep(Duration::from_micros(100));
continue; continue;
} }
let status = unsafe { status.assume_init() };
if WIFEXITED(status) { if WIFEXITED(status) {
let event = ChildEvent { let event = ChildEvent {
pid: Pid::from_raw(pid), pid: Pid::from_raw(pid),