Skip to content

Commit 4ab701c

Browse files
committed
use userspace bounce buffers if secret freedom is enabled
Needed because we cannot do I/O straight into secret hidden memory - the host kernel cannot access it. Signed-off-by: Patrick Roy <[email protected]>
1 parent 32b6679 commit 4ab701c

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

src/vmm/src/builder.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ pub fn build_microvm_for_boot(
243243
let entry_point = load_kernel(
244244
MaybeBounce::new(
245245
boot_config.kernel_file.try_clone().unwrap(),
246-
vm_resources.machine_config.mem_config.secret_free,
246+
vm_resources.machine_config.secret_free,
247247
),
248248
vmm.vm.guest_memory(),
249249
)?;
@@ -258,7 +258,7 @@ pub fn build_microvm_for_boot(
258258
vmm.vm.guest_memory(),
259259
MaybeBounce::new(
260260
initrd_file.as_fd(),
261-
vm_resources.machine_config.mem_config.secret_free,
261+
vm_resources.machine_config.secret_free,
262262
),
263263
u64_to_usize(size),
264264
)?)
@@ -294,16 +294,24 @@ pub fn build_microvm_for_boot(
294294
&mut boot_cmdline,
295295
vm_resources.block.devices.iter(),
296296
event_manager,
297+
vm_resources.machine_config.secret_free,
297298
)?;
298299
attach_net_devices(
299300
&mut vmm,
300301
&mut boot_cmdline,
301302
vm_resources.net_builder.iter(),
302303
event_manager,
304+
vm_resources.machine_config.secret_free,
303305
)?;
304306

305307
if let Some(unix_vsock) = vm_resources.vsock.get() {
306-
attach_unixsock_vsock_device(&mut vmm, &mut boot_cmdline, unix_vsock, event_manager)?;
308+
attach_unixsock_vsock_device(
309+
&mut vmm,
310+
&mut boot_cmdline,
311+
unix_vsock,
312+
event_manager,
313+
vm_resources.machine_config.secret_free,
314+
)?;
307315
}
308316

309317
if let Some(entropy) = vm_resources.entropy.get() {
@@ -620,9 +628,14 @@ fn attach_virtio_device<T: 'static + VirtioDevice + MutEventSubscriber + Debug>(
620628
device: Arc<Mutex<T>>,
621629
cmdline: &mut LoaderKernelCmdline,
622630
is_vhost_user: bool,
631+
secret_free: bool,
623632
) -> Result<(), MmioError> {
624633
event_manager.add_subscriber(device.clone());
625634

635+
if secret_free {
636+
device.lock().unwrap().force_userspace_bounce_buffers();
637+
}
638+
626639
// The device mutex mustn't be locked here otherwise it will deadlock.
627640
let device = MmioTransport::new(vmm.vm.guest_memory().clone(), device, is_vhost_user);
628641
vmm.mmio_device_manager
@@ -678,6 +691,7 @@ fn attach_entropy_device(
678691
entropy_device.clone(),
679692
cmdline,
680693
false,
694+
false,
681695
)
682696
}
683697

