diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index 3abebbee92..414f6e3d86 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -1148,6 +1148,63 @@ impl ToQemuParams for Rtc { } } +#[derive(Debug)] +struct ObjectRngRandom { + // id is the device ID + id: String, + + // filename is the entropy source on the host + filename: String, +} + +impl ObjectRngRandom { + fn new() -> ObjectRngRandom { + ObjectRngRandom { + id: "rng0".to_owned(), + filename: "/dev/urandom".to_owned(), + } + } +} + +#[async_trait] +impl ToQemuParams for ObjectRngRandom { + async fn qemu_params(&self) -> Result> { + let mut object_params = Vec::new(); + + object_params.push("rng-random".to_owned()); + object_params.push(format!("id={}", self.id)); + object_params.push(format!("filename={}", self.filename)); + + Ok(vec!["-object".to_owned(), object_params.join(",")]) + } +} + +#[derive(Debug)] +struct DeviceRng { + // transport is the virtio transport for this device. + transport: String, +} + +impl DeviceRng { + fn new() -> DeviceRng { + DeviceRng { + transport: "virtio-rng-pci".to_owned(), + } + } +} + +#[async_trait] +impl ToQemuParams for DeviceRng { + async fn qemu_params(&self) -> Result> { + let mut device_params = Vec::new(); + + device_params.push(self.transport.clone()); + device_params.push(format!("rng={}", "rng0".to_owned())); + + Ok(vec!["-device".to_owned(), device_params.join(",")]) + } +} + #[derive(Debug)] struct DeviceIntelIommu { intremap: bool, @@ -1238,6 +1295,10 @@ impl<'a> QemuCmdLine<'a> { qemu_cmd_line.add_rtc(); + if qemu_cmd_line.bus_type() != VirtioBusType::Ccw { + qemu_cmd_line.add_rng(); + } + Ok(qemu_cmd_line) } @@ -1246,6 +1307,14 @@ impl<'a> QemuCmdLine<'a> { self.devices.push(Box::new(rtc)); } + fn add_rng(&mut self) { + let rng_object = ObjectRngRandom::new(); + let rng_device = DeviceRng::new(); + + self.devices.push(Box::new(rng_object)); + self.devices.push(Box::new(rng_device)); + } + fn bus_type(&self) -> VirtioBusType { if self.config.machine_info.machine_type.contains("-ccw-") { VirtioBusType::Ccw