Skip to content

Commit

Permalink
Add SMBIOS OEM Strings support (aarch64 only)
Browse files Browse the repository at this point in the history
Add a new API `krun_set_smbios_oem_strings()` to set SMBIOS
OEM Strings (type 11), and all the internal machinery to
provide them to the firmware. The EDK2 firmware expect the
SMBIOS tables on address 0x4000_F000.

Currently, this is only supported on aarch64 architectures.

Signed-off-by: German Maglione <gmaglione@redhat.com>
  • Loading branch information
germag authored and slp committed May 28, 2024
1 parent cc568e2 commit 41d0f60
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 3 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions include/libkrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@ int32_t krun_set_snd_device(uint32_t ctx_id, bool enable);
*/
int32_t krun_set_rlimits(uint32_t ctx_id, const char *const rlimits[]);

/**
* Sets the SMBIOS OEM Strings.
*
* Arguments:
* "ctx_id" - the configuration context ID.
* "oem_strings" - an array of string pointers. Must be terminated with an additional NULL pointer.
*
* Returns:
* Zero on success or a negative error number on failure.
*/
int32_t krun_set_smbios_oem_strings(uint32_t ctx_id, const char *const oem_strings[]);

/**
* Sets the working directory for the executable to be run inside the microVM.
*
Expand Down
1 change: 1 addition & 0 deletions src/arch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ libc = ">=0.2.39"
vm-memory = { version = ">=0.13", features = ["backend-mmap"] }

arch_gen = { path = "../arch_gen" }
smbios = { path = "../smbios" }
utils = { path = "../utils" }

[target.'cfg(target_os = "linux")'.dependencies]
Expand Down
3 changes: 3 additions & 0 deletions src/arch/src/aarch64/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,6 @@ pub const GTIMER_PHYS: u32 = 12;
pub const MAPPED_IO_START: u64 = 1 << 30; // 1 GB
#[cfg(feature = "efi")]
pub const MAPPED_IO_START: u64 = 0x0a00_0000;

#[cfg(feature = "efi")]
pub const SMBIOS_START: u64 = 0x4000_F000;
14 changes: 14 additions & 0 deletions src/arch/src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,20 @@ use self::gic::GICDevice;
use crate::ArchMemoryInfo;
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap};

#[cfg(feature = "efi")]
use smbios;

/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
pub enum Error {
/// Failed to create a Flattened Device Tree for this aarch64 microVM.
SetupFDT(fdt::Error),
/// Failed to compute the initrd address.
InitrdAddress,

#[cfg(feature = "efi")]
/// SMBIOS Error
Smbios(smbios::Error),
}

/// The start of the memory area reserved for MMIO devices.
Expand Down Expand Up @@ -80,6 +87,7 @@ pub fn arch_memory_regions(size: usize) -> (ArchMemoryInfo, Vec<(GuestAddress, u
/// * `device_info` - A hashmap containing the attached devices for building FDT device nodes.
/// * `gic_device` - The GIC device.
/// * `initrd` - Information about an optional initrd.
#[allow(clippy::too_many_arguments)]
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
guest_mem: &GuestMemoryMmap,
arch_memory_info: &ArchMemoryInfo,
Expand All @@ -88,6 +96,7 @@ pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
device_info: &HashMap<(DeviceType, String), T>,
gic_device: &Box<dyn GICDevice>,
initrd: &Option<super::InitrdConfig>,
_smbios_oem_strings: &Option<Vec<String>>,
) -> super::Result<()> {
fdt::create_fdt(
guest_mem,
Expand All @@ -99,6 +108,11 @@ pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
initrd,
)
.map_err(Error::SetupFDT)?;

#[cfg(feature = "efi")]
smbios::setup_smbios(guest_mem, layout::SMBIOS_START, _smbios_oem_strings)
.map_err(Error::Smbios)?;

Ok(())
}

Expand Down
32 changes: 32 additions & 0 deletions src/libkrun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,38 @@ pub unsafe extern "C" fn krun_set_console_output(ctx_id: u32, c_filepath: *const
}
}

#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub unsafe extern "C" fn krun_set_smbios_oem_strings(
ctx_id: u32,
oem_strings: *const *const c_char,
) -> i32 {
if oem_strings.is_null() {
return -libc::EINVAL;
}

let cstr_ptr_slice = slice::from_raw_parts(oem_strings, MAX_ARGS);

let mut oem_strings = Vec::new();

for cstr_ptr in cstr_ptr_slice.iter().take_while(|p| !p.is_null()) {
let Ok(s) = CStr::from_ptr(*cstr_ptr).to_str() else {
return -libc::EINVAL;
};
oem_strings.push(s.to_string());
}

match CTX_MAP.lock().unwrap().entry(ctx_id) {
Entry::Occupied(mut ctx_cfg) => {
ctx_cfg.get_mut().vmr.smbios_oem_strings =
(!oem_strings.is_empty()).then_some(oem_strings)
}
Entry::Vacant(_) => return -libc::ENOENT,
}

KRUN_SUCCESS
}

#[cfg(feature = "net")]
fn create_virtio_net(ctx_cfg: &mut ContextConfig, backend: VirtioNetBackend) {
let mac = if let Some(mac) = ctx_cfg.mac {
Expand Down
8 changes: 6 additions & 2 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,8 +638,12 @@ pub fn build_microvm(
#[cfg(not(feature = "tee"))]
let initrd_config = None;

vmm.configure_system(vcpus.as_slice(), &initrd_config)
.map_err(StartMicrovmError::Internal)?;
vmm.configure_system(
vcpus.as_slice(),
&initrd_config,
&vm_resources.smbios_oem_strings,
)
.map_err(StartMicrovmError::Internal)?;

#[cfg(feature = "tee")]
{
Expand Down
9 changes: 8 additions & 1 deletion src/vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,12 @@ impl Vmm {
}

/// Configures the system for boot.
pub fn configure_system(&self, vcpus: &[Vcpu], initrd: &Option<InitrdConfig>) -> Result<()> {
pub fn configure_system(
&self,
vcpus: &[Vcpu],
initrd: &Option<InitrdConfig>,
_smbios_oem_strings: &Option<Vec<String>>,
) -> Result<()> {
#[cfg(target_arch = "x86_64")]
{
let cmdline_len = if cfg!(feature = "tee") {
Expand Down Expand Up @@ -292,6 +297,7 @@ impl Vmm {
self.mmio_device_manager.get_device_info(),
self.vm.get_irqchip(),
initrd,
_smbios_oem_strings,
)
.map_err(Error::ConfigureSystem)?;
}
Expand All @@ -307,6 +313,7 @@ impl Vmm {
self.mmio_device_manager.get_device_info(),
self.vm.get_irqchip(),
initrd,
_smbios_oem_strings,
)
.map_err(Error::ConfigureSystem)?;
}
Expand Down
3 changes: 3 additions & 0 deletions src/vmm/src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub struct VmResources {
pub snd_device: bool,
/// File to send console output.
pub console_output: Option<PathBuf>,
/// SMBIOS OEM Strings
pub smbios_oem_strings: Option<Vec<String>>,
}

impl VmResources {
Expand Down Expand Up @@ -327,6 +329,7 @@ mod tests {
#[cfg(feature = "snd")]
enable_snd: False,
console_output: None,
smbios_oem_strings: None,
}
}

Expand Down

0 comments on commit 41d0f60

Please sign in to comment.