Add support for reading hypervisor console (#344)

* feature(xencall): add hypervisor SYSCTL_readconsole definitions

* feature(hypervisor-dmesg): xencall: add read_console_ring_raw hypercall wrapper

* feature(hypervisor-dmesg): protobuf: add ReadHypervisorConsoleRing RPC

* feature(hypervisor-dmesg): runtime: add read_hypervisor_console wrapper

* feature(hypervisor-dmesg): daemon: add ReadHypervisorConsoleRing rpc implementation

* feature(hypervisor-dmesg): ctl: add host hypervisor-messages command to get hypervisor messages

* feature(hypervisor-dmesg): cli: rename hypervisor-messages command to hv-console

* feature(hypervisor-dmesg): proto: change ReadHypervisorConsoleRing to ReadHypervisorConsole

* feature(hypervisor-dmesg): fix up kratactl protobuf calls
This commit is contained in:
Ariadne Conill
2024-08-19 16:49:02 -07:00
committed by GitHub
parent 2519d76479
commit 2ab2cda937
8 changed files with 118 additions and 2 deletions

View File

@ -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(())
}

View File

@ -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))
}
}

View File

@ -752,6 +752,7 @@ pub struct SysctlCputopoinfo {
#[repr(C)]
pub union SysctlValue {
pub console: SysctlReadconsole,
pub cputopoinfo: SysctlCputopoinfo,
pub pm_op: SysctlPmOp,
pub phys_info: SysctlPhysinfo,
@ -765,6 +766,7 @@ pub struct Sysctl {
pub value: SysctlValue,
}
pub const XEN_SYSCTL_READCONSOLE: u32 = 1;
pub const XEN_SYSCTL_PHYSINFO: u32 = 3;
pub const XEN_SYSCTL_PM_OP: u32 = 12;
pub const XEN_SYSCTL_CPUTOPOINFO: u32 = 16;
@ -802,3 +804,14 @@ pub struct SysctlPhysinfo {
pub max_mfn: u64,
pub hw_cap: [u32; 8],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SysctlReadconsole {
pub clear: u8,
pub incremental: u8,
pub pad: u16,
pub index: u32,
pub buffer: u64,
pub count: u32,
}