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