Skip to content

Commit 6ad459d

Browse files
n0toosefogti
andcommitted
feat(uhyve): use v2 interface
On x86_64, the data address will be stored in the rcx register to support 64-bit addresses. This also removes the usage of ExitArgs, as it is a single integer. Co-authored-by: Ellen Εμιλία Άννα Zscheile <fogti+devel@ytrizja.de> Helped-by: Jonathan Klimt <jonathan.klimt@eonerc.rwth-aachen.de>
1 parent 4e2eb9e commit 6ad459d

File tree

5 files changed

+54
-33
lines changed

5 files changed

+54
-33
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ thiserror = { version = "2", default-features = false }
141141
time = { version = "0.3", default-features = false }
142142
volatile = "0.6"
143143
zerocopy = { version = "0.8", default-features = false }
144-
uhyve-interface = "0.1.4"
144+
uhyve-interface = "0.2.0"
145145

146146
[dependencies.smoltcp]
147147
version = "0.12"
@@ -210,6 +210,7 @@ exclude = [
210210
]
211211

212212
[patch.crates-io]
213+
uhyve-interface = { git = "https://github.com/n0toose/uhyve", branch = "uhyve-if-v2_io-plus-rcx" }
213214
safe-mmio = { git = "https://github.com/hermit-os/safe-mmio", branch = "be" }
214215

215216
[profile.profiling]

src/fd/stdio.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ use core::task::Poll;
44

55
use async_trait::async_trait;
66
use embedded_io::{Read, ReadReady, Write};
7-
use uhyve_interface::parameters::WriteParams;
8-
use uhyve_interface::{GuestVirtAddr, Hypercall};
7+
use memory_addresses::VirtAddr;
8+
use uhyve_interface::GuestPhysAddr;
9+
use uhyve_interface::v2::Hypercall;
10+
use uhyve_interface::v2::parameters::WriteParams;
911

12+
use crate::arch::mm::paging;
1013
use crate::console::{CONSOLE, CONSOLE_WAKER};
1114
use crate::fd::{
1215
AccessPermission, FileAttr, ObjectInterface, PollEvent, STDERR_FILENO, STDOUT_FILENO,
@@ -161,12 +164,16 @@ impl ObjectInterface for UhyveStdout {
161164
async fn write(&self, buf: &[u8]) -> io::Result<usize> {
162165
let write_params = WriteParams {
163166
fd: STDOUT_FILENO,
164-
buf: GuestVirtAddr::from_ptr(buf.as_ptr()),
165-
len: buf.len(),
167+
buf: GuestPhysAddr::new(
168+
paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr()))
169+
.unwrap()
170+
.as_u64(),
171+
),
172+
len: buf.len().try_into().unwrap(),
166173
};
167174
uhyve_hypercall(Hypercall::FileWrite(&write_params));
168175

169-
Ok(write_params.len)
176+
Ok(write_params.len.try_into().unwrap())
170177
}
171178

172179
async fn isatty(&self) -> io::Result<bool> {
@@ -200,12 +207,16 @@ impl ObjectInterface for UhyveStderr {
200207
async fn write(&self, buf: &[u8]) -> io::Result<usize> {
201208
let write_params = WriteParams {
202209
fd: STDERR_FILENO,
203-
buf: GuestVirtAddr::from_ptr(buf.as_ptr()),
204-
len: buf.len(),
210+
buf: GuestPhysAddr::new(
211+
paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr()))
212+
.unwrap()
213+
.as_u64(),
214+
),
215+
len: buf.len().try_into().unwrap(),
205216
};
206217
uhyve_hypercall(Hypercall::FileWrite(&write_params));
207218

208-
Ok(write_params.len)
219+
Ok(write_params.len.try_into().unwrap())
209220
}
210221

