diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index b61e9277e..55839a8ad 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -20,6 +20,7 @@ use linux_loader::loader::bootparam::boot_params; use linux_loader::loader::elf::start_info::{ hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info, }; +use std::collections::BTreeMap; use std::mem; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, @@ -64,7 +65,7 @@ impl SgxEpcSection { pub struct SgxEpcRegion { start: GuestAddress, size: GuestUsize, - epc_sections: Vec, + epc_sections: BTreeMap, } impl SgxEpcRegion { @@ -72,7 +73,7 @@ impl SgxEpcRegion { SgxEpcRegion { start, size, - epc_sections: Vec::new(), + epc_sections: BTreeMap::new(), } } pub fn start(&self) -> GuestAddress { @@ -81,11 +82,11 @@ impl SgxEpcRegion { pub fn size(&self) -> GuestUsize { self.size } - pub fn epc_sections(&self) -> &Vec { + pub fn epc_sections(&self) -> &BTreeMap { &self.epc_sections } - pub fn push(&mut self, epc_section: SgxEpcSection) { - self.epc_sections.push(epc_section); + pub fn insert(&mut self, id: String, epc_section: SgxEpcSection) { + self.epc_sections.insert(id, epc_section); } } diff --git a/docs/intel_sgx.md b/docs/intel_sgx.md index 023168b9a..58be64801 100644 --- a/docs/intel_sgx.md +++ b/docs/intel_sgx.md @@ -34,7 +34,7 @@ memory, the second one being 32MiB with no pre-allocated memory. --disk path=focal-server-cloudimg-amd64.raw \ --kernel vmlinux \ --cmdline "console=ttyS0 console=hvc0 root=/dev/vda1 rw" \ - --sgx-epc size=64M,prefault=on size=32M,prefault=off + --sgx-epc id=epc0,size=64M,prefault=on id=epc1,size=32M,prefault=off ``` Once booted, and assuming your guest kernel contains the patches from the diff --git a/tests/integration.rs b/tests/integration.rs index 08c393f62..eee2134cf 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -6358,7 +6358,7 @@ mod tests { .args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE]) .default_disks() .default_net() - .args(&["--sgx-epc", "size=64M"]) + .args(&["--sgx-epc", "id=epc0,size=64M"]) .capture_output() .spawn() .unwrap(); diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index cf43d3713..7349a3292 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -851,9 +851,12 @@ components: SgxEpcConfig: required: + - id - size type: object properties: + id: + type: string size: type: integer format: int64 diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 2c712f4c3..d5a76df34 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -77,6 +77,9 @@ pub enum Error { /// Failed to parse SGX EPC parameters #[cfg(target_arch = "x86_64")] ParseSgxEpc(OptionParserError), + /// Missing 'id' from SGX EPC section + #[cfg(target_arch = "x86_64")] + ParseSgxEpcIdMissing, /// Failed to parse NUMA parameters ParseNuma(OptionParserError), /// Failed to validate configuration @@ -215,6 +218,7 @@ impl fmt::Display for Error { ParseRestore(o) => write!(f, "Error parsing --restore: {}", o), #[cfg(target_arch = "x86_64")] ParseSgxEpc(o) => write!(f, "Error parsing --sgx-epc: {}", o), + ParseSgxEpcIdMissing => write!(f, "Error parsing --sgx-epc: id missing"), ParseNuma(o) => write!(f, "Error parsing --numa: {}", o), ParseRestoreSourceUrlMissing => { write!(f, "Error parsing --restore: source_url missing") @@ -1593,6 +1597,7 @@ impl TdxConfig { #[cfg(target_arch = "x86_64")] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)] pub struct SgxEpcConfig { + pub id: String, #[serde(default)] pub size: u64, #[serde(default)] @@ -1602,12 +1607,13 @@ pub struct SgxEpcConfig { #[cfg(target_arch = "x86_64")] impl SgxEpcConfig { pub const SYNTAX: &'static str = "SGX EPC parameters \ - \"size=,prefault=on|off\""; + \"id=,size=,prefault=on|off\""; pub fn parse(sgx_epc: &str) -> Result { let mut parser = OptionParser::new(); - parser.add("size").add("prefault"); + parser.add("id").add("size").add("prefault"); parser.parse(sgx_epc).map_err(Error::ParseSgxEpc)?; + let id = parser.get("id").ok_or(Error::ParseSgxEpcIdMissing)?; let size = parser .convert::("size") .map_err(Error::ParseSgxEpc)? @@ -1619,7 +1625,7 @@ impl SgxEpcConfig { .unwrap_or(Toggle(false)) .0; - Ok(SgxEpcConfig { size, prefault }) + Ok(SgxEpcConfig { id, size, prefault }) } } diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 9e9ab3ecb..d0ebda3dd 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -572,7 +572,7 @@ impl CpuManager { .unwrap() .sgx_epc_region() .as_ref() - .map(|sgx_epc_region| sgx_epc_region.epc_sections().clone()); + .map(|sgx_epc_region| sgx_epc_region.epc_sections().values().cloned().collect()); #[cfg(target_arch = "x86_64")] let cpuid = { let phys_bits = physical_bits(config.max_phys_bits); diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 00a342567..85215cc2c 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -1458,10 +1458,13 @@ impl MemoryManager { false, )?; - sgx_epc_region.push(SgxEpcSection::new( - GuestAddress(epc_section_start), - epc_section.size as GuestUsize, - )); + sgx_epc_region.insert( + epc_section.id.clone(), + SgxEpcSection::new( + GuestAddress(epc_section_start), + epc_section.size as GuestUsize, + ), + ); epc_section_start += epc_section.size; }