mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: plumb legacy SMBIOS config
Add a small SMBIOS config that carries serial_number, uuid, and OEM strings, and pass it from platform config into x86_64 setup. On-behalf-of: SAP leander.kohler@sap.com Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
0141635a5c
commit
e097d7d495
+3
-18
@@ -31,6 +31,7 @@ use linux_loader::loader::elf::start_info::{
|
|||||||
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
|
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
|
||||||
};
|
};
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
|
pub use smbios::SmbiosConfig;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use vm_memory::{
|
use vm_memory::{
|
||||||
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
|
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
|
||||||
@@ -1059,9 +1060,7 @@ pub fn configure_system(
|
|||||||
_num_cpus: u32,
|
_num_cpus: u32,
|
||||||
setup_header: Option<setup_header>,
|
setup_header: Option<setup_header>,
|
||||||
rsdp_addr: Option<GuestAddress>,
|
rsdp_addr: Option<GuestAddress>,
|
||||||
serial_number: Option<&str>,
|
smbios: Option<&SmbiosConfig>,
|
||||||
uuid: Option<&str>,
|
|
||||||
oem_strings: Option<&[String]>,
|
|
||||||
topology: Option<(u16, u16, u16, u16)>,
|
topology: Option<(u16, u16, u16, u16)>,
|
||||||
) -> 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
|
||||||
@@ -1069,13 +1068,7 @@ pub fn configure_system(
|
|||||||
.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(
|
let size = smbios::setup_smbios(guest_mem, smbios).map_err(Error::SmbiosSetup)?;
|
||||||
guest_mem,
|
|
||||||
serial_number,
|
|
||||||
uuid,
|
|
||||||
oem_strings.unwrap_or_default(),
|
|
||||||
)
|
|
||||||
.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);
|
||||||
@@ -1620,8 +1613,6 @@ mod unit_tests {
|
|||||||
Some(layout::RSDP_POINTER),
|
Some(layout::RSDP_POINTER),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
config_err.unwrap_err();
|
config_err.unwrap_err();
|
||||||
|
|
||||||
@@ -1644,8 +1635,6 @@ mod unit_tests {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1673,8 +1662,6 @@ mod unit_tests {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1688,8 +1675,6 @@ mod unit_tests {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,19 @@ const IS_VIRTUAL_MACHINE: u8 = 1 << 4;
|
|||||||
pub const DEFAULT_SYSTEM_MANUFACTURER: &str = "Cloud Hypervisor";
|
pub const DEFAULT_SYSTEM_MANUFACTURER: &str = "Cloud Hypervisor";
|
||||||
pub const DEFAULT_SYSTEM_PRODUCT_NAME: &str = "cloud-hypervisor";
|
pub const DEFAULT_SYSTEM_PRODUCT_NAME: &str = "cloud-hypervisor";
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
pub struct SmbiosConfig {
|
||||||
|
pub serial_number: Option<String>,
|
||||||
|
pub uuid: Option<String>,
|
||||||
|
pub oem_strings: Box<[String]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SmbiosConfig {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
*self == Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn compute_checksum<T: Copy>(v: &T) -> u8 {
|
fn compute_checksum<T: Copy>(v: &T) -> u8 {
|
||||||
let v: *const T = v;
|
let v: *const T = v;
|
||||||
// SAFETY: we are only reading the bytes within the size of the `T` reference `v`.
|
// SAFETY: we are only reading the bytes within the size of the `T` reference `v`.
|
||||||
@@ -222,12 +235,10 @@ fn write_type1_system(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_smbios(
|
pub fn setup_smbios(mem: &GuestMemoryMmap, smbios: Option<&SmbiosConfig>) -> Result<u64> {
|
||||||
mem: &GuestMemoryMmap,
|
let serial_number = smbios.and_then(|cfg| cfg.serial_number.as_deref());
|
||||||
serial_number: Option<&str>,
|
let uuid = smbios.and_then(|cfg| cfg.uuid.as_deref());
|
||||||
uuid: Option<&str>,
|
let oem_strings: &[String] = smbios.map_or(&[], |cfg| &cfg.oem_strings);
|
||||||
oem_strings: &[String],
|
|
||||||
) -> 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)?;
|
||||||
@@ -333,7 +344,7 @@ mod unit_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, None, None, &[]).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();
|
||||||
|
|
||||||
|
|||||||
+3
-21
@@ -1855,29 +1855,13 @@ impl Vm {
|
|||||||
|
|
||||||
let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus();
|
let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus();
|
||||||
|
|
||||||
let serial_number = self
|
let smbios = self
|
||||||
.config
|
.config
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.platform
|
.platform
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|p| p.serial_number.clone());
|
.and_then(|p| p.smbios_config());
|
||||||
|
|
||||||
let uuid = self
|
|
||||||
.config
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.platform
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|p| p.uuid.clone());
|
|
||||||
|
|
||||||
let oem_strings = self
|
|
||||||
.config
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.platform
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|p| p.oem_strings.clone());
|
|
||||||
|
|
||||||
let topology = self.cpu_manager.lock().unwrap().get_vcpu_topology();
|
let topology = self.cpu_manager.lock().unwrap().get_vcpu_topology();
|
||||||
|
|
||||||
@@ -1889,9 +1873,7 @@ impl Vm {
|
|||||||
boot_vcpus,
|
boot_vcpus,
|
||||||
entry_addr.setup_header,
|
entry_addr.setup_header,
|
||||||
rsdp_addr,
|
rsdp_addr,
|
||||||
serial_number.as_deref(),
|
smbios.as_ref(),
|
||||||
uuid.as_deref(),
|
|
||||||
oem_strings.as_deref(),
|
|
||||||
topology,
|
topology,
|
||||||
)
|
)
|
||||||
.map_err(Error::ConfigureSystem)?;
|
.map_err(Error::ConfigureSystem)?;
|
||||||
|
|||||||
@@ -149,6 +149,21 @@ pub struct PlatformConfig {
|
|||||||
pub vfio_p2p_dma: bool,
|
pub vfio_p2p_dma: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
impl PlatformConfig {
|
||||||
|
/// Returns `None` if no SMBIOS-relevant platform fields are set, otherwise
|
||||||
|
/// `Some` with a [`SmbiosConfig`] built from the populated fields.
|
||||||
|
pub fn smbios_config(&self) -> Option<arch::x86_64::SmbiosConfig> {
|
||||||
|
let smbios = arch::x86_64::SmbiosConfig {
|
||||||
|
serial_number: self.serial_number.clone(),
|
||||||
|
uuid: self.uuid.clone(),
|
||||||
|
oem_strings: self.oem_strings.clone().unwrap_or_default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
(!smbios.is_empty()).then_some(smbios)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT: u32 = 1;
|
pub const DEFAULT_PCI_SEGMENT_APERTURE_WEIGHT: u32 = 1;
|
||||||
|
|
||||||
fn default_pci_segment_aperture_weight() -> u32 {
|
fn default_pci_segment_aperture_weight() -> u32 {
|
||||||
|
|||||||
Reference in New Issue
Block a user