Skip to content

Commit

Permalink
Allow the efi flavor to not link against libkrunfw
Browse files Browse the repository at this point in the history
The efi flavor doesn't need a bundled kernel, so allow it to be built
without linking against libkrunfw.

Signed-off-by: Sergio Lopez <[email protected]>
  • Loading branch information
slp committed Feb 7, 2024
1 parent a271ad1 commit 3846bb0
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/libkrun/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fn main() {
println!("cargo:rustc-link-lib=framework=Hypervisor");
#[cfg(target_os = "macos")]
println!("cargo:rustc-link-search=/opt/homebrew/lib");
#[cfg(not(feature = "tee"))]
#[cfg(all(not(feature = "tee"), not(feature = "efi")))]
println!("cargo:rustc-link-lib=krunfw");
#[cfg(feature = "tee")]
println!("cargo:rustc-link-lib=krunfw-sev");
Expand Down
24 changes: 22 additions & 2 deletions src/libkrun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use std::sync::Mutex;
#[cfg(feature = "blk")]
use devices::virtio::CacheType;
use env_logger::Env;
use libc::{c_char, c_int, size_t};
#[cfg(not(feature = "efi"))]
use libc::size_t;
use libc::{c_char, c_int};
use once_cell::sync::Lazy;
use polly::event_manager::EventManager;
use vmm::resources::VmResources;
Expand All @@ -30,6 +32,7 @@ use vmm::vmm_config::block::BlockDeviceConfig;
use vmm::vmm_config::boot_source::{BootSourceConfig, DEFAULT_KERNEL_CMDLINE};
#[cfg(not(feature = "tee"))]
use vmm::vmm_config::fs::FsDeviceConfig;
#[cfg(not(feature = "efi"))]
use vmm::vmm_config::kernel_bundle::KernelBundle;
#[cfg(feature = "tee")]
use vmm::vmm_config::kernel_bundle::{InitrdBundle, QbootBundle};
Expand All @@ -39,6 +42,7 @@ use vmm::vmm_config::net::NetworkInterfaceConfig;
use vmm::vmm_config::vsock::VsockDeviceConfig;

// Minimum krunfw version we require.
#[cfg(not(feature = "efi"))]
const KRUNFW_MIN_VERSION: u32 = 4;
// Value returned on success. We use libc's errors otherwise.
const KRUN_SUCCESS: i32 = 0;
Expand Down Expand Up @@ -206,7 +210,7 @@ impl ContextConfig {
static CTX_MAP: Lazy<Mutex<HashMap<u32, ContextConfig>>> = Lazy::new(|| Mutex::new(HashMap::new()));
static CTX_IDS: AtomicI32 = AtomicI32::new(0);

#[cfg(not(feature = "tee"))]
#[cfg(all(not(feature = "tee"), not(feature = "efi")))]
#[link(name = "krunfw")]
extern "C" {
fn krunfw_get_kernel(
Expand Down Expand Up @@ -245,6 +249,7 @@ pub extern "C" fn krun_set_log_level(level: u32) -> i32 {
}

#[no_mangle]
#[cfg(not(feature = "efi"))]
pub extern "C" fn krun_create_ctx() -> i32 {
let krunfw_version = unsafe { krunfw_get_version() };
if krunfw_version < KRUNFW_MIN_VERSION {
Expand Down Expand Up @@ -302,6 +307,21 @@ pub extern "C" fn krun_create_ctx() -> i32 {
ctx_id
}

#[no_mangle]
#[cfg(feature = "efi")]
pub extern "C" fn krun_create_ctx() -> i32 {
let ctx_cfg = ContextConfig::default();

let ctx_id = CTX_IDS.fetch_add(1, Ordering::SeqCst);
if ctx_id == i32::MAX || CTX_MAP.lock().unwrap().contains_key(&(ctx_id as u32)) {
// libkrun is not intended to be used as a daemon for managing VMs.
panic!("Context ID namespace exhausted");
}
CTX_MAP.lock().unwrap().insert(ctx_id as u32, ctx_cfg);

ctx_id
}

#[no_mangle]
pub extern "C" fn krun_free_ctx(ctx_id: u32) -> i32 {
match CTX_MAP.lock().unwrap().remove(&ctx_id) {
Expand Down
52 changes: 33 additions & 19 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ use utils::eventfd::EventFd;
use utils::time::TimestampUs;
#[cfg(all(target_os = "linux", target_arch = "x86_64", not(feature = "tee")))]
use vm_memory::mmap::GuestRegionMmap;
#[cfg(not(feature = "efi"))]
use vm_memory::mmap::MmapRegion;
#[cfg(any(target_arch = "aarch64", feature = "tee"))]
use vm_memory::Bytes;
#[cfg(target_os = "linux")]
use vm_memory::GuestMemory;
use vm_memory::{mmap::MmapRegion, GuestAddress, GuestMemoryMmap};
use vm_memory::{GuestAddress, GuestMemoryMmap};

#[cfg(feature = "efi")]
static EDK2_BINARY: &[u8] = include_bytes!("../../../edk2/KRUN_EFI.silent.fd");
Expand Down Expand Up @@ -272,9 +274,11 @@ pub fn build_microvm(
// Timestamp for measuring microVM boot duration.
let request_ts = TimestampUs::default();

#[cfg(not(feature = "efi"))]
let kernel_bundle = vm_resources
.kernel_bundle()
.ok_or(StartMicrovmError::MissingKernelConfig)?;
#[cfg(not(feature = "efi"))]
let kernel_region = unsafe {
MmapRegion::build_raw(kernel_bundle.host_addr as *mut u8, kernel_bundle.size, 0, 0)
.map_err(StartMicrovmError::KernelBundle)?
Expand All @@ -295,8 +299,11 @@ pub fn build_microvm(
.vm_config()
.mem_size_mib
.ok_or(StartMicrovmError::MissingMemSizeConfig)?,
#[cfg(not(feature = "efi"))]
kernel_region,
#[cfg(not(feature = "efi"))]
kernel_bundle.guest_addr,
#[cfg(not(feature = "efi"))]
kernel_bundle.size,
#[cfg(feature = "tee")]
qboot_bundle,
Expand Down Expand Up @@ -480,11 +487,10 @@ pub fn build_microvm(

#[cfg(all(target_arch = "aarch64", target_os = "macos"))]
{
let start_addr = if cfg!(feature = "efi") {
GuestAddress(0u64)
} else {
GuestAddress(kernel_bundle.guest_addr)
};
#[cfg(not(feature = "efi"))]
let start_addr = GuestAddress(kernel_bundle.guest_addr);
#[cfg(feature = "efi")]
let start_addr = GuestAddress(0u64);

vcpus = create_vcpus_aarch64(
&vm,
Expand Down Expand Up @@ -684,29 +690,37 @@ pub fn create_guest_memory(
Ok((guest_mem, arch_mem_info))
}

#[cfg(target_arch = "aarch64")]
#[cfg(all(target_arch = "aarch64", not(feature = "efi")))]
pub fn create_guest_memory(
mem_size_mib: usize,
kernel_region: MmapRegion,
kernel_load_addr: u64,
kernel_size: usize,
) -> std::result::Result<(GuestMemoryMmap, ArchMemoryInfo), StartMicrovmError> {
let mem_size = mem_size_mib << 20;
let (arch_mem_info, arch_mem_regions) = arch::arch_memory_regions(mem_size);

let guest_mem = GuestMemoryMmap::from_ranges(&arch_mem_regions)
.map_err(StartMicrovmError::GuestMemoryMmap)?;

let kernel_data = unsafe { std::slice::from_raw_parts(kernel_region.as_ptr(), kernel_size) };
guest_mem
.write(kernel_data, GuestAddress(kernel_load_addr))
.unwrap();
Ok((guest_mem, arch_mem_info))
}

#[cfg(all(target_arch = "aarch64", feature = "efi"))]
pub fn create_guest_memory(
mem_size_mib: usize,
_kernel_region: MmapRegion,
_kernel_load_addr: u64,
_kernel_size: usize,
) -> std::result::Result<(GuestMemoryMmap, ArchMemoryInfo), StartMicrovmError> {
let mem_size = mem_size_mib << 20;
let (arch_mem_info, arch_mem_regions) = arch::arch_memory_regions(mem_size);

let guest_mem = GuestMemoryMmap::from_ranges(&arch_mem_regions)
.map_err(StartMicrovmError::GuestMemoryMmap)?;

#[cfg(feature = "efi")]
guest_mem.write(EDK2_BINARY, GuestAddress(0u64)).unwrap();
#[cfg(not(feature = "efi"))]
{
let kernel_data =
unsafe { std::slice::from_raw_parts(_kernel_region.as_ptr(), _kernel_size) };
guest_mem
.write(kernel_data, GuestAddress(_kernel_load_addr))
.unwrap();
}
Ok((guest_mem, arch_mem_info))
}

Expand Down

0 comments on commit 3846bb0

Please sign in to comment.