unpause domain so domain can run during boot

This commit is contained in:
Alex Zenla 2024-01-17 01:41:17 -08:00
parent 5c1bb3d8fc
commit 6ca61410ad
No known key found for this signature in database
GPG Key ID: 067B238899B51269
7 changed files with 68 additions and 8 deletions

View File

@ -5,7 +5,7 @@ use crate::sys::{
XEN_DOMCTL_GETDOMAININFO, XEN_DOMCTL_GETPAGEFRAMEINFO3, XEN_DOMCTL_GETVCPUCONTEXT, XEN_DOMCTL_GETDOMAININFO, XEN_DOMCTL_GETPAGEFRAMEINFO3, XEN_DOMCTL_GETVCPUCONTEXT,
XEN_DOMCTL_HYPERCALL_INIT, XEN_DOMCTL_INTERFACE_VERSION, XEN_DOMCTL_MAX_MEM, XEN_DOMCTL_HYPERCALL_INIT, XEN_DOMCTL_INTERFACE_VERSION, XEN_DOMCTL_MAX_MEM,
XEN_DOMCTL_MAX_VCPUS, XEN_DOMCTL_PAUSEDOMAIN, XEN_DOMCTL_SETVCPUCONTEXT, XEN_DOMCTL_MAX_VCPUS, XEN_DOMCTL_PAUSEDOMAIN, XEN_DOMCTL_SETVCPUCONTEXT,
XEN_DOMCTL_SET_ADDRESS_SIZE, XEN_DOMCTL_SET_ADDRESS_SIZE, XEN_DOMCTL_UNPAUSEDOMAIN,
}; };
use crate::{XenCall, XenCallError}; use crate::{XenCall, XenCallError};
use log::trace; use log::trace;
@ -98,6 +98,23 @@ impl DomainControl<'_> {
Ok(()) Ok(())
} }
pub fn unpause_domain(&self, domid: u32) -> Result<(), XenCallError> {
trace!(
"domctl fd={} unpause_domain domid={:?}",
self.call.handle.as_raw_fd(),
domid,
);
let mut domctl = DomCtl {
cmd: XEN_DOMCTL_UNPAUSEDOMAIN,
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
domid,
value: DomCtlValue { pad: [0; 128] },
};
self.call
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
Ok(())
}
pub fn set_max_mem(&self, domid: u32, memkb: u64) -> Result<(), XenCallError> { pub fn set_max_mem(&self, domid: u32, memkb: u64) -> Result<(), XenCallError> {
trace!( trace!(
"domctl fd={} set_max_mem domid={} memkb={}", "domctl fd={} set_max_mem domid={} memkb={}",

View File

@ -3,10 +3,10 @@ pub mod memory;
pub mod sys; pub mod sys;
use crate::sys::{ use crate::sys::{
Hypercall, MmapBatch, MmapResource, MultiCallEntry, XenCapabilitiesInfo, HYPERVISOR_MULTICALL, EvtChnAllocUnbound, Hypercall, MmapBatch, MmapResource, MultiCallEntry, XenCapabilitiesInfo,
HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES, HYPERVISOR_EVENT_CHANNEL_OP, HYPERVISOR_MULTICALL, HYPERVISOR_XEN_VERSION, XENVER_CAPABILITIES,
}; };
use libc::{mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; use libc::{c_int, mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use log::trace; use log::trace;
use nix::errno::Errno; use nix::errno::Errno;
use std::error::Error; use std::error::Error;
@ -236,4 +236,19 @@ impl XenCall {
)?; )?;
Ok(info) Ok(info)
} }
pub fn evtchn_op(&self, cmd: c_int, arg: u64) -> Result<(), XenCallError> {
self.hypercall2(HYPERVISOR_EVENT_CHANNEL_OP, cmd as c_ulong, arg)?;
Ok(())
}
pub fn evtchn_alloc_unbound(&self, domid: u32, remote_domid: u32) -> Result<u32, XenCallError> {
let mut alloc_unbound = EvtChnAllocUnbound {
dom: domid as u16,
remote_dom: remote_domid as u16,
port: 0,
};
self.evtchn_op(6, addr_of_mut!(alloc_unbound) as c_ulong)?;
Ok(alloc_unbound.port)
}
} }

View File

@ -496,3 +496,11 @@ pub struct MmuExtOp {
} }
pub const MMUEXT_PIN_L4_TABLE: u32 = 3; pub const MMUEXT_PIN_L4_TABLE: u32 = 3;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EvtChnAllocUnbound {
pub dom: u16,
pub remote_dom: u16,
pub port: u32,
}

View File

@ -19,6 +19,9 @@ path = "../xencall"
[dependencies.xenstore] [dependencies.xenstore]
path = "../xenstore" path = "../xenstore"
[dependencies.xenevtchn]
path = "../xenevtchn"
[dependencies.uuid] [dependencies.uuid]
version = "1.6.1" version = "1.6.1"
features = ["v4"] features = ["v4"]

