Skip to content

Commit 5fba4ea

Browse files
committed
add concept of "secret free" VMs
Have the `struct Vm` constructor take an argument to indicate whether the VM should be secret free. Use this to determine the correct vm type for guest_memfd support, and store it inside the VM so that we don't have to pass bools to various functions. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent 0f49046 commit 5fba4ea

File tree

6 files changed

+74
-65
lines changed

6 files changed

+74
-65
lines changed

src/vmm/src/arch/aarch64/vm.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ use crate::arch::aarch64::gic::GicState;
88
use crate::vstate::memory::{GuestMemoryExtension, GuestMemoryState};
99
use crate::vstate::vm::{VmCommon, VmError};
1010

11+
/// The VM type for this architecture that allows us to use guest_memfd. On ARM, all VMs
12+
/// support guest_memfd and no special type is needed (in fact, no concept of vm types really
13+
/// exists, and the correspoding field of the CREATE_VM ioctl determines IPA size instead,
14+
/// e.g. the size of the guest physical address space. This value cannot be hardcoded, hence
15+
/// `None` to let the `Vm` constructor now that just normal [`Kvm::create_vm`] should be called,
16+
/// which internally determines the preferred IPA size.
17+
pub const VM_TYPE_FOR_SECRET_FREEDOM: Option<u64> = None;
18+
1119
/// Structure representing the current architecture's understand of what a "virtual machine" is.
1220
#[derive(Debug)]
1321
pub struct ArchVm {
@@ -30,8 +38,8 @@ pub enum ArchVmError {
3038

3139
impl ArchVm {
3240
/// Create a new `Vm` struct.
33-
pub fn new(kvm: &Kvm) -> Result<ArchVm, VmError> {
34-
let common = Self::create_common(kvm)?;
41+
pub fn new(kvm: &Kvm, secret_free: bool) -> Result<ArchVm, VmError> {
42+
let common = Self::create_common(kvm, secret_free)?;
3543
Ok(ArchVm {
3644
common,
3745
irqchip_handle: None,

src/vmm/src/arch/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use aarch64::kvm::{Kvm, KvmArchError, OptionalCapabilities};
1717
#[cfg(target_arch = "aarch64")]
1818
pub use aarch64::vcpu::*;
1919
#[cfg(target_arch = "aarch64")]
20-
pub use aarch64::vm::{ArchVm, ArchVmError, VmState};
20+
pub use aarch64::vm::{ArchVm, ArchVmError, VM_TYPE_FOR_SECRET_FREEDOM, VmState};
2121
#[cfg(target_arch = "aarch64")]
2222
pub use aarch64::{
2323
ConfigurationError, MMIO_MEM_SIZE, MMIO_MEM_START, arch_memory_regions,
@@ -35,7 +35,7 @@ pub use x86_64::kvm::{Kvm, KvmArchError};
3535
#[cfg(target_arch = "x86_64")]
3636
pub use x86_64::vcpu::*;
3737
#[cfg(target_arch = "x86_64")]
38-
pub use x86_64::vm::{ArchVm, ArchVmError, VmState};
38+
pub use x86_64::vm::{ArchVm, ArchVmError, VM_TYPE_FOR_SECRET_FREEDOM, VmState};
3939

4040
#[cfg(target_arch = "x86_64")]
4141
pub use crate::arch::x86_64::{

src/vmm/src/arch/x86_64/vm.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use std::fmt;
55

66
use kvm_bindings::{
77
KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE,
8-
KVM_PIT_SPEAKER_DUMMY, MsrList, kvm_clock_data, kvm_irqchip, kvm_pit_config, kvm_pit_state2,
8+
KVM_PIT_SPEAKER_DUMMY, KVM_X86_SW_PROTECTED_VM, MsrList, kvm_clock_data, kvm_irqchip,
9+
kvm_pit_config, kvm_pit_state2,
910
};
1011
use kvm_ioctls::Cap;
1112
use serde::{Deserialize, Serialize};
@@ -46,6 +47,9 @@ pub enum ArchVmError {
4647
SetTssAddress(kvm_ioctls::Error),
4748
}
4849

50+
/// The VM type for this architecture that allows us to use guest_memfd.
51+
pub const VM_TYPE_FOR_SECRET_FREEDOM: Option<u64> = Some(KVM_X86_SW_PROTECTED_VM as u64);
52+
4953
/// Structure representing the current architecture's understand of what a "virtual machine" is.
5054
#[derive(Debug)]
5155
pub struct ArchVm {
@@ -60,8 +64,8 @@ pub struct ArchVm {
6064

6165
impl ArchVm {
6266
/// Create a new `Vm` struct.
63-
pub fn new(kvm: &crate::vstate::kvm::Kvm) -> Result<ArchVm, VmError> {
64-
let common = Self::create_common(kvm)?;
67+
pub fn new(kvm: &crate::vstate::kvm::Kvm, secret_free: bool) -> Result<ArchVm, VmError> {
68+
let common = Self::create_common(kvm, secret_free)?;
6569

6670
let msrs_to_save = kvm.msrs_to_save().map_err(ArchVmError::GetMsrsToSave)?;
6771

src/vmm/src/builder.rs

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,12 @@ fn create_vmm_and_vcpus(
139139
event_manager: &mut EventManager,
140140
vcpu_count: u8,
141141
kvm_capabilities: Vec<KvmCapability>,
142+
secret_free: bool,
142143
) -> Result<(Vmm, Vec<Vcpu>), VmmError> {
143144
let kvm = Kvm::new(kvm_capabilities)?;
144145
// Set up Kvm Vm and register memory regions.
145146
// Build custom CPU config if a custom template is provided.
146-
let mut vm = Vm::new(&kvm)?;
147+
let mut vm = Vm::new(&kvm, secret_free)?;
147148

148149
let resource_allocator = ResourceAllocator::new()?;
149150

@@ -234,6 +235,7 @@ pub fn build_microvm_for_boot(
234235
event_manager,
235236
vm_resources.machine_config.vcpu_count,
236237
cpu_template.kvm_capabilities.clone(),
238+
vm_resources.machine_config.secret_free,
237239
)?;
238240

239241
vmm.vm
@@ -243,7 +245,7 @@ pub fn build_microvm_for_boot(
243245
let entry_point = load_kernel(
244246
MaybeBounce::new(
245247
boot_config.kernel_file.try_clone().unwrap(),
246-
vm_resources.machine_config.secret_free,
248+
vmm.vm.secret_free(),
247249
),
248250
vmm.vm.guest_memory(),
249251
)?;
@@ -256,7 +258,7 @@ pub fn build_microvm_for_boot(
256258

257259
Some(InitrdConfig::from_reader(
258260
vmm.vm.guest_memory(),
259-
MaybeBounce::new(initrd_file.as_fd(), vm_resources.machine_config.secret_free),
261+
MaybeBounce::new(initrd_file.as_fd(), vmm.vm.secret_free()),
260262
u64_to_usize(size),
261263
)?)
262264
}
@@ -291,24 +293,16 @@ pub fn build_microvm_for_boot(
291293
&mut boot_cmdline,
292294
vm_resources.block.devices.iter(),
293295
event_manager,
294-
vm_resources.machine_config.secret_free,
295296
)?;
296297
attach_net_devices(
297298
&mut vmm,
298299
&mut boot_cmdline,
299300
vm_resources.net_builder.iter(),
300301
event_manager,
301-
vm_resources.machine_config.secret_free,
302302
)?;
303303

304304
if let Some(unix_vsock) = vm_resources.vsock.get() {
305-
attach_unixsock_vsock_device(
306-
&mut vmm,
307-
&mut boot_cmdline,
308-
unix_vsock,
309-
event_manager,
310-
vm_resources.machine_config.secret_free,
311-
)?;
305+
attach_unixsock_vsock_device(&mut vmm, &mut boot_cmdline, unix_vsock, event_manager)?;
312306
}
313307

314308
if let Some(entropy) = vm_resources.entropy.get() {
@@ -457,6 +451,7 @@ pub fn build_microvm_from_snapshot(
457451
event_manager,
458452
vm_resources.machine_config.vcpu_count,
459453
microvm_state.kvm_state.kvm_cap_modifiers.clone(),
454+
false,
460455
)
461456
.map_err(StartMicrovmError::Internal)?;
462457

@@ -625,11 +620,10 @@ fn attach_virtio_device<T: 'static + VirtioDevice + MutEventSubscriber + Debug>(
625620
device: Arc<Mutex<T>>,
626621
cmdline: &mut LoaderKernelCmdline,
627622
is_vhost_user: bool,
628-
secret_free: bool,
629623
) -> Result<(), MmioError> {
630624
event_manager.add_subscriber(device.clone());
631625

632-
if secret_free {
626+
if vmm.vm.secret_free() {
633627
device.lock().unwrap().force_userspace_bounce_buffers();
634628
}
635629

@@ -688,7 +682,6 @@ fn attach_entropy_device(
688682
entropy_device.clone(),
689683
cmdline,
690684
false,
691-
false,
692685
)
693686
}
694687

@@ -697,7 +690,6 @@ fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
697690
cmdline: &mut LoaderKernelCmdline,
698691
blocks: I,
699692
event_manager: &mut EventManager,
700-
secret_free: bool,
701693
) -> Result<(), StartMicrovmError> {
702694
for block in blocks {
703695
let (id, is_vhost_user) = {
@@ -722,7 +714,6 @@ fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
722714
block.clone(),
723715
cmdline,
724716
is_vhost_user,
725-
secret_free,
726717
)?;
727718
}
728719
Ok(())
@@ -733,20 +724,11 @@ fn attach_net_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Net>>> + Debug>(
733724
cmdline: &mut LoaderKernelCmdline,
734725
net_devices: I,
735726
event_manager: &mut EventManager,
736-
secret_free: bool,
737727
) -> Result<(), StartMicrovmError> {
738728
for net_device in net_devices {
739729
let id = net_device.lock().expect("Poisoned lock").id().clone();
740730
// The device mutex mustn't be locked here otherwise it will deadlock.
741-
attach_virtio_device(
742-
event_manager,
743-
vmm,
744-
id,
745-
net_device.clone(),
746-
cmdline,
747-
false,
748-
secret_free,
749-
)?;
731+
attach_virtio_device(event_manager, vmm, id, net_device.clone(), cmdline, false)?;
750732
}
751733
Ok(())
752734
}
@@ -756,19 +738,10 @@ fn attach_unixsock_vsock_device(
756738
cmdline: &mut LoaderKernelCmdline,
757739
unix_vsock: &Arc<Mutex<Vsock<VsockUnixBackend>>>,
758740
event_manager: &mut EventManager,
759-
secret_free: bool,
760741
) -> Result<(), MmioError> {
761742
let id = String::from(unix_vsock.lock().expect("Poisoned lock").id());
762743
// The device mutex mustn't be locked here otherwise it will deadlock.
763-
attach_virtio_device(
764-
event_manager,
765-
vmm,
766-
id,
767-
unix_vsock.clone(),
768-
cmdline,
769-
false,
770-
secret_free,
771-
)
744+
attach_virtio_device(event_manager, vmm, id, unix_vsock.clone(), cmdline, false)
772745
}
773746

774747
fn attach_balloon_device(
@@ -779,15 +752,7 @@ fn attach_balloon_device(
779752
) -> Result<(), MmioError> {
780753
let id = String::from(balloon.lock().expect("Poisoned lock").id());
781754
// The device mutex mustn't be locked here otherwise it will deadlock.
782-
attach_virtio_device(
783-
event_manager,
784-
vmm,
785-
id,
786-
balloon.clone(),
787-
cmdline,
788-
false,
789-
false,
790-
)
755+
attach_virtio_device(event_manager, vmm, id, balloon.clone(), cmdline, false)
791756
}
792757

793758
// Adds `O_NONBLOCK` to the stdout flags.
@@ -963,7 +928,6 @@ pub(crate) mod tests {
963928
cmdline,
964929
block_dev_configs.devices.iter(),
965930
event_manager,
966-
false,
967931
)
968932
.unwrap();
969933
block_files
@@ -978,7 +942,7 @@ pub(crate) mod tests {
978942
let mut net_builder = NetBuilder::new();
979943
net_builder.build(net_config).unwrap();
980944

981-
let res = attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager, false);
945+
let res = attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager);
982946
res.unwrap();
983947
}
984948

@@ -999,7 +963,7 @@ pub(crate) mod tests {
999963
Arc::new(Mutex::new(mmds)),
1000964
);
1001965

1002-
attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager, false).unwrap();
966+
attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager).unwrap();
1003967
}
1004968

1005969
pub(crate) fn insert_vsock_device(
@@ -1012,7 +976,7 @@ pub(crate) mod tests {
1012976
let vsock = VsockBuilder::create_unixsock_vsock(vsock_config).unwrap();
1013977
let vsock = Arc::new(Mutex::new(vsock));
1014978

1015-
attach_unixsock_vsock_device(vmm, cmdline, &vsock, event_manager, false).unwrap();
979+
attach_unixsock_vsock_device(vmm, cmdline, &vsock, event_manager).unwrap();
1016980

1017981
assert!(
1018982
vmm.mmio_device_manager

src/vmm/src/device_manager/mmio.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ mod tests {
659659
let start_addr2 = GuestAddress(0x1000);
660660
let guest_mem = multi_region_mem_raw(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]);
661661
let kvm = Kvm::new(vec![]).expect("Cannot create Kvm");
662-
let mut vm = Vm::new(&kvm).unwrap();
662+
let mut vm = Vm::new(&kvm, false).unwrap();
663663
vm.register_memory_regions(guest_mem).unwrap();
664664
let mut device_manager = MMIODeviceManager::new();
665665
let mut resource_allocator = ResourceAllocator::new().unwrap();
@@ -690,7 +690,7 @@ mod tests {
690690
let start_addr2 = GuestAddress(0x1000);
691691
let guest_mem = multi_region_mem_raw(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]);
692692
let kvm = Kvm::new(vec![]).expect("Cannot create Kvm");
693-
let mut vm = Vm::new(&kvm).unwrap();
693+
let mut vm = Vm::new(&kvm, false).unwrap();
694694
vm.register_memory_regions(guest_mem).unwrap();
695695
let mut device_manager = MMIODeviceManager::new();
696696
let mut resource_allocator = ResourceAllocator::new().unwrap();
@@ -746,7 +746,7 @@ mod tests {
746746
let start_addr2 = GuestAddress(0x1000);
747747
let guest_mem = multi_region_mem_raw(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]);
748748
let kvm = Kvm::new(vec![]).expect("Cannot create Kvm");
749-
let mut vm = Vm::new(&kvm).unwrap();
749+
let mut vm = Vm::new(&kvm, false).unwrap();
750750
vm.register_memory_regions(guest_mem).unwrap();
751751

752752
#[cfg(target_arch = "x86_64")]

0 commit comments

Comments
 (0)