Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions crates/xen/xencall/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ use std::sync::Arc;
use std::time::Duration;
use sys::{
CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, SetDomainHandle, Sysctl, SysctlCputopo,
SysctlCputopoinfo, SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlReadconsole,
SysctlSetCpuFreqGov, SysctlValue, VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP,
HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ, XEN_DOMCTL_MAX_INTERFACE_VERSION,
XEN_DOMCTL_MIN_INTERFACE_VERSION, XEN_DOMCTL_SETDOMAINHANDLE, XEN_MEM_SET_MEMORY_MAP,
XEN_SYSCTL_CPUTOPOINFO, XEN_SYSCTL_MAX_INTERFACE_VERSION, XEN_SYSCTL_MIN_INTERFACE_VERSION,
XEN_SYSCTL_PHYSINFO, XEN_SYSCTL_PM_OP, XEN_SYSCTL_PM_OP_DISABLE_TURBO,
XEN_SYSCTL_PM_OP_ENABLE_TURBO, XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_READCONSOLE,
SysctlCputopoinfo, SysctlGetdomaininfolist, SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue,
SysctlReadconsole, SysctlSetCpuFreqGov, SysctlValue, VcpuGuestContextAny,
HYPERVISOR_PHYSDEV_OP, HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ,
XEN_DOMCTL_MAX_INTERFACE_VERSION, XEN_DOMCTL_MIN_INTERFACE_VERSION,
XEN_DOMCTL_SETDOMAINHANDLE, XEN_MEM_SET_MEMORY_MAP, XEN_SYSCTL_CPUTOPOINFO,
XEN_SYSCTL_GETDOMAININFOLIST, XEN_SYSCTL_MAX_INTERFACE_VERSION,
XEN_SYSCTL_MIN_INTERFACE_VERSION, XEN_SYSCTL_PHYSINFO, XEN_SYSCTL_PM_OP,
XEN_SYSCTL_PM_OP_DISABLE_TURBO, XEN_SYSCTL_PM_OP_ENABLE_TURBO,
XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_READCONSOLE,
};
use tokio::time::sleep;

Expand Down Expand Up @@ -417,6 +419,37 @@ impl XenCall {
Ok(unsafe { domctl.value.get_domain_info })
}

/// Enumerate Xen domains starting from `first_domid`.
///
/// Uses XEN_SYSCTL_getdomaininfolist which correctly enumerates domains
/// on all Xen versions (unlike XEN_DOMCTL_GETDOMAININFO which does
/// exact domid lookup on Xen 4.17+).
pub async fn get_domain_info_list(
&self,
first_domid: u16,
max_domains: u32,
) -> Result<Vec<GetDomainInfo>> {
let mut buffer = vec![GetDomainInfo::default(); max_domains as usize];
let mut sysctl = Sysctl {
cmd: XEN_SYSCTL_GETDOMAININFOLIST,
interface_version: self.sysctl_interface_version,
value: SysctlValue {
getdomaininfolist: SysctlGetdomaininfolist {
first_domain: first_domid,
pad: 0,
max_domains,
buffer: buffer.as_mut_ptr() as u64,
num_domains: 0,
},
},
};
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong)
.await?;
let count = unsafe { sysctl.value.getdomaininfolist.num_domains } as usize;
buffer.truncate(count);
Ok(buffer)
}

pub async fn create_domain(&self, create_domain: CreateDomain) -> Result<u32> {
trace!(
"domctl fd={} create_domain create_domain={:?}",
Expand Down
15 changes: 15 additions & 0 deletions crates/xen/xencall/src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,10 +807,24 @@ pub struct SysctlCputopoinfo {
pub handle: c_ulong,
}

/// Buffer-based domain enumeration via XEN_SYSCTL_getdomaininfolist.
/// Returns info for domains with domid >= first_domain, up to max_domains.
/// Layout matches xen/include/public/sysctl.h xen_sysctl_getdomaininfolist.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SysctlGetdomaininfolist {
pub first_domain: u16,
pub pad: u16,
pub max_domains: u32,
pub buffer: u64, // XEN_GUEST_HANDLE_64(xen_domctl_getdomaininfo_t)
pub num_domains: u32,
}

#[repr(C)]
pub union SysctlValue {
pub console: SysctlReadconsole,
pub cputopoinfo: SysctlCputopoinfo,
pub getdomaininfolist: SysctlGetdomaininfolist,
pub pm_op: SysctlPmOp,
pub phys_info: SysctlPhysinfo,
pub pad: [u8; 128],
Expand All @@ -825,6 +839,7 @@ pub struct Sysctl {

pub const XEN_SYSCTL_READCONSOLE: u32 = 1;
pub const XEN_SYSCTL_PHYSINFO: u32 = 3;
pub const XEN_SYSCTL_GETDOMAININFOLIST: u32 = 6;
pub const XEN_SYSCTL_PM_OP: u32 = 12;
pub const XEN_SYSCTL_CPUTOPOINFO: u32 = 16;

Expand Down