211222
async fn isatty(&self) -> io::Result<bool> {

src/fs/uhyve.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ use async_lock::Mutex;
99
use async_trait::async_trait;
1010
use embedded_io::{ErrorType, Read, Write};
1111
use memory_addresses::VirtAddr;
12-
use uhyve_interface::parameters::{
12+
use uhyve_interface::GuestPhysAddr;
13+
use uhyve_interface::v2::Hypercall;
14+
use uhyve_interface::v2::parameters::{
1315
CloseParams, LseekParams, OpenParams, ReadParams, UnlinkParams, WriteParams,
1416
};
15-
use uhyve_interface::{GuestPhysAddr, GuestVirtAddr, Hypercall};
1617

1718
use crate::arch::mm::paging;
1819
use crate::env::fdt;
@@ -56,8 +57,12 @@ impl Read for UhyveFileHandleInner {
5657
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
5758
let mut read_params = ReadParams {
5859
fd: self.0,
59-
buf: GuestVirtAddr::from_ptr(buf.as_mut_ptr()),
60-
len: buf.len(),
60+
buf: GuestPhysAddr::new(
61+
paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_mut_ptr()))
62+
.unwrap()
63+
.as_u64(),
64+
),
65+
len: buf.len().try_into().unwrap(),
6166
ret: 0,
6267
};
6368
uhyve_hypercall(Hypercall::FileRead(&mut read_params));
@@ -74,12 +79,16 @@ impl Write for UhyveFileHandleInner {
7479
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
7580
let write_params = WriteParams {
7681
fd: self.0,
77-
buf: GuestVirtAddr::from_ptr(buf.as_ptr()),
78-
len: buf.len(),
82+
buf: GuestPhysAddr::new(
83+
paging::virtual_to_physical(VirtAddr::from_ptr(buf.as_ptr()))
84+
.unwrap()
85+
.as_u64(),
86+
),
87+
len: buf.len().try_into().unwrap(),
7988
};
8089
uhyve_hypercall(Hypercall::FileWrite(&write_params));
8190

82-
Ok(write_params.len)
91+
Ok(write_params.len.try_into().unwrap())
8392
}
8493

8594
fn flush(&mut self) -> Result<(), Self::Error> {

src/syscalls/interfaces/uhyve.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use core::ptr;
22

33
use memory_addresses::VirtAddr;
4-
use uhyve_interface::parameters::{ExitParams, SerialWriteBufferParams};
5-
use uhyve_interface::{Hypercall, HypercallAddress};
4+
use uhyve_interface::v2::parameters::SerialWriteBufferParams;
5+
use uhyve_interface::v2::{Hypercall, HypercallAddress};
66

77
use crate::arch;
88
use crate::arch::mm::paging::{self, virtual_to_physical};
99
use crate::syscalls::interfaces::SyscallInterface;
1010

11-
/// perform a SerialWriteBuffer hypercall with `buf` as payload.
11+
/// perform a SerialWriteBuffer hypercall with `buf` as payload
1212
#[inline]
1313
#[cfg_attr(target_arch = "riscv64", expect(dead_code))]
1414
pub(crate) fn serial_buf_hypercall(buf: &[u8]) {
@@ -31,9 +31,11 @@ fn data_addr<T>(data: &T) -> u64 {
3131
#[inline]
3232
fn hypercall_data(hypercall: &Hypercall<'_>) -> u64 {
3333
match hypercall {
34-
Hypercall::Cmdsize(data) => data_addr(*data),
35-
Hypercall::Cmdval(data) => data_addr(*data),
36-
Hypercall::Exit(data) => data_addr(*data),
34+
// As we are encoding an exit code (max 32 bits) into "an
35+
// address", and memory_addresses complains if an address
36+
// has any bits above the 48th one set to 1, we encode
37+
// potential negative numbers into a u32, then a u64.
38+
Hypercall::Exit(exit_code) => u64::from((*exit_code) as u32),
3739
Hypercall::FileClose(data) => data_addr(*data),
3840
Hypercall::FileLseek(data) => data_addr(*data),
3941
Hypercall::FileOpen(data) => data_addr(*data),
@@ -55,19 +57,18 @@ pub(crate) fn uhyve_hypercall(hypercall: Hypercall<'_>) {
5557

5658
#[cfg(target_arch = "x86_64")]
5759
unsafe {
58-
use x86_64::instructions::port::Port;
59-
60-
let data =
61-
u32::try_from(data).expect("Hypercall data must lie in the first 4GiB of memory");
62-
Port::new(ptr).write(data);
60+
use core::arch::asm;
61+
asm!(
62+
"out dx, eax", in("dx") ptr, in("eax") 0x1234u32, in("rcx") data, options(nomem, nostack, preserves_flags)
63+
);
6364
}
6465

6566
#[cfg(target_arch = "aarch64")]
6667
unsafe {
6768
use core::arch::asm;
6869
asm!(
6970
"str x8, [{ptr}]",
70-
ptr = in(reg) u64::from(ptr),
71+
ptr = in(reg) ptr,
7172
in("x8") data,
7273
options(nostack),
7374
);
@@ -81,8 +82,7 @@ pub struct Uhyve;
8182

8283
impl SyscallInterface for Uhyve {
8384
fn shutdown(&self, error_code: i32) -> ! {
84-
let sysexit = ExitParams { arg: error_code };
85-
uhyve_hypercall(Hypercall::Exit(&sysexit));
85+
uhyve_hypercall(Hypercall::Exit(error_code));
8686

8787
loop {
8888
arch::processor::halt();

0 commit comments

Comments
 (0)