This adds support to issue the set irqfd ioctl via the privcmd file.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- V2: - Fixed comment
crates/xen-ioctls/src/private.rs | 14 +++++++- crates/xen-ioctls/src/xdm/types.rs | 14 ++++++++ crates/xen-ioctls/src/xdm/xdm.rs | 56 ++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/crates/xen-ioctls/src/private.rs b/crates/xen-ioctls/src/private.rs index 2d3379213e03..59a75f67f18d 100644 --- a/crates/xen-ioctls/src/private.rs +++ b/crates/xen-ioctls/src/private.rs @@ -14,8 +14,8 @@ use std::io::Error; use std::os::unix::io::AsRawFd; use vmm_sys_util::ioctl::_IOC_NONE;
+use crate::xdm::types::{PrivcmdDeviceModelIrqFd, PrivcmdDeviceModelOp}; use crate::xfm::types::{PrivCmdMmapBatchV2, PrivCmdMmapResource}; -use crate::xdm::types::PrivcmdDeviceModelOp;
pub const PAGE_SHIFT: u32 = 12; pub const PAGE_SIZE: u32 = 1 << PAGE_SHIFT; @@ -73,6 +73,18 @@ ioctl_ioc_nr!( std::mem::size_of::<PrivCmdMmapResource>() as u32 );
+/* + * #define IOCTL_PRIVCMD_IRQFD \ + * _IOC(_IOC_NONE, 'P', 8, sizeof(privcmd_irqfd_t)) + */ +ioctl_ioc_nr!( + IOCTL_PRIVCMD_IRQFD, + _IOC_NONE, + XEN_PRIVCMD_TYPE, + 8 as u32, + std::mem::size_of::<PrivcmdDeviceModelIrqFd>() as u32 +); + pub const HYPERCALL_EVTCHN: &str = "/dev/xen/evtchn"; pub const HYPERCALL_PRIVCMD: &str = "/dev/xen/privcmd"; pub const HYPERCALL_BUFFER_FILE: &str = "/dev/xen/hypercall"; diff --git a/crates/xen-ioctls/src/xdm/types.rs b/crates/xen-ioctls/src/xdm/types.rs index ea429558b852..b115ecb1b496 100644 --- a/crates/xen-ioctls/src/xdm/types.rs +++ b/crates/xen-ioctls/src/xdm/types.rs @@ -143,3 +143,17 @@ impl PrivcmdDeviceModelOp { PrivcmdDeviceModelOp { domid, num, ubufs } } } + +pub const PRIVCMD_IRQFD_FLAG_DEASSIGN: u32 = 1; + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +// tools/include/xen-sys/Linux/privcmd.h::privcmd_irqfd +pub struct PrivcmdDeviceModelIrqFd { + pub fd: u32, + pub flags: u32, + pub irq: u32, + pub domid: u16, + pub level: u8, + pub pad: u8, +} diff --git a/crates/xen-ioctls/src/xdm/xdm.rs b/crates/xen-ioctls/src/xdm/xdm.rs index 115724284b7e..fc8440528ba5 100644 --- a/crates/xen-ioctls/src/xdm/xdm.rs +++ b/crates/xen-ioctls/src/xdm/xdm.rs @@ -15,6 +15,8 @@ use std::fs::{File, OpenOptions}; use std::io::Error; use std::os::unix::io::AsRawFd;
+use vmm_sys_util::eventfd::EventFd; + #[cfg(target_arch = "aarch64")] use crate::aarch64::types::*; #[cfg(target_arch = "x86_64")] @@ -239,4 +241,58 @@ impl XenDeviceModelHandle {
do_dm_op(&self.fd, domid, &mut privcmd_dm_op_buffers) } + + pub fn config_irqfd( + &self, + fd: EventFd, + domid: u16, + irq: u32, + level: u8, + flags: u32, + ) -> Result<(), std::io::Error> { + let mut irqfd = PrivcmdDeviceModelIrqFd { + fd: fd.as_raw_fd() as u32, + flags, + irq, + domid, + level, + pad: 0, + }; + + let ret = unsafe { + // The expression "&mut irqfd as *mut _" creates a reference to irqfd before casting it + // to a *mut c_void. + ioctl( + self.fd.as_raw_fd(), + IOCTL_PRIVCMD_IRQFD(), + &mut irqfd as *mut _ as *mut c_void, + ) + }; + + if ret < 0 { + return Err(Error::last_os_error()); + } + + Ok(()) + } + + pub fn set_irqfd( + &self, + fd: EventFd, + domid: u16, + irq: u32, + level: u8, + ) -> Result<(), std::io::Error> { + self.config_irqfd(fd, domid, irq, level, 0) + } + + pub fn clear_irqfd( + &self, + fd: EventFd, + domid: u16, + irq: u32, + level: u8, + ) -> Result<(), std::io::Error> { + self.config_irqfd(fd, domid, irq, level, PRIVCMD_IRQFD_FLAG_DEASSIGN) + } }
stratos-dev@op-lists.linaro.org