diff --git a/crates/xen/xencall/examples/console_read.rs b/crates/xen/xencall/examples/console_read.rs new file mode 100644 index 0000000..96a4aae --- /dev/null +++ b/crates/xen/xencall/examples/console_read.rs @@ -0,0 +1,18 @@ +use xencall::error::Result; +use xencall::XenCall; + +#[tokio::main] +async fn main() -> Result<()> { + env_logger::init(); + + let call = XenCall::open(0)?; + let index = 0 as u32; + let (buf, newindex) = call.read_console_ring_raw(false, index).await?; + + match std::str::from_utf8(&buf[..newindex as usize]) { + Ok(v) => print!("{}", v), + _ => panic!("unable to decode Xen console messages"), + }; + + Ok(()) +} diff --git a/crates/xen/xencall/src/lib.rs b/crates/xen/xencall/src/lib.rs index 531122f..a69f989 100644 --- a/crates/xen/xencall/src/lib.rs +++ b/crates/xen/xencall/src/lib.rs @@ -26,12 +26,12 @@ use std::sync::Arc; use std::time::Duration; use sys::{ CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, Sysctl, SysctlCputopo, SysctlCputopoinfo, - SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlSetCpuFreqGov, SysctlValue, + SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlSetCpuFreqGov, SysctlValue, SysctlReadconsole, VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP, HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ, XEN_DOMCTL_MAX_INTERFACE_VERSION, XEN_DOMCTL_MIN_INTERFACE_VERSION, 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_PM_OP_ENABLE_TURBO, XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_READCONSOLE, }; use tokio::sync::Semaphore; use tokio::time::sleep; @@ -1087,4 +1087,31 @@ impl XenCall { .await?; Ok(()) } + + pub async fn read_console_ring_raw(&self, clear: bool, index: u32) -> Result<([u8; 16384], u32)> { + let mut u8buf = [0u8; 16384]; + let mut sysctl = Sysctl { + cmd: XEN_SYSCTL_READCONSOLE, + interface_version: self.sysctl_interface_version, + value: SysctlValue { + console: SysctlReadconsole { + clear: clear as u8, + incremental: 1, + pad: 0, + index: index, + buffer: addr_of_mut!(u8buf) as u64, + count: 16384, + }, + }, + }; + self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong) + .await?; + // Safety: We are passing a SysctlReadconsole struct as part of the hypercall, and + // calling the hypercall is known to not change the underlying value outside changing + // the values on some SysctlReadconsole fields. + let newindex = unsafe { + sysctl.value.console.index + }; + Ok((u8buf, newindex)) + } }