mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-23 08:21:15 +00:00
vmm: igvm: Generate memory map for SEV-SNP guests
For SEV-SNP guests we need to provide the extended memory. It follows a very simple layout and very similar to other x86 guests. First segment: [HIGH_RAM_START - MEM_32BIT_RESERVED_START] PCI hole: [MEM_32BIT_RESERVED_START - RAM_64BIT_START] Second segment: [RAM_64BIT_START - RAM_END] Fixes #5993 Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
parent
91fe48d5f7
commit
9b151d06ca
@ -30,6 +30,11 @@ use std::mem::size_of;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
use crate::GuestMemoryMmap;
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
use igvm_defs::{MemoryMapEntryType, IGVM_VHS_MEMORY_MAP_ENTRY};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("command line is not a valid C string")]
|
#[error("command line is not a valid C string")]
|
||||||
@ -38,6 +43,8 @@ pub enum Error {
|
|||||||
Igvm(#[source] std::io::Error),
|
Igvm(#[source] std::io::Error),
|
||||||
#[error("invalid igvm file")]
|
#[error("invalid igvm file")]
|
||||||
InvalidIgvmFile(#[source] igvm_parser::Error),
|
InvalidIgvmFile(#[source] igvm_parser::Error),
|
||||||
|
#[error("invalid guest memory map")]
|
||||||
|
InvalidGuestMemmap(#[source] arch::Error),
|
||||||
#[error("loader error")]
|
#[error("loader error")]
|
||||||
Loader(#[source] crate::igvm::loader::Error),
|
Loader(#[source] crate::igvm::loader::Error),
|
||||||
#[error("parameter too large for parameter area")]
|
#[error("parameter too large for parameter area")]
|
||||||
@ -64,6 +71,41 @@ enum ParameterAreaState {
|
|||||||
Inserted,
|
Inserted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
fn igvm_memmap_from_ram_range(ram_range: (u64, u64)) -> IGVM_VHS_MEMORY_MAP_ENTRY {
|
||||||
|
assert!(ram_range.0 % HV_PAGE_SIZE == 0);
|
||||||
|
assert!((ram_range.1 - ram_range.0) % HV_PAGE_SIZE == 0);
|
||||||
|
|
||||||
|
IGVM_VHS_MEMORY_MAP_ENTRY {
|
||||||
|
starting_gpa_page_number: ram_range.0 / HV_PAGE_SIZE,
|
||||||
|
number_of_pages: (ram_range.1 - ram_range.0) / HV_PAGE_SIZE,
|
||||||
|
entry_type: MemoryMapEntryType::MEMORY,
|
||||||
|
flags: 0,
|
||||||
|
reserved: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
fn generate_memory_map(
|
||||||
|
guest_mem: &GuestMemoryMmap,
|
||||||
|
) -> Result<Vec<IGVM_VHS_MEMORY_MAP_ENTRY>, Error> {
|
||||||
|
let mut memory_map = Vec::new();
|
||||||
|
|
||||||
|
// Get usable physical memory ranges
|
||||||
|
let (first_ram_range, second_ram_range) =
|
||||||
|
arch::generate_ram_ranges(guest_mem).map_err(Error::InvalidGuestMemmap)?;
|
||||||
|
|
||||||
|
// Create the memory map entry for memory region before the gap
|
||||||
|
memory_map.push(igvm_memmap_from_ram_range(first_ram_range));
|
||||||
|
|
||||||
|
// Create the memory map entry for memory region after the gap if any
|
||||||
|
if let Some(second_ram_range) = second_ram_range {
|
||||||
|
memory_map.push(igvm_memmap_from_ram_range(second_ram_range));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(memory_map)
|
||||||
|
}
|
||||||
|
|
||||||
// Import a parameter to the given parameter area.
|
// Import a parameter to the given parameter area.
|
||||||
fn import_parameter(
|
fn import_parameter(
|
||||||
parameter_areas: &mut HashMap<u32, ParameterAreaState>,
|
parameter_areas: &mut HashMap<u32, ParameterAreaState>,
|
||||||
@ -245,6 +287,14 @@ pub fn load_igvm(
|
|||||||
todo!("unsupported IgvmPageDataType");
|
todo!("unsupported IgvmPageDataType");
|
||||||
}
|
}
|
||||||
IgvmDirectiveHeader::MemoryMap(_info) => {
|
IgvmDirectiveHeader::MemoryMap(_info) => {
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
{
|
||||||
|
let guest_mem = memory_manager.lock().unwrap().boot_guest_memory();
|
||||||
|
let memory_map = generate_memory_map(&guest_mem)?;
|
||||||
|
import_parameter(&mut parameter_areas, _info, memory_map.as_bytes())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sev_snp"))]
|
||||||
todo!("Not implemented");
|
todo!("Not implemented");
|
||||||
}
|
}
|
||||||
IgvmDirectiveHeader::CommandLine(info) => {
|
IgvmDirectiveHeader::CommandLine(info) => {
|
||||||
|
@ -998,8 +998,6 @@ impl Vm {
|
|||||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
cpu_manager: Arc<Mutex<cpu::CpuManager>>,
|
cpu_manager: Arc<Mutex<cpu::CpuManager>>,
|
||||||
) -> Result<EntryPoint> {
|
) -> Result<EntryPoint> {
|
||||||
//TODO: see issue https://github.com/cloud-hypervisor/cloud-hypervisor/issues/5993
|
|
||||||
|
|
||||||
let res = igvm_loader::load_igvm(&igvm, memory_manager, cpu_manager, "")
|
let res = igvm_loader::load_igvm(&igvm, memory_manager, cpu_manager, "")
|
||||||
.map_err(Error::IgvmLoad)?;
|
.map_err(Error::IgvmLoad)?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user