diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index c860458c4..9bba3c8aa 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -838,13 +838,14 @@ pub fn configure_system( _num_cpus: u8, rsdp_addr: Option, sgx_epc_region: Option, + serial_number: Option<&str>, ) -> super::Result<()> { // Write EBDA address to location where ACPICA expects to find it guest_mem .write_obj((layout::EBDA_START.0 >> 4) as u16, layout::EBDA_POINTER) .map_err(Error::EbdaSetup)?; - let size = smbios::setup_smbios(guest_mem).map_err(Error::SmbiosSetup)?; + let size = smbios::setup_smbios(guest_mem, serial_number).map_err(Error::SmbiosSetup)?; // Place the MP table after the SMIOS table aligned to 16 bytes let offset = GuestAddress(layout::SMBIOS_START).unchecked_add(size); @@ -1193,6 +1194,7 @@ mod tests { 1, Some(layout::RSDP_POINTER), None, + None, ); assert!(config_err.is_err()); @@ -1206,7 +1208,7 @@ mod tests { .collect(); let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); - configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap(); + configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap(); // Now assigning some memory that is equal to the start of the 32bit memory hole. let mem_size = 3328 << 20; @@ -1217,9 +1219,9 @@ mod tests { .map(|r| (r.0, r.1)) .collect(); let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); - configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap(); + configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap(); - configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap(); + configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap(); // Now assigning some memory that falls after the 32bit memory hole. let mem_size = 3330 << 20; @@ -1230,9 +1232,9 @@ mod tests { .map(|r| (r.0, r.1)) .collect(); let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); - configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap(); + configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap(); - configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None).unwrap(); + configure_system(&gm, GuestAddress(0), &None, no_vcpus, None, None, None).unwrap(); } #[test] diff --git a/arch/src/x86_64/smbios.rs b/arch/src/x86_64/smbios.rs index 2edc49481..d3e1b2e56 100644 --- a/arch/src/x86_64/smbios.rs +++ b/arch/src/x86_64/smbios.rs @@ -162,7 +162,7 @@ fn write_string( Ok(curptr) } -pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result { +pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Result { let physptr = GuestAddress(SMBIOS_START) .checked_add(mem::size_of::() as u64) .ok_or(Error::NotEnoughMemory)?; @@ -195,11 +195,15 @@ pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result { handle, manufacturer: 1, // First string written in this section product_name: 2, // Second string written in this section + serial_number: serial_number.map(|_| 3).unwrap_or_default(), // 3rd string ..Default::default() }; curptr = write_and_incr(mem, smbios_sysinfo, curptr)?; curptr = write_string(mem, "Cloud Hypervisor", curptr)?; curptr = write_string(mem, "cloud-hypervisor", curptr)?; + if let Some(serial_number) = serial_number { + curptr = write_string(mem, serial_number, curptr)?; + } curptr = write_and_incr(mem, 0u8, curptr)?; } @@ -263,7 +267,7 @@ mod tests { fn entrypoint_checksum() { let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(SMBIOS_START), 4096)]).unwrap(); - setup_smbios(&mem).unwrap(); + setup_smbios(&mem, None).unwrap(); let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap(); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index cf2a34a00..b7a21a4c6 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1115,6 +1115,14 @@ impl Vm { .as_ref() .cloned(); + let serial_number = self + .config + .lock() + .unwrap() + .platform + .as_ref() + .and_then(|p| p.serial_number.clone()); + arch::configure_system( &mem, arch::layout::CMDLINE_START, @@ -1122,6 +1130,7 @@ impl Vm { boot_vcpus, rsdp_addr, sgx_epc_region, + serial_number.as_deref(), ) .map_err(Error::ConfigureSystem)?; Ok(())