hypervisor: Add API to complete isolated import

This is the function that needs to be called by the VMM
to inform the MSHV that isolation is complete and inform
PSP about this completion.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2023-10-13 12:58:56 -07:00 committed by Bo Chen
parent dc3903012d
commit 5bd113e625
5 changed files with 168 additions and 2 deletions

75
Cargo.lock generated
View File

@ -300,6 +300,17 @@ dependencies = [
"serde",
]
[[package]]
name = "bitfield-struct"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac32db62a43cf33353ce30b4a208b08193ea2086a1c6c004acb0073c706a29d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.31",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -478,6 +489,15 @@ dependencies = [
"rustc_version",
]
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "crc64"
version = "1.0.0"
@ -938,6 +958,8 @@ dependencies = [
"byteorder",
"env_logger",
"iced-x86",
"igvm",
"igvm_defs",
"kvm-bindings",
"kvm-ioctls",
"libc",
@ -967,6 +989,33 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "igvm"
version = "0.1.0"
source = "git+https://github.com/microsoft/igvm?branch=main#c1b0201d8286cb23b9f30cb16ba435484666cfa3"
dependencies = [
"bitfield-struct",
"crc32fast",
"hex",
"igvm_defs",
"open-enum",
"range_map_vec",
"thiserror",
"tracing",
"zerocopy",
]
[[package]]
name = "igvm_defs"
version = "0.1.0"
source = "git+https://github.com/microsoft/igvm?branch=main#c1b0201d8286cb23b9f30cb16ba435484666cfa3"
dependencies = [
"bitfield-struct",
"open-enum",
"static_assertions",
"zerocopy",
]
[[package]]
name = "indexmap"
version = "1.9.3"
@ -1294,6 +1343,26 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "open-enum"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9807f1199cf84ec7cc801a79e5ee9aa5178e4762c6b9c7066c30b3cabdcd911e"
dependencies = [
"open-enum-derive",
]
[[package]]
name = "open-enum-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "894ae443e59fecf7173ab3b963473f44193fa71b3c8953c61a5bd5f30880bb88"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "openssl-src"
version = "300.1.5+3.1.3"
@ -1641,6 +1710,12 @@ dependencies = [
"getrandom",
]
[[package]]
name = "range_map_vec"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8edc89eaa583cf6bc4c6ef16a219f0a60d342ca3bf0eae793560038ac8af1795"
[[package]]
name = "rate_limiter"
version = "0.1.0"

View File

@ -8,13 +8,14 @@ license = "Apache-2.0 OR BSD-3-Clause"
[features]
kvm = ["kvm-ioctls", "kvm-bindings", "vfio-ioctls/kvm"]
mshv = ["mshv-ioctls", "mshv-bindings", "vfio-ioctls/mshv", "iced-x86"]
sev_snp = []
sev_snp = ["igvm_parser", "igvm_defs"]
tdx = []
[dependencies]
anyhow = "1.0.75"
byteorder = "1.4.3"
thiserror = "1.0.40"
igvm_defs = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm_defs", optional = true }
igvm_parser = { git = "https://github.com/microsoft/igvm", branch = "main" , package = "igvm", optional = true }
libc = "0.2.147"
log = "0.4.17"
kvm-ioctls = { version = "0.13.0", optional = true }
@ -26,6 +27,7 @@ serde_with = { version = "3.0.0", default-features = false, features = ["macros"
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio", branch = "main", default-features = false }
vm-memory = { version = "0.12.2", features = ["backend-mmap", "backend-atomic"] }
vmm-sys-util = { version = "0.11.0", features = ["with-serde"] }
thiserror = "1.0.40"
[target.'cfg(target_arch = "x86_64")'.dependencies.iced-x86]
optional = true

View File

@ -20,13 +20,21 @@ use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use vfio_ioctls::VfioDeviceFd;
use vm::DataMatch;
#[cfg(feature = "sev_snp")]
mod snp_constants;
// x86_64 dependencies
#[cfg(target_arch = "x86_64")]
pub mod x86_64;
#[cfg(feature = "sev_snp")]
use snp_constants::*;
use crate::{
ClockData, CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
};
#[cfg(feature = "sev_snp")]
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
use vmm_sys_util::eventfd::EventFd;
#[cfg(target_arch = "x86_64")]
pub use x86_64::VcpuMshvState;
@ -1314,4 +1322,51 @@ impl vm::Vm for MshvVm {
.import_isolated_pages(&isolated_pages[0])
.map_err(|e| vm::HypervisorVmError::ImportIsolatedPages(e.into()))
}
#[cfg(feature = "sev_snp")]
fn complete_isolated_import(
&self,
snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
host_data: &[u8],
id_block_enabled: u8,
) -> vm::Result<()> {
let mut auth_info = hv_snp_id_auth_info {
id_key_algorithm: snp_id_block.id_key_algorithm,
auth_key_algorithm: snp_id_block.author_key_algorithm,
..Default::default()
};
// Each of r/s component is 576 bits long
auth_info.id_block_signature[..SIG_R_COMPONENT_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_key_signature.r_comp.as_ref());
auth_info.id_block_signature
[SIG_R_COMPONENT_SIZE_IN_BYTES..SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_key_signature.s_comp.as_ref());
auth_info.id_key[..ECDSA_CURVE_ID_SIZE_IN_BYTES]
.copy_from_slice(snp_id_block.id_public_key.curve.to_le_bytes().as_ref());
auth_info.id_key[ECDSA_SIG_X_COMPONENT_START..ECDSA_SIG_X_COMPONENT_END]
.copy_from_slice(snp_id_block.id_public_key.qx.as_ref());
auth_info.id_key[ECDSA_SIG_Y_COMPONENT_START..ECDSA_SIG_Y_COMPONENT_END]
.copy_from_slice(snp_id_block.id_public_key.qy.as_ref());
let data = mshv_complete_isolated_import {
import_data: hv_partition_complete_isolated_import_data {
psp_parameters: hv_psp_launch_finish_data {
id_block: hv_snp_id_block {
launch_digest: snp_id_block.ld,
family_id: snp_id_block.family_id,
image_id: snp_id_block.image_id,
version: snp_id_block.version,
guest_svn: snp_id_block.guest_svn,
policy: get_default_snp_guest_policy(),
},
id_auth_info: auth_info,
host_data: host_data[0..32].try_into().unwrap(),
id_block_enabled,
author_key_enabled: 0,
},
},
};
self.fd
.complete_isolated_import(&data)
.map_err(|e| vm::HypervisorVmError::CompleteIsolatedImport(e.into()))
}
}

View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Reference: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56860.pdf
// Chapter 10
pub const SIG_R_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const SIG_R_AND_S_COMPONENT_SIZE_IN_BYTES: usize = 144;
pub const ECDSA_CURVE_ID_SIZE_IN_BYTES: usize = 4;
pub const ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES: usize = 72;
pub const ECDSA_SIG_X_COMPONENT_START: usize = ECDSA_CURVE_ID_SIZE_IN_BYTES;
pub const ECDSA_SIG_X_COMPONENT_END: usize =
ECDSA_SIG_X_COMPONENT_START + ECDSA_SIG_X_COMPONENT_SIZE_IN_BYTES;
pub const ECDSA_SIG_Y_COMPONENT_START: usize = ECDSA_SIG_X_COMPONENT_END;
pub const ECDSA_SIG_Y_COMPONENT_END: usize =
ECDSA_SIG_X_COMPONENT_END + ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES;

View File

@ -19,6 +19,8 @@ use crate::cpu::Vcpu;
use crate::ClockData;
use crate::UserMemoryRegion;
use crate::{IoEventAddress, IrqRoutingEntry};
#[cfg(feature = "sev_snp")]
use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
use std::any::Any;
#[cfg(target_arch = "x86_64")]
use std::fs::File;
@ -225,6 +227,10 @@ pub enum HypervisorVmError {
///
#[error("Failed to import isolated pages: {0}")]
ImportIsolatedPages(#[source] anyhow::Error),
/// Failed to complete isolated import
///
#[error("Failed to complete isolated import: {0}")]
CompleteIsolatedImport(#[source] anyhow::Error),
}
///
/// Result type for returning from a function
@ -374,6 +380,16 @@ pub trait Vm: Send + Sync + Any {
) -> Result<()> {
unimplemented!()
}
/// Complete the isolated import
#[cfg(feature = "sev_snp")]
fn complete_isolated_import(
&self,
_snp_id_block: IGVM_VHS_SNP_ID_BLOCK,
_host_data: &[u8],
_id_block_enabled: u8,
) -> Result<()> {
unimplemented!()
}
}
pub trait VmOps: Send + Sync {