Skip to content

Commit b9883ea

Browse files
committed
Add "krun_set_nested_virt" API
After introducing Nested Virt (EL2) support on macOS, let's add a new API to enable library users to request its enablement. Signed-off-by: Sergio Lopez <[email protected]>
1 parent 6d1fd78 commit b9883ea

File tree

5 files changed

+49
-8
lines changed

5 files changed

+49
-8
lines changed

include/libkrun.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,23 @@ int32_t krun_setuid(uint32_t ctx_id, uid_t uid);
536536
*/
537537
int32_t krun_setgid(uint32_t ctx_id, gid_t gid);
538538

539+
/**
540+
* Configures the microVM to support Nested Virtualization
541+
*
542+
* Arguments:
543+
* "ctx_id" - the configuration context ID.
544+
* "enabled" - true to enable Nested Virtualization in the microVM.
545+
*
546+
* Notes:
547+
* This feature is only supported on macOS.
548+
*
549+
* Returns:
550+
* Zero on success or a negative error number on failure. Success doesn't imply that
551+
* Nested Virtualization is supported on the system, only that it's going to be requested
552+
* when the microVM is created after calling "krun_start_enter".
553+
*/
554+
int32_t krun_set_nested_virt(uint32_t ctx_id, bool enabled);
555+
539556
/**
540557
* Starts and enters the microVM with the configured parameters. The VMM will attempt to take over
541558
* stdin/stdout to manage them on behalf of the process running inside the isolated environment,

src/libkrun/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,23 @@ pub unsafe extern "C" fn krun_set_console_output(ctx_id: u32, c_filepath: *const
10481048
}
10491049
}
10501050

1051+
#[allow(clippy::missing_safety_doc)]
1052+
#[no_mangle]
1053+
pub unsafe extern "C" fn krun_set_nested_virt(ctx_id: u32, enabled: bool) -> i32 {
1054+
if enabled && !cfg!(target_os = "macos") {
1055+
return -libc::EINVAL;
1056+
}
1057+
1058+
match CTX_MAP.lock().unwrap().entry(ctx_id) {
1059+
Entry::Occupied(mut ctx_cfg) => {
1060+
let cfg = ctx_cfg.get_mut();
1061+
cfg.vmr.nested_enabled = enabled;
1062+
KRUN_SUCCESS
1063+
}
1064+
Entry::Vacant(_) => -libc::ENOENT,
1065+
}
1066+
}
1067+
10511068
#[allow(clippy::missing_safety_doc)]
10521069
#[no_mangle]
10531070
pub unsafe extern "C" fn krun_set_smbios_oem_strings(

src/vmm/src/builder.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ pub fn build_microvm(
533533

534534
#[cfg(not(feature = "tee"))]
535535
#[allow(unused_mut)]
536-
let mut vm = setup_vm(&guest_memory)?;
536+
let mut vm = setup_vm(&guest_memory, vm_resources.nested_enabled)?;
537537

538538
#[cfg(feature = "tee")]
539539
let (kvm, vm) = {
@@ -723,6 +723,7 @@ pub fn build_microvm(
723723
payload_config.entry_addr,
724724
&exit_evt,
725725
vcpu_list.clone(),
726+
vm_resources.nested_enabled,
726727
)
727728
.map_err(StartMicrovmError::Internal)?;
728729

@@ -1260,6 +1261,7 @@ fn load_cmdline(vmm: &Vmm) -> std::result::Result<(), StartMicrovmError> {
12601261
#[cfg(all(target_os = "linux", not(feature = "tee")))]
12611262
pub(crate) fn setup_vm(
12621263
guest_memory: &GuestMemoryMmap,
1264+
_nested_enabled: bool,
12631265
) -> std::result::Result<Vm, StartMicrovmError> {
12641266
let kvm = KvmContext::new()
12651267
.map_err(Error::KvmContext)
@@ -1289,8 +1291,9 @@ pub(crate) fn setup_vm(
12891291
#[cfg(target_os = "macos")]
12901292
pub(crate) fn setup_vm(
12911293
guest_memory: &GuestMemoryMmap,
1294+
nested_enabled: bool,
12921295
) -> std::result::Result<Vm, StartMicrovmError> {
1293-
let mut vm = Vm::new(false)
1296+
let mut vm = Vm::new(nested_enabled)
12941297
.map_err(Error::Vm)
12951298
.map_err(StartMicrovmError::Internal)?;
12961299
vm.memory_init(guest_memory)
@@ -1473,6 +1476,7 @@ fn create_vcpus_aarch64(
14731476
entry_addr: GuestAddress,
14741477
exit_evt: &EventFd,
14751478
vcpu_list: Arc<VcpuList>,
1479+
nested_enabled: bool,
14761480
) -> super::Result<Vec<Vcpu>> {
14771481
let mut vcpus = Vec::with_capacity(vcpu_config.vcpu_count as usize);
14781482
let mut boot_senders: HashMap<u64, Sender<u64>> = HashMap::new();
@@ -1491,7 +1495,7 @@ fn create_vcpus_aarch64(
14911495
boot_receiver,
14921496
exit_evt.try_clone().map_err(Error::EventFd)?,
14931497
vcpu_list.clone(),
1494-
false,
1498+
nested_enabled,
14951499
)
14961500
.map_err(Error::Vcpu)?;
14971501

@@ -1916,7 +1920,7 @@ pub mod tests {
19161920

19171921
let (guest_memory, _arch_memory_info, _shm_manager, _payload_config) =
19181922
default_guest_memory(128).unwrap();
1919-
let vm = setup_vm(&guest_memory).unwrap();
1923+
let vm = setup_vm(&guest_memory, false).unwrap();
19201924
let _kvmioapic = KvmIoapic::new(&vm.fd()).unwrap();
19211925

19221926
// Dummy entry_addr, vcpus will not boot.
@@ -1939,7 +1943,7 @@ pub mod tests {
19391943
fn test_create_vcpus_aarch64() {
19401944
let (guest_memory, _arch_memory_info) =
19411945
create_guest_memory(128, None, Payload::Empty).unwrap();
1942-
let vm = setup_vm(&guest_memory).unwrap();
1946+
let vm = setup_vm(&guest_memory, false).unwrap();
19431947
let vcpu_count = 2;
19441948

19451949
let vcpu_config = VcpuConfig {

src/vmm/src/device_manager/kvm/mmio.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ mod tests {
402402
let guest_mem =
403403
GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap();
404404
let vcpu_count: u8 = 1;
405-
let vm = builder::setup_vm(&guest_mem).unwrap();
405+
let vm = builder::setup_vm(&guest_mem, false).unwrap();
406406
let mut device_manager =
407407
MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX));
408408
let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap();
@@ -422,7 +422,7 @@ mod tests {
422422
let guest_mem =
423423
GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap();
424424
let vcpu_count: u8 = 1;
425-
let vm = builder::setup_vm(&guest_mem).unwrap();
425+
let vm = builder::setup_vm(&guest_mem, false).unwrap();
426426
let mut device_manager =
427427
MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX));
428428
let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap();
@@ -523,7 +523,7 @@ mod tests {
523523
let guest_mem =
524524
GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap();
525525
let vcpu_count = 1;
526-
let vm = builder::setup_vm(&guest_mem).unwrap();
526+
let vm = builder::setup_vm(&guest_mem, false).unwrap();
527527
let mut device_manager =
528528
MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX));
529529
let mut cmdline = kernel_cmdline::Cmdline::new(4096);

src/vmm/src/resources.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ pub struct VmResources {
118118
pub console_output: Option<PathBuf>,
119119
/// SMBIOS OEM Strings
120120
pub smbios_oem_strings: Option<Vec<String>>,
121+
/// Whether to enable nested virtualization.
122+
pub nested_enabled: bool,
121123
}
122124

123125
impl VmResources {
@@ -341,6 +343,7 @@ mod tests {
341343
enable_snd: False,
342344
console_output: None,
343345
smbios_oem_strings: None,
346+
nested_enabled: false,
344347
}
345348
}
346349

0 commit comments

Comments
 (0)