uhyve_interface/v1/mod.rs
1//! # Uhyve Hypervisor Interface V1
2//!
3//! The Uhyve hypercall interface works as follows:
4//!
5//! - On `x86_64` you use an out port instruction. The address of the `out`-port corresponds to the
6//! hypercall you want to use. You can obtain it from the [`HypercallAddress`](v1::HypercallAddress) enum. The data send to
7//! that port is the physical memory address (of the VM) of the parameters of that hypercall.
8//! - On `aarch64` you write to the respective [`HypercallAddress`](v1::HypercallAddress). The 64-bit value written to that location is the guest's physical memory address of the hypercall's parameter.
9
10// TODO: Throw this out, once https://github.com/rust-lang/rfcs/issues/2783 or https://github.com/rust-lang/rust/issues/86772 is resolved
11
12pub mod parameters;
13use parameters::*;
14
15/// Enum containing all valid port mappings for hypercalls.
16///
17/// The discriminants of this enum are the respective ports, so one can get the code by calling
18/// e.g., `HypercallPorts::FileWrite as u16`.
19#[repr(u16)]
20#[non_exhaustive]
21#[derive(Clone, Copy, Debug, Eq, PartialEq, num_enum::TryFromPrimitive, Hash)]
22pub enum HypercallAddress {
23 /// Port address = `0x400`
24 FileWrite = 0x400,
25 /// Port address = `0x440`
26 FileOpen = 0x440,
27 /// Port address = `0x480`
28 FileClose = 0x480,
29 /// Port address = `0x500`
30 FileRead = 0x500,
31 /// Port address = `0x540`
32 Exit = 0x540,
33 /// Port address = `0x580`
34 FileLseek = 0x580,
35 #[deprecated = "was never really in use"]
36 /// Port address = `0x640`
37 Netwrite = 0x640,
38 #[deprecated = "was never really in use"]
39 /// Port address = `0x680`
40 Netread = 0x680,
41 #[deprecated = "was never really in use"]
42 /// Port address = `0x700`
43 Netstat = 0x700,
44 /// Port address = `0x740`
45 Cmdsize = 0x740,
46 /// Port address = `0x780`
47 Cmdval = 0x780,
48 /// Port address = `0x800`
49 Uart = 0x800,
50 /// Port address = `0x840`
51 FileUnlink = 0x840,
52 /// Port address = `0x880`
53 SerialBufferWrite = 0x880,
54}
55
56into_hypercall_addresses! {
57 impl From<Hypercall> for HypercallAddress {
58 match {
59 Cmdsize,
60 Cmdval,
61 Exit,
62 FileClose,
63 FileLseek,
64 FileOpen,
65 FileRead,
66 FileWrite,
67 FileUnlink,
68 SerialWriteByte => Uart,
69 SerialWriteBuffer => SerialBufferWrite,
70 }
71 }
72}
73
74/// Hypervisor calls available in Uhyve with their respective parameters. See the [module level documentation](crate) on how to invoke them.
75#[non_exhaustive]
76#[derive(Debug)]
77pub enum Hypercall<'a> {
78 /// Get the size of the argument and environment strings. Used to allocate memory for
79 /// [`Hypercall::Cmdval`].
80 Cmdsize(&'a mut CmdsizeParams),
81 /// Copy the argument and environment strings into the VM. Usually preceeeded by
82 /// [`Hypercall::Cmdsize`] so that the guest can allocate the memory for this call.
83 Cmdval(&'a CmdvalParams),
84 /// Exit the VM and return a status.
85 Exit(&'a ExitParams),
86 FileClose(&'a mut CloseParams),
87 FileLseek(&'a mut LseekParams),
88 FileOpen(&'a mut OpenParams),
89 FileRead(&'a mut ReadParams),
90 FileWrite(&'a mut WriteParams),
91 FileUnlink(&'a mut UnlinkParams),
92 /// Write a char to the terminal.
93 SerialWriteByte(u8),
94 /// Write a buffer to the terminal.
95 SerialWriteBuffer(&'a SerialWriteBufferParams),
96}
97impl<'a> Hypercall<'a> {
98 /// Get a hypercall's port address.
99 pub fn port(self) -> u16 {
100 HypercallAddress::from(self) as u16
101 }
102}
103
104// Networkports (not used at the moment)
105// TODO: Remove this
106pub const UHYVE_PORT_NETWRITE: u16 = 0x640;
107
108// FIXME: Do not use a fix number of arguments
109/// The maximum number of items in an argument of environment vector.
110pub const MAX_ARGC_ENVC: usize = 128;