mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										18
									
								
								crates/xen/xencall/examples/console_read.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								crates/xen/xencall/examples/console_read.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
}
 | 
			
		||||
@ -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))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user