vmm: Add IGVM to the config/commandline

This patch adds igvm to the Vm config and params as well as
the command line argument to pass igvm file to load into
guest memory. The file must maintain the IGVM format.
The CLI option is featured guarded by igvm feature gate.

The IGVM(Independent Guest Virtual Machine) file format
is designed to encapsulate all information required to
launch a virtual machine on any given virtualization stack,
with support for different isolation technologies such as
AMD SEV-SNP and Intel TDX.

At a conceptual level, this file format is a set of commands created
by the tool that generated the file, used by the loader to construct
the initial guest state. The file format also contains measurement
information that the underlying platform will use to confirm that
the file was loaded correctly and signed by the appropriate authorities.

The IGVM file is generated by the tool:
https://github.com/microsoft/igvm-tooling

The IGVM file is parsed by the following crates:
https://github.com/microsoft/igvm

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2023-10-04 18:07:45 -07:00 committed by Bo Chen
parent c0faa75922
commit 13ef424bf1
8 changed files with 37 additions and 3 deletions

View File

@ -71,10 +71,11 @@ default = ["kvm", "io_uring"]
dbus_api = ["zbus", "vmm/dbus_api"]
dhat-heap = ["dhat"] # For heap profiling
guest_debug = ["vmm/guest_debug"]
igvm = ["vmm/igvm", "mshv"]
io_uring = ["vmm/io_uring"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
sev_snp = ["vmm/sev_snp", "mshv"]
sev_snp = ["igvm", "vmm/sev_snp", "mshv"]
tdx = ["vmm/tdx"]
tracing = ["vmm/tracing", "tracer/tracing"]

View File

@ -8,6 +8,9 @@ edition = "2021"
[package.metadata]
cargo-fuzz = true
[features]
igvm = []
[dependencies]
block = { path = "../block" }
devices = { path = "../devices" }

View File

@ -23,6 +23,8 @@ fuzz_target!(|bytes| {
kernel: None,
cmdline: Some(String::from_utf8_lossy(&bytes).to_string()),
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
};
let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) {
Ok(cmdline) => cmdline,

View File

@ -443,7 +443,14 @@ fn create_app(default_vcpus: String, default_memory: String, default_rng: String
.num_args(0)
.group("vmm-config"),
);
#[cfg(feature = "igvm")]
let app = app.arg(
Arg::new("igvm")
.long("igvm")
.help("Path to IGVM file to load.")
.num_args(1)
.group("vm-config"),
);
app.arg(
Arg::new("version")
.short('V')

View File

@ -8,6 +8,7 @@ edition = "2021"
default = []
dbus_api = ["blocking", "futures", "zbus"]
guest_debug = ["kvm", "gdbstub", "gdbstub_arch"]
igvm = []
io_uring = ["block/io_uring"]
kvm = ["hypervisor/kvm", "vfio-ioctls/kvm", "vm-device/kvm", "pci/kvm"]
mshv = ["hypervisor/mshv", "vfio-ioctls/mshv", "vm-device/mshv", "pci/mshv"]

View File

@ -398,6 +398,8 @@ pub struct VmParams<'a> {
pub gdb: bool,
pub platform: Option<&'a str>,
pub tpm: Option<&'a str>,
#[cfg(feature = "igvm")]
pub igvm: Option<&'a str>,
}
impl<'a> VmParams<'a> {
@ -451,6 +453,8 @@ impl<'a> VmParams<'a> {
#[cfg(feature = "guest_debug")]
let gdb = args.contains_id("gdb");
let tpm: Option<&str> = args.get_one::<String>("tpm").map(|x| x as &str);
#[cfg(feature = "igvm")]
let igvm = args.get_one::<String>("igvm").map(|x| x as &str);
VmParams {
cpus,
memory,
@ -480,6 +484,8 @@ impl<'a> VmParams<'a> {
gdb,
platform,
tpm,
#[cfg(feature = "igvm")]
igvm,
}
}
}
@ -2283,12 +2289,21 @@ impl VmConfig {
numa = Some(numa_config_list);
}
let payload = if vm_params.kernel.is_some() || vm_params.firmware.is_some() {
#[cfg(not(feature = "igvm"))]
let payload_present = vm_params.kernel.is_some() || vm_params.firmware.is_some();
#[cfg(feature = "igvm")]
let payload_present =
vm_params.kernel.is_some() || vm_params.firmware.is_some() || vm_params.igvm.is_some();
let payload = if payload_present {
Some(PayloadConfig {
kernel: vm_params.kernel.map(PathBuf::from),
initramfs: vm_params.initramfs.map(PathBuf::from),
cmdline: vm_params.cmdline.map(|s| s.to_string()),
firmware: vm_params.firmware.map(PathBuf::from),
#[cfg(feature = "igvm")]
igvm: vm_params.igvm.map(PathBuf::from),
})
} else {
None

View File

@ -302,6 +302,8 @@ pub fn feature_list() -> Vec<String> {
"dhat-heap".to_string(),
#[cfg(feature = "guest_debug")]
"guest_debug".to_string(),
#[cfg(feature = "igvm")]
"igvm".to_string(),
#[cfg(feature = "io_uring")]
"io_uring".to_string(),
#[cfg(feature = "kvm")]

View File

@ -556,6 +556,9 @@ pub struct PayloadConfig {
pub cmdline: Option<String>,
#[serde(default)]
pub initramfs: Option<PathBuf>,
#[cfg(feature = "igvm")]
#[serde(default)]
pub igvm: Option<PathBuf>,
}
pub fn default_serial() -> ConsoleConfig {