diff --git a/Cargo.lock b/Cargo.lock index 433c09fb5c..c6bea15573 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,22 +4,22 @@ version = 4 [[package]] name = "aarch64" -version = "0.0.13" +version = "0.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfa8287e400aa9af0c4e0c93967882634f7972b94b74fd5110507b486a1ced4" +checksum = "2df0852593ebb4ed15e4fce123daf16a272b8d4449ae75050d6b9d7cea461a21" dependencies = [ - "aarch64-cpu 9.4.0", + "aarch64-cpu 10.0.0", "memory_addresses", - "tock-registers 0.8.1", + "tock-registers 0.9.0", ] [[package]] name = "aarch64-cpu" -version = "9.4.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287" +checksum = "6a21cd0131c25c438e19cd6a774adf7e3f64f7f4d723022882facc2dee0f8bc9" dependencies = [ - "tock-registers 0.8.1", + "tock-registers 0.9.0", ] [[package]] @@ -810,6 +810,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hermit-entry" version = "0.10.7" @@ -1973,9 +1979,9 @@ dependencies = [ [[package]] name = "tock-registers" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "696941a0aee7e276a165a978b37918fd5d22c55c3d6bda197813070ca9c0f21c" +checksum = "2b9e2fdb3a1e862c0661768b7ed25390811df1947a8acbfbefe09b47078d93c4" [[package]] name = "tock-registers" @@ -2011,11 +2017,12 @@ dependencies = [ [[package]] name = "uhyve-interface" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7390116b0481b52dbc7d979f858dcc426494714a3ba03e9534d26c8ea41b899e" +version = "0.2.0" +source = "git+https://github.com/n0toose/uhyve?branch=uhyve_if_v2-mmiowrite#954e7e173288aebbe42a0a96a90194f78d9344ea" dependencies = [ "aarch64", + "bitflags 2.10.0", + "hermit-abi", "memory_addresses", "num_enum", "x86_64", diff --git a/Cargo.toml b/Cargo.toml index 1f7f2512d7..ea79120d37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,7 +135,7 @@ thiserror = { version = "2", default-features = false } time = { version = "0.3", default-features = false } volatile = "0.6" zerocopy = { version = "0.8", default-features = false } -uhyve-interface = "0.1.3" +uhyve-interface = "0.2.0" [dependencies.smoltcp] version = "0.12" @@ -204,6 +204,7 @@ exclude = [ ] [patch.crates-io] +uhyve-interface = { git = "https://github.com/n0toose/uhyve", branch = 'uhyve_if_v2-mmiowrite' } # FIXME: remove once merged: https://github.com/rcore-os/trapframe-rs/pull/16 trapframe = { git = "https://github.com/hermit-os/trapframe-rs", branch = "global_asm" } safe-mmio = { git = "https://github.com/hermit-os/safe-mmio", branch = "be" } diff --git a/src/fd/stdio.rs b/src/fd/stdio.rs index 7c9ed14c5b..c1e97cdc8f 100644 --- a/src/fd/stdio.rs +++ b/src/fd/stdio.rs @@ -4,9 +4,12 @@ use core::task::Poll; use async_trait::async_trait; use embedded_io::{Read, ReadReady, Write}; -use uhyve_interface::parameters::WriteParams; -use uhyve_interface::{GuestVirtAddr, Hypercall}; +use memory_addresses::VirtAddr; +use uhyve_interface::GuestPhysAddr; +use uhyve_interface::v2::Hypercall; +use uhyve_interface::v2::parameters::WriteParams; +use crate::arch::mm::paging; use crate::console::{CONSOLE, CONSOLE_WAKER}; use crate::fd::{ AccessPermission, FileAttr, ObjectInterface, PollEvent, STDERR_FILENO, STDOUT_FILENO, @@ -161,12 +164,16 @@ impl ObjectInterface for UhyveStdout { async fn write(&self, buf: &[u8]) -> io::Result { let write_params = WriteParams { fd: STDOUT_FILENO, - buf: GuestVirtAddr::new(buf.as_ptr() as u64), - len: buf.len(), + buf: GuestPhysAddr::new( + paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr())) + .unwrap() + .as_u64(), + ), + len: buf.len().try_into().unwrap(), }; uhyve_hypercall(Hypercall::FileWrite(&write_params)); - Ok(write_params.len) + Ok(write_params.len.try_into().unwrap()) } async fn isatty(&self) -> io::Result { @@ -200,12 +207,16 @@ impl ObjectInterface for UhyveStderr { async fn write(&self, buf: &[u8]) -> io::Result { let write_params = WriteParams { fd: STDERR_FILENO, - buf: GuestVirtAddr::new(buf.as_ptr() as u64), - len: buf.len(), + buf: GuestPhysAddr::new( + paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr())) + .unwrap() + .as_u64(), + ), + len: buf.len().try_into().unwrap(), }; uhyve_hypercall(Hypercall::FileWrite(&write_params)); - Ok(write_params.len) + Ok(write_params.len.try_into().unwrap()) } async fn isatty(&self) -> io::Result { diff --git a/src/fs/uhyve.rs b/src/fs/uhyve.rs index ec627c1919..63680efd25 100644 --- a/src/fs/uhyve.rs +++ b/src/fs/uhyve.rs @@ -9,10 +9,11 @@ use async_lock::Mutex; use async_trait::async_trait; use embedded_io::{ErrorType, Read, Write}; use memory_addresses::VirtAddr; -use uhyve_interface::parameters::{ +use uhyve_interface::GuestPhysAddr; +use uhyve_interface::v2::Hypercall; +use uhyve_interface::v2::parameters::{ CloseParams, LseekParams, OpenParams, ReadParams, UnlinkParams, WriteParams, }; -use uhyve_interface::{GuestPhysAddr, GuestVirtAddr, Hypercall}; use crate::arch::mm::paging; use crate::env::fdt; @@ -56,8 +57,12 @@ impl Read for UhyveFileHandleInner { fn read(&mut self, buf: &mut [u8]) -> Result { let mut read_params = ReadParams { fd: self.0, - buf: GuestVirtAddr::new(buf.as_mut_ptr() as u64), - len: buf.len(), + buf: GuestPhysAddr::new( + paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_mut_ptr())) + .unwrap() + .as_u64(), + ), + len: buf.len().try_into().unwrap(), ret: 0, }; uhyve_hypercall(Hypercall::FileRead(&mut read_params)); @@ -74,12 +79,16 @@ impl Write for UhyveFileHandleInner { fn write(&mut self, buf: &[u8]) -> Result { let write_params = WriteParams { fd: self.0, - buf: GuestVirtAddr::new(buf.as_ptr() as u64), - len: buf.len(), + buf: GuestPhysAddr::new( + paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr())) + .unwrap() + .as_u64(), + ), + len: buf.len().try_into().unwrap(), }; uhyve_hypercall(Hypercall::FileWrite(&write_params)); - Ok(write_params.len) + Ok(write_params.len.try_into().unwrap()) } fn flush(&mut self) -> Result<(), Self::Error> { diff --git a/src/syscalls/interfaces/uhyve.rs b/src/syscalls/interfaces/uhyve.rs index 06dde48495..3096e3a288 100644 --- a/src/syscalls/interfaces/uhyve.rs +++ b/src/syscalls/interfaces/uhyve.rs @@ -1,14 +1,14 @@ use core::ptr; use memory_addresses::VirtAddr; -use uhyve_interface::parameters::{ExitParams, SerialWriteBufferParams}; -use uhyve_interface::{Hypercall, HypercallAddress}; +use uhyve_interface::v2::parameters::SerialWriteBufferParams; +use uhyve_interface::v2::{Hypercall, HypercallAddress}; use crate::arch; use crate::arch::mm::paging::{self, virtual_to_physical}; use crate::syscalls::interfaces::SyscallInterface; -/// perform a SerialWriteBuffer hypercall with `buf` as payload. +/// perform a SerialWriteBuffer hypercall with `buf` as payload #[inline] #[cfg_attr(target_arch = "riscv64", expect(dead_code))] pub(crate) fn serial_buf_hypercall(buf: &[u8]) { @@ -31,9 +31,11 @@ fn data_addr(data: &T) -> u64 { #[inline] fn hypercall_data(hypercall: &Hypercall<'_>) -> u64 { match hypercall { - Hypercall::Cmdsize(data) => data_addr(*data), - Hypercall::Cmdval(data) => data_addr(*data), - Hypercall::Exit(data) => data_addr(*data), + // As we are encoding an exit code (max 32 bits) into "an + // address", and memory_addresses complains if an address + // has any bits above the 48th one set to 1, we encode + // potential negative numbers into a u32, then a u64. + Hypercall::Exit(exit_code) => u64::from((*exit_code) as u32), Hypercall::FileClose(data) => data_addr(*data), Hypercall::FileLseek(data) => data_addr(*data), Hypercall::FileOpen(data) => data_addr(*data), @@ -50,16 +52,13 @@ fn hypercall_data(hypercall: &Hypercall<'_>) -> u64 { #[inline] #[allow(unused_variables)] // until riscv64 is implemented pub(crate) fn uhyve_hypercall(hypercall: Hypercall<'_>) { - let ptr = HypercallAddress::from(&hypercall) as u16; + let ptr = HypercallAddress::from(&hypercall) as u64; let data = hypercall_data(&hypercall); #[cfg(target_arch = "x86_64")] - unsafe { - use x86_64::instructions::port::Port; - - let data = - u32::try_from(data).expect("Hypercall data must lie in the first 4GiB of memory"); - Port::new(ptr).write(data); + { + let ptr = ptr as *mut u64; + unsafe { ptr.write_volatile(data) }; } #[cfg(target_arch = "aarch64")] @@ -67,7 +66,7 @@ pub(crate) fn uhyve_hypercall(hypercall: Hypercall<'_>) { use core::arch::asm; asm!( "str x8, [{ptr}]", - ptr = in(reg) u64::from(ptr), + ptr = in(reg) ptr, in("x8") data, options(nostack), ); @@ -81,8 +80,7 @@ pub struct Uhyve; impl SyscallInterface for Uhyve { fn shutdown(&self, error_code: i32) -> ! { - let sysexit = ExitParams { arg: error_code }; - uhyve_hypercall(Hypercall::Exit(&sysexit)); + uhyve_hypercall(Hypercall::Exit(error_code)); loop { arch::processor::halt();