mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-09-28 17:45:44 +00:00
arch, vmm: Expose platform uuid via SMBIOS
Parse and set uuid. Signed-off-by: lizhaoxin1 <Lxiaoyouling@163.com> Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
3abc1e1e51
commit
bc3a276b43
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -50,6 +50,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"uuid",
|
||||||
"versionize",
|
"versionize",
|
||||||
"versionize_derive",
|
"versionize_derive",
|
||||||
"vm-fdt",
|
"vm-fdt",
|
||||||
|
@ -17,6 +17,7 @@ linux-loader = { version = "0.4.0", features = ["elf", "bzimage", "pe"] }
|
|||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
serde = { version = "1.0.141", features = ["rc", "derive"] }
|
serde = { version = "1.0.141", features = ["rc", "derive"] }
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
|
uuid = "1.1.1"
|
||||||
versionize = "0.1.6"
|
versionize = "0.1.6"
|
||||||
versionize_derive = "0.1.4"
|
versionize_derive = "0.1.4"
|
||||||
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-bitmap"] }
|
vm-memory = { version = "0.8.0", features = ["backend-mmap", "backend-bitmap"] }
|
||||||
|
@ -819,13 +819,14 @@ pub fn configure_system(
|
|||||||
rsdp_addr: Option<GuestAddress>,
|
rsdp_addr: Option<GuestAddress>,
|
||||||
sgx_epc_region: Option<SgxEpcRegion>,
|
sgx_epc_region: Option<SgxEpcRegion>,
|
||||||
serial_number: Option<&str>,
|
serial_number: Option<&str>,
|
||||||
|
uuid: 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, serial_number).map_err(Error::SmbiosSetup)?;
|
let size = smbios::setup_smbios(guest_mem, serial_number, uuid).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);
|
||||||
@ -1178,6 +1179,7 @@ mod tests {
|
|||||||
Some(layout::RSDP_POINTER),
|
Some(layout::RSDP_POINTER),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
assert!(config_err.is_err());
|
assert!(config_err.is_err());
|
||||||
|
|
||||||
@ -1191,7 +1193,17 @@ 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, None).unwrap();
|
configure_system(
|
||||||
|
&gm,
|
||||||
|
GuestAddress(0),
|
||||||
|
&None,
|
||||||
|
no_vcpus,
|
||||||
|
None,
|
||||||
|
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;
|
||||||
@ -1202,9 +1214,29 @@ 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, None).unwrap();
|
configure_system(
|
||||||
|
&gm,
|
||||||
|
GuestAddress(0),
|
||||||
|
&None,
|
||||||
|
no_vcpus,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
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,
|
||||||
|
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;
|
||||||
@ -1215,9 +1247,29 @@ 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, None).unwrap();
|
configure_system(
|
||||||
|
&gm,
|
||||||
|
GuestAddress(0),
|
||||||
|
&None,
|
||||||
|
no_vcpus,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
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,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12,6 +12,7 @@ use std::fmt::{self, Display};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use uuid::Uuid;
|
||||||
use vm_memory::ByteValued;
|
use vm_memory::ByteValued;
|
||||||
use vm_memory::{Address, Bytes, GuestAddress};
|
use vm_memory::{Address, Bytes, GuestAddress};
|
||||||
|
|
||||||
@ -27,6 +28,8 @@ pub enum Error {
|
|||||||
WriteSmbiosEp,
|
WriteSmbiosEp,
|
||||||
/// Failure to write additional data to memory
|
/// Failure to write additional data to memory
|
||||||
WriteData,
|
WriteData,
|
||||||
|
/// Failure to parse uuid, uuid format may be error
|
||||||
|
ParseUuid(uuid::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
@ -36,11 +39,16 @@ impl Display for Error {
|
|||||||
use self::Error::*;
|
use self::Error::*;
|
||||||
|
|
||||||
let description = match self {
|
let description = match self {
|
||||||
NotEnoughMemory => "There was too little guest memory to store the SMBIOS table",
|
NotEnoughMemory => {
|
||||||
AddressOverflow => "The SMBIOS table has too little address space to be stored",
|
"There was too little guest memory to store the SMBIOS table".to_string()
|
||||||
Clear => "Failure while zeroing out the memory for the SMBIOS table",
|
}
|
||||||
WriteSmbiosEp => "Failure to write SMBIOS entrypoint structure",
|
AddressOverflow => {
|
||||||
WriteData => "Failure to write additional data to memory",
|
"The SMBIOS table has too little address space to be stored".to_string()
|
||||||
|
}
|
||||||
|
Clear => "Failure while zeroing out the memory for the SMBIOS table".to_string(),
|
||||||
|
WriteSmbiosEp => "Failure to write SMBIOS entrypoint structure".to_string(),
|
||||||
|
WriteData => "Failure to write additional data to memory".to_string(),
|
||||||
|
ParseUuid(e) => format!("Failure to parse uuid: {}", e),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(f, "SMBIOS error: {}", description)
|
write!(f, "SMBIOS error: {}", description)
|
||||||
@ -161,7 +169,11 @@ fn write_string(
|
|||||||
Ok(curptr)
|
Ok(curptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Result<u64> {
|
pub fn setup_smbios(
|
||||||
|
mem: &GuestMemoryMmap,
|
||||||
|
serial_number: Option<&str>,
|
||||||
|
uuid: 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)?;
|
||||||
@ -188,6 +200,12 @@ pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Resul
|
|||||||
|
|
||||||
{
|
{
|
||||||
handle += 1;
|
handle += 1;
|
||||||
|
|
||||||
|
let uuid_number = uuid
|
||||||
|
.map(Uuid::parse_str)
|
||||||
|
.transpose()
|
||||||
|
.map_err(Error::ParseUuid)?
|
||||||
|
.unwrap_or(Uuid::nil());
|
||||||
let smbios_sysinfo = SmbiosSysInfo {
|
let smbios_sysinfo = SmbiosSysInfo {
|
||||||
typ: SYSTEM_INFORMATION,
|
typ: SYSTEM_INFORMATION,
|
||||||
length: mem::size_of::<SmbiosSysInfo>() as u8,
|
length: mem::size_of::<SmbiosSysInfo>() as u8,
|
||||||
@ -195,6 +213,7 @@ pub fn setup_smbios(mem: &GuestMemoryMmap, serial_number: Option<&str>) -> Resul
|
|||||||
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
|
serial_number: serial_number.map(|_| 3).unwrap_or_default(), // 3rd string
|
||||||
|
uuid: uuid_number.to_bytes_le(), // set uuid
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
|
curptr = write_and_incr(mem, smbios_sysinfo, curptr)?;
|
||||||
@ -266,7 +285,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, None).unwrap();
|
setup_smbios(&mem, None, None).unwrap();
|
||||||
|
|
||||||
let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();
|
let smbios_ep: Smbios30Entrypoint = mem.read_obj(GuestAddress(SMBIOS_START)).unwrap();
|
||||||
|
|
||||||
|
@ -1119,6 +1119,14 @@ impl Vm {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|p| p.serial_number.clone());
|
.and_then(|p| p.serial_number.clone());
|
||||||
|
|
||||||
|
let uuid = self
|
||||||
|
.config
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.platform
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|p| p.uuid.clone());
|
||||||
|
|
||||||
arch::configure_system(
|
arch::configure_system(
|
||||||
&mem,
|
&mem,
|
||||||
arch::layout::CMDLINE_START,
|
arch::layout::CMDLINE_START,
|
||||||
@ -1127,6 +1135,7 @@ impl Vm {
|
|||||||
rsdp_addr,
|
rsdp_addr,
|
||||||
sgx_epc_region,
|
sgx_epc_region,
|
||||||
serial_number.as_deref(),
|
serial_number.as_deref(),
|
||||||
|
uuid.as_deref(),
|
||||||
)
|
)
|
||||||
.map_err(Error::ConfigureSystem)?;
|
.map_err(Error::ConfigureSystem)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user