mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 12:50:54 +00:00
feat(xencall): improve asynchronous support
This commit is contained in:
parent
d7affe6c8c
commit
895b84e22d
@ -1,5 +1,7 @@
|
||||
use std::io;
|
||||
|
||||
use tokio::task::JoinError;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("version of xen is not supported")]
|
||||
@ -16,6 +18,8 @@ pub enum Error {
|
||||
MmapBatchFailed(nix::errno::Errno),
|
||||
#[error("specified value is too long")]
|
||||
ValueTooLong,
|
||||
#[error("failed to join async task: {0}")]
|
||||
JoinError(JoinError),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -35,7 +35,6 @@ use sys::{
|
||||
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::sync::Semaphore;
|
||||
use tokio::time::sleep;
|
||||
|
||||
use std::fs::{File, OpenOptions};
|
||||
@ -46,7 +45,6 @@ use std::slice;
|
||||
#[derive(Clone)]
|
||||
pub struct XenCall {
|
||||
pub handle: Arc<File>,
|
||||
semaphore: Arc<Semaphore>,
|
||||
domctl_interface_version: u32,
|
||||
sysctl_interface_version: u32,
|
||||
}
|
||||
@ -62,7 +60,6 @@ impl XenCall {
|
||||
let sysctl_interface_version = XenCall::detect_sysctl_interface_version(&handle)?;
|
||||
Ok(XenCall {
|
||||
handle: Arc::new(handle),
|
||||
semaphore: Arc::new(Semaphore::new(1)),
|
||||
domctl_interface_version,
|
||||
sysctl_interface_version,
|
||||
})
|
||||
@ -119,7 +116,6 @@ impl XenCall {
|
||||
}
|
||||
|
||||
pub async fn mmap(&self, addr: u64, len: u64) -> Option<u64> {
|
||||
let _permit = self.semaphore.acquire().await.ok()?;
|
||||
trace!(
|
||||
"call fd={} mmap addr={:#x} len={}",
|
||||
self.handle.as_raw_fd(),
|
||||
@ -127,14 +123,20 @@ impl XenCall {
|
||||
len
|
||||
);
|
||||
unsafe {
|
||||
let ptr = mmap(
|
||||
addr as *mut c_void,
|
||||
len as usize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
self.handle.as_raw_fd(),
|
||||
0,
|
||||
);
|
||||
let handle = self.handle.clone();
|
||||
let ptr = tokio::task::spawn_blocking(move || {
|
||||
mmap(
|
||||
addr as *mut c_void,
|
||||
len as usize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
handle.as_raw_fd(),
|
||||
0,
|
||||
) as u64
|
||||
})
|
||||
.await
|
||||
.map_err(Error::JoinError)
|
||||
.ok()? as *mut c_void;
|
||||
if ptr == MAP_FAILED {
|
||||
None
|
||||
} else {
|
||||
@ -151,18 +153,22 @@ impl XenCall {
|
||||
}
|
||||
|
||||
pub async fn hypercall(&self, op: c_ulong, arg: [c_ulong; 5]) -> Result<c_long> {
|
||||
let _permit = self.semaphore.acquire().await?;
|
||||
trace!(
|
||||
"call fd={} hypercall op={:#x} arg={:?}",
|
||||
self.handle.as_raw_fd(),
|
||||
op,
|
||||
arg
|
||||
);
|
||||
unsafe {
|
||||
|
||||
let handle = self.handle.clone();
|
||||
tokio::task::spawn_blocking(move || unsafe {
|
||||
let mut call = Hypercall { op, arg };
|
||||
let result = sys::hypercall(self.handle.as_raw_fd(), &mut call)?;
|
||||
Ok(result as c_long)
|
||||
}
|
||||
sys::hypercall(handle.as_raw_fd(), &mut call)
|
||||
.map(|x| x as c_long)
|
||||
.map_err(|e| e.into())
|
||||
})
|
||||
.await
|
||||
.map_err(Error::JoinError)?
|
||||
}
|
||||
|
||||
pub async fn hypercall0(&self, op: c_ulong) -> Result<c_long> {
|
||||
@ -234,18 +240,21 @@ impl XenCall {
|
||||
num: u64,
|
||||
addr: u64,
|
||||
) -> Result<()> {
|
||||
let _permit = self.semaphore.acquire().await?;
|
||||
let mut resource = MmapResource {
|
||||
dom: domid as u16,
|
||||
typ,
|
||||
id,
|
||||
idx,
|
||||
num,
|
||||
addr,
|
||||
};
|
||||
unsafe {
|
||||
sys::mmap_resource(self.handle.as_raw_fd(), &mut resource)?;
|
||||
}
|
||||
let handle = self.handle.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let mut resource = MmapResource {
|
||||
dom: domid as u16,
|
||||
typ,
|
||||
id,
|
||||
idx,
|
||||
num,
|
||||
addr,
|
||||
};
|
||||
|
||||
unsafe { sys::mmap_resource(handle.as_raw_fd(), &mut resource) }
|
||||
})
|
||||
.await
|
||||
.map_err(Error::JoinError)??;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -256,7 +265,6 @@ impl XenCall {
|
||||
addr: u64,
|
||||
mfns: Vec<u64>,
|
||||
) -> Result<c_long> {
|
||||
let _permit = self.semaphore.acquire().await?;
|
||||
trace!(
|
||||
"call fd={} mmap_batch domid={} num={} addr={:#x} mfns={:?}",
|
||||
self.handle.as_raw_fd(),
|
||||
@ -322,7 +330,7 @@ impl XenCall {
|
||||
break;
|
||||
}
|
||||
|
||||
let count = result.unwrap();
|
||||
let count = result?;
|
||||
if count <= 0 {
|
||||
break;
|
||||
}
|
||||
@ -330,7 +338,7 @@ impl XenCall {
|
||||
|
||||
return Ok(paged as c_long);
|
||||
}
|
||||
Ok(result.unwrap() as c_long)
|
||||
Ok(result? as c_long)
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,6 +626,11 @@ impl XenCall {
|
||||
}
|
||||
|
||||
pub async fn get_memory_map(&self, max_entries: u32) -> Result<Vec<E820Entry>> {
|
||||
trace!(
|
||||
"fd={} get_memory_map max_entries={}",
|
||||
self.handle.as_raw_fd(),
|
||||
max_entries,
|
||||
);
|
||||
let mut memory_map = MemoryMap {
|
||||
count: max_entries,
|
||||
buffer: 0,
|
||||
|
@ -205,6 +205,16 @@ pub const XEN_DOMCTL_GDBSX_PAUSEVCPU: u32 = 1001;
|
||||
pub const XEN_DOMCTL_GDBSX_UNPAUSEVCPU: u32 = 1002;
|
||||
pub const XEN_DOMCTL_GDBSX_DOMSTATUS: u32 = 1003;
|
||||
|
||||
pub const XEN_DOMINF_DYING: u32 = 1u32 << 0;
|
||||
pub const XEN_DOMINF_HVM_GUEST: u32 = 1u32 << 1;
|
||||
pub const XEN_DOMINF_SHUTDOWN: u32 = 1u32 << 2;
|
||||
pub const XEN_DOMINF_PAUSED: u32 = 1u32 << 3;
|
||||
pub const XEN_DOMINF_BLOCKED: u32 = 1u32 << 4;
|
||||
pub const XEN_DOMINF_RUNNING: u32 = 1u32 << 5;
|
||||
pub const XEN_DOMINF_DEBUGGED: u32 = 1u32 << 6;
|
||||
pub const XEN_DOMINF_XS_DOMAIN: u32 = 1u32 << 7;
|
||||
pub const XEN_DOMINF_HAP: u32 = 1u32 << 8;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct DomCtl {
|
||||
|
Loading…
Reference in New Issue
Block a user