diff --git a/src/linux/vcpu.rs b/src/linux/vcpu.rs index 4f50f5fb..c435e92c 100755 --- a/src/linux/vcpu.rs +++ b/src/linux/vcpu.rs @@ -378,6 +378,9 @@ impl VirtualCPU for UhyveCPU { Hypercall::FileWrite(syswrite) => self.write(syswrite)?, Hypercall::FileUnlink(sysunlink) => self.unlink(sysunlink), Hypercall::SerialWriteByte(buf) => self.uart(&[buf])?, + Hypercall::SerialWriteBuffer(sysserialwrite) => { + self.uart_buffer(sysserialwrite)? + } _ => panic!("Got unknown hypercall {:?}", hypercall), }; } else { diff --git a/src/macos/aarch64/vcpu.rs b/src/macos/aarch64/vcpu.rs index 6758c26e..7550171e 100644 --- a/src/macos/aarch64/vcpu.rs +++ b/src/macos/aarch64/vcpu.rs @@ -187,6 +187,13 @@ impl VirtualCPU for UhyveCPU { self.uart(&[x8]).unwrap(); } + Hypercall::SerialWriteBuffer(sysserialwrite) => { + let data_addr = self.vcpu.read_register(Register::X8)?; + let sysuart = unsafe { + &*(self.host_address(data_addr as usize) as *const SysUart) + }; + self.uart_buffer(sysuart).unwrap(); + } Hypercall::Exit(sysexit) => { return Ok(VcpuStopReason::Exit(self.exit(sysexit))); } diff --git a/src/macos/x86_64/vcpu.rs b/src/macos/x86_64/vcpu.rs index 764b25e1..3d810cfc 100644 --- a/src/macos/x86_64/vcpu.rs +++ b/src/macos/x86_64/vcpu.rs @@ -768,6 +768,10 @@ impl VirtualCPU for UhyveCPU { let al = (self.vcpu.read_register(&Register::RAX)? & 0xFF) as u8; self.uart(&[al]).unwrap(); } + Hypercall::SerialWriteBuffer(sysserialwrite) => { + self.uart_buffer(sysserialwrite).unwrap(); + } + _ => panic!("Got unknown hypercall {:?}", hypercall), } self.vcpu.write_register(&Register::RIP, rip + len)?; diff --git a/src/vm.rs b/src/vm.rs index 7c702c20..fdf16958 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -119,8 +119,9 @@ pub trait VirtualCPU { Hypercall::Cmdval(syscmdval) } HypercallAddress::Uart => Hypercall::SerialWriteByte(data as u8), - HypercallAddress::SerialWriteBuffer => { - let syscmdval = unsafe { &*(self.host_address(data) as *const SerialWriteBufferParams) }; + HypercallAddress::SerialBufferWrite => { + let syscmdval = + unsafe { &*(self.host_address(data) as *const SerialWriteBufferParams) }; Hypercall::SerialWriteBuffer(syscmdval) } _ => unimplemented!(), @@ -303,8 +304,9 @@ pub trait VirtualCPU { } /// Handles a UART syscall by contructing a buffer from parameter - fn uart_buffer(&self, sysuart: &SysUart) -> io::Result<()> { - let buf_addr = self.virt_to_phys(sysuart.buf as usize) as *const u8; + fn uart_buffer(&self, sysuart: &SerialWriteBufferParams) -> io::Result<()> { + let buf_addr = self.virt_to_phys(sysuart.buf.as_u64() as usize) as *const u8; + // TODO: Check that we don't have an out ouf bounds read (stay inside vm memory) let buf = unsafe { std::slice::from_raw_parts(buf_addr, sysuart.len) }; io::stdout().write_all(buf) } diff --git a/uhyve-interface/src/parameters.rs b/uhyve-interface/src/parameters.rs index 2066469f..22405969 100644 --- a/uhyve-interface/src/parameters.rs +++ b/uhyve-interface/src/parameters.rs @@ -112,6 +112,6 @@ pub struct LseekParams { #[repr(C, packed)] #[derive(Debug, Copy, Clone)] pub struct SerialWriteBufferParams { - buf: PhysAddr, - len: usize, + pub buf: PhysAddr, + pub len: usize, }