diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 8ccfaf75d..da30cdc73 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -826,7 +826,8 @@ pub fn configure_system( .write_obj((layout::EBDA_START.0 >> 4) as u16, layout::EBDA_POINTER) .map_err(Error::EbdaSetup)?; - let size = smbios::setup_smbios(guest_mem, serial_number, uuid).map_err(Error::SmbiosSetup)?; + let size = + smbios::setup_smbios(guest_mem, serial_number, uuid, None).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); diff --git a/arch/src/x86_64/smbios.rs b/arch/src/x86_64/smbios.rs index 790036af2..d670cf7e5 100644 --- a/arch/src/x86_64/smbios.rs +++ b/arch/src/x86_64/smbios.rs @@ -61,6 +61,7 @@ pub type Result = result::Result; const SM3_MAGIC_IDENT: &[u8; 5usize] = b"_SM3_"; const BIOS_INFORMATION: u8 = 0; const SYSTEM_INFORMATION: u8 = 1; +const OEM_STRINGS: u8 = 11; const END_OF_TABLE: u8 = 127; const PCI_SUPPORTED: u64 = 1 << 7; const IS_VIRTUAL_MACHINE: u8 = 1 << 4; @@ -125,6 +126,16 @@ pub struct SmbiosSysInfo { pub family: u8, } +#[repr(C)] +#[repr(packed)] +#[derive(Default, Copy, Clone)] +struct SmbiosOemStrings { + r#type: u8, + length: u8, + handle: u16, + count: u8, +} + #[repr(C)] #[repr(packed)] #[derive(Default, Copy, Clone)] @@ -138,6 +149,7 @@ pub struct SmbiosEndOfTable { unsafe impl ByteValued for Smbios30Entrypoint {} unsafe impl ByteValued for SmbiosBiosInfo {} unsafe impl ByteValued for SmbiosSysInfo {} +unsafe impl ByteValued for SmbiosOemStrings {} unsafe impl ByteValued for SmbiosEndOfTable {} fn write_and_incr( @@ -168,6 +180,7 @@ pub fn setup_smbios( mem: &GuestMemoryMmap, serial_number: Option<&str>, uuid: Option<&str>, + oem_strings: Option<&[&str]>, ) -> Result { let physptr = GuestAddress(SMBIOS_START) .checked_add(mem::size_of::() as u64) @@ -220,6 +233,25 @@ pub fn setup_smbios( curptr = write_and_incr(mem, 0u8, curptr)?; } + if let Some(oem_strings) = oem_strings { + handle += 1; + + let smbios_oemstrings = SmbiosOemStrings { + r#type: OEM_STRINGS, + length: mem::size_of::() as u8, + handle, + count: oem_strings.len() as u8, + }; + + curptr = write_and_incr(mem, smbios_oemstrings, curptr)?; + + for s in oem_strings { + curptr = write_string(mem, s, curptr)?; + } + + curptr = write_and_incr(mem, 0u8, curptr)?; + } + { handle += 1; let smbios_end = SmbiosEndOfTable { @@ -280,7 +312,7 @@ mod tests { fn entrypoint_checksum() { let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(SMBIOS_START), 4096)]).unwrap(); - setup_smbios(&mem, None, None).unwrap(); + setup_smbios(&mem, None, None, None).unwrap(); let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();