Skip to main content

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;