arch, vmm: Expose platform serial_number via SMBIOS

Fixes: #4002

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-04-21 12:25:17 +01:00 committed by Sebastien Boeuf
parent 203dfdc156
commit e972eb7c74
3 changed files with 23 additions and 8 deletions

View File

@ -838,13 +838,14 @@ pub fn configure_system(
_num_cpus: u8, _num_cpus: u8,
rsdp_addr: Option<GuestAddress>, rsdp_addr: Option<GuestAddress>,
sgx_epc_region: Option<SgxEpcRegion>, sgx_epc_region: Option<SgxEpcRegion>,
serial_number: Option<&str>,
) -> super::Result<()> { ) -> super::Result<()> {
// Write EBDA address to location where ACPICA expects to find it // Write EBDA address to location where ACPICA expects to find it
guest_mem guest_mem
.write_obj((layout::EBDA_START.0 >> 4) as u16, layout::EBDA_POINTER) .write_obj((layout::EBDA_START.0 >> 4) as u16, layout::EBDA_POINTER)
.map_err(Error::EbdaSetup)?; .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 // Place the MP table after the SMIOS table aligned to 16 bytes
let offset = GuestAddress(layout::SMBIOS_START).unchecked_add(size); let offset = GuestAddress(layout::SMBIOS_START).unchecked_add(size);
@ -1193,6 +1194,7 @@ mod tests {
1, 1,
Some(layout::RSDP_POINTER), Some(layout::RSDP_POINTER),
None, None,
None,
); );
assert!(config_err.is_err()); assert!(config_err.is_err());
@ -1206,7 +1208,7 @@ mod tests {
.collect(); .collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); 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. // Now assigning some memory that is equal to the start of the 32bit memory hole.
let mem_size = 3328 << 20; let mem_size = 3328 << 20;
@ -1217,9 +1219,9 @@ mod tests {
.map(|r| (r.0, r.1)) .map(|r| (r.0, r.1))
.collect(); .collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); 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. // Now assigning some memory that falls after the 32bit memory hole.
let mem_size = 3330 << 20; let mem_size = 3330 << 20;
@ -1230,9 +1232,9 @@ mod tests {
.map(|r| (r.0, r.1)) .map(|r| (r.0, r.1))
.collect(); .collect();
let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); 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] #[test]

View File

@ -162,7 +162,7 @@ fn write_string(
Ok(curptr) Ok(curptr)
} }
pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<u64> { pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Result<u64> {
let physptr = GuestAddress(SMBIOS_START) let physptr = GuestAddress(SMBIOS_START)
.checked_add(mem::size_of::<Smbios30Entrypoint>() as u64) .checked_add(mem::size_of::<Smbios30Entrypoint>() as u64)
.ok_or(Error::NotEnoughMemory)?; .ok_or(Error::NotEnoughMemory)?;
@ -195,11 +195,15 @@ pub fn setup_smbios(mem: &GuestMemoryMmap) -> Result<u64> {
handle, handle,
manufacturer: 1, // First string written in this section manufacturer: 1, // First string written in this section
product_name: 2, // Second 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() ..Default::default()
}; };
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?; curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
curptr = write_string(mem, "Cloud Hypervisor", curptr)?; curptr = write_string(mem, "Cloud Hypervisor", 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)?; curptr = write_and_incr(mem, 0u8, curptr)?;
} }
@ -263,7 +267,7 @@ mod tests {
fn entrypoint_checksum() { fn entrypoint_checksum() {
let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(SMBIOS_START), 4096)]).unwrap(); 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(); let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();

View File

@ -1115,6 +1115,14 @@ impl Vm {
.as_ref() .as_ref()
.cloned(); .cloned();
let serial_number = self
.config
.lock()
.unwrap()
.platform
.as_ref()
.and_then(|p| p.serial_number.clone());
arch::configure_system( arch::configure_system(
&mem, &mem,
arch::layout::CMDLINE_START, arch::layout::CMDLINE_START,
@ -1122,6 +1130,7 @@ impl Vm {
boot_vcpus, boot_vcpus,
rsdp_addr, rsdp_addr,
sgx_epc_region, sgx_epc_region,
serial_number.as_deref(),
) )
.map_err(Error::ConfigureSystem)?; .map_err(Error::ConfigureSystem)?;
Ok(()) Ok(())