View File

@ -7,6 +7,7 @@ use xencall::XenCall;
use xenclient::boot::BootSetup; use xenclient::boot::BootSetup;
use xenclient::elfloader::ElfImageLoader; use xenclient::elfloader::ElfImageLoader;
use xenclient::XenClientError; use xenclient::XenClientError;
use xenevtchn::EventChannel;
fn main() -> Result<(), XenClientError> { fn main() -> Result<(), XenClientError> {
env_logger::init(); env_logger::init();
@ -48,6 +49,10 @@ fn boot(
let mut boot = BootSetup::new(call, domctl, &memctl, domid); let mut boot = BootSetup::new(call, domctl, &memctl, domid);
let initrd = read(initrd_path)?; let initrd = read(initrd_path)?;
let mut state = boot.initialize(&image_loader, initrd.as_slice(), 1, 512)?; let mut state = boot.initialize(&image_loader, initrd.as_slice(), 1, 512)?;
boot.boot(&mut state, "debug")?; boot.boot(&mut state, "debug elevator=noop")?;
domctl.unpause_domain(domid)?;
let _evtchn = EventChannel::open()?;
Ok(()) Ok(())
} }

View File

@ -82,6 +82,8 @@ pub struct BootState {
pub image_info: BootImageInfo, pub image_info: BootImageInfo,
pub shared_info_frame: u64, pub shared_info_frame: u64,
pub initrd_segment: DomainSegment, pub initrd_segment: DomainSegment,
pub store_evtchn: u32,
pub console_evtchn: u32,
} }
impl BootSetup<'_> { impl BootSetup<'_> {
@ -282,7 +284,8 @@ impl BootSetup<'_> {
} }
let initrd_segment = initrd_segment.unwrap(); let initrd_segment = initrd_segment.unwrap();
let store_evtchn = self.domctl.call.evtchn_alloc_unbound(self.domid, 0)?;
let console_evtchn = self.domctl.call.evtchn_alloc_unbound(self.domid, 0)?;
let state = BootState { let state = BootState {
kernel_segment, kernel_segment,
start_info_segment, start_info_segment,
@ -294,6 +297,8 @@ impl BootSetup<'_> {
page_table, page_table,
image_info, image_info,
initrd_segment, initrd_segment,
store_evtchn,
console_evtchn,
shared_info_frame: 0, shared_info_frame: 0,
}; };
debug!("BootSetup initialize state={:?}", state); debug!("BootSetup initialize state={:?}", state);
@ -491,10 +496,10 @@ impl BootSetup<'_> {
(*info).first_p2m_pfn = state.p2m_segment.pfn; (*info).first_p2m_pfn = state.p2m_segment.pfn;
(*info).nr_p2m_frames = state.p2m_segment.pages; (*info).nr_p2m_frames = state.p2m_segment.pages;
(*info).flags = 0; (*info).flags = 0;
(*info).store_evtchn = 0; (*info).store_evtchn = state.store_evtchn;
(*info).store_mfn = self.phys.p2m[state.xenstore_segment.pfn as usize]; (*info).store_mfn = self.phys.p2m[state.xenstore_segment.pfn as usize];
(*info).console.mfn = self.phys.p2m[state.console_segment.pfn as usize]; (*info).console.mfn = self.phys.p2m[state.console_segment.pfn as usize];
(*info).console.evtchn = 0; (*info).console.evtchn = state.console_evtchn;
(*info).mod_start = state.initrd_segment.vstart; (*info).mod_start = state.initrd_segment.vstart;
(*info).mod_len = state.initrd_segment.size; (*info).mod_len = state.initrd_segment.size;
for (i, c) in cmdline.chars().enumerate() { for (i, c) in cmdline.chars().enumerate() {

View File

@ -12,6 +12,7 @@ use std::string::FromUtf8Error;
use xencall::domctl::DomainControl; use xencall::domctl::DomainControl;
use xencall::sys::CreateDomain; use xencall::sys::CreateDomain;
use xencall::{XenCall, XenCallError}; use xencall::{XenCall, XenCallError};
use xenevtchn::EventChannelError;
use xenstore::bus::XsdBusError; use xenstore::bus::XsdBusError;
use xenstore::client::{XsdClient, XsdInterface}; use xenstore::client::{XsdClient, XsdInterface};
@ -69,6 +70,12 @@ impl From<FromUtf8Error> for XenClientError {
} }
} }
impl From<EventChannelError> for XenClientError {
fn from(value: EventChannelError) -> Self {
XenClientError::new(value.to_string().as_str())
}
}
impl XenClient { impl XenClient {
pub fn open() -> Result<XenClient, XenClientError> { pub fn open() -> Result<XenClient, XenClientError> {
let store = XsdClient::open()?; let store = XsdClient::open()?;