@@ -686,6 +700,7 @@ fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
686700
cmdline: &mut LoaderKernelCmdline,
687701
blocks: I,
688702
event_manager: &mut EventManager,
703+
secret_free: bool,
689704
) -> Result<(), StartMicrovmError> {
690705
for block in blocks {
691706
let (id, is_vhost_user) = {
@@ -710,6 +725,7 @@ fn attach_block_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Block>>> + Debug>(
710725
block.clone(),
711726
cmdline,
712727
is_vhost_user,
728+
secret_free,
713729
)?;
714730
}
715731
Ok(())
@@ -720,11 +736,20 @@ fn attach_net_devices<'a, I: Iterator<Item = &'a Arc<Mutex<Net>>> + Debug>(
720736
cmdline: &mut LoaderKernelCmdline,
721737
net_devices: I,
722738
event_manager: &mut EventManager,
739+
secret_free: bool,
723740
) -> Result<(), StartMicrovmError> {
724741
for net_device in net_devices {
725742
let id = net_device.lock().expect("Poisoned lock").id().clone();
726743
// The device mutex mustn't be locked here otherwise it will deadlock.
727-
attach_virtio_device(event_manager, vmm, id, net_device.clone(), cmdline, false)?;
744+
attach_virtio_device(
745+
event_manager,
746+
vmm,
747+
id,
748+
net_device.clone(),
749+
cmdline,
750+
false,
751+
secret_free,
752+
)?;
728753
}
729754
Ok(())
730755
}
@@ -734,10 +759,19 @@ fn attach_unixsock_vsock_device(
734759
cmdline: &mut LoaderKernelCmdline,
735760
unix_vsock: &Arc<Mutex<Vsock<VsockUnixBackend>>>,
736761
event_manager: &mut EventManager,
762+
secret_free: bool,
737763
) -> Result<(), MmioError> {
738764
let id = String::from(unix_vsock.lock().expect("Poisoned lock").id());
739765
// The device mutex mustn't be locked here otherwise it will deadlock.
740-
attach_virtio_device(event_manager, vmm, id, unix_vsock.clone(), cmdline, false)
766+
attach_virtio_device(
767+
event_manager,
768+
vmm,
769+
id,
770+
unix_vsock.clone(),
771+
cmdline,
772+
false,
773+
secret_free,
774+
)
741775
}
742776

743777
fn attach_balloon_device(
@@ -748,7 +782,15 @@ fn attach_balloon_device(
748782
) -> Result<(), MmioError> {
749783
let id = String::from(balloon.lock().expect("Poisoned lock").id());
750784
// The device mutex mustn't be locked here otherwise it will deadlock.
751-
attach_virtio_device(event_manager, vmm, id, balloon.clone(), cmdline, false)
785+
attach_virtio_device(
786+
event_manager,
787+
vmm,
788+
id,
789+
balloon.clone(),
790+
cmdline,
791+
false,
792+
false,
793+
)
752794
}
753795

754796
// Adds `O_NONBLOCK` to the stdout flags.
@@ -924,6 +966,7 @@ pub(crate) mod tests {
924966
cmdline,
925967
block_dev_configs.devices.iter(),
926968
event_manager,
969+
false,
927970
)
928971
.unwrap();
929972
block_files
@@ -938,7 +981,7 @@ pub(crate) mod tests {
938981
let mut net_builder = NetBuilder::new();
939982
net_builder.build(net_config).unwrap();
940983

941-
let res = attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager);
984+
let res = attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager, false);
942985
res.unwrap();
943986
}
944987

@@ -959,7 +1002,7 @@ pub(crate) mod tests {
9591002
Arc::new(Mutex::new(mmds)),
9601003
);
9611004

962-
attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager).unwrap();
1005+
attach_net_devices(vmm, cmdline, net_builder.iter(), event_manager, false).unwrap();
9631006
}
9641007

9651008
pub(crate) fn insert_vsock_device(
@@ -972,7 +1015,7 @@ pub(crate) mod tests {
9721015
let vsock = VsockBuilder::create_unixsock_vsock(vsock_config).unwrap();
9731016
let vsock = Arc::new(Mutex::new(vsock));
9741017

975-
attach_unixsock_vsock_device(vmm, cmdline, &vsock, event_manager).unwrap();
1018+
attach_unixsock_vsock_device(vmm, cmdline, &vsock, event_manager, false).unwrap();
9761019

9771020
assert!(
9781021
vmm.mmio_device_manager

src/vmm/src/devices/virtio/block/vhost_user/device.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
296296

297297
fn force_userspace_bounce_buffers(&mut self) {
298298
// Nothing Firecracker can do about this, the backend would need to do the bouncing
299+
panic!("vhost-user-blk is incompatible with userspace bounce buffers")
299300
}
300301

301302
fn userspace_bounce_buffers(&self) -> bool {

src/vmm/src/devices/virtio/block/virtio/device.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,9 @@ impl VirtioDevice for VirtioBlock {
580580

581581
fn force_userspace_bounce_buffers(&mut self) {
582582
match self.disk.file_engine {
583-
FileEngine::Async(_) => panic!("No idea how this is supposed to work for io_uring"),
583+
FileEngine::Async(_) => {
584+
panic!("async engine is incompatible with userspace bounce buffers")
585+
}
584586
FileEngine::Sync(ref mut engine) => engine.start_bouncing(),
585587
}
586588
}

0 commit comments

Comments
 (0)