diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 64211024362..246911df480 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -67,7 +67,7 @@ use crate::vmm_config::instance_info::InstanceInfo; use crate::vmm_config::machine_config::MachineConfigError; use crate::vmm_config::snapshot::{LoadSnapshotParams, MemBackendType}; use crate::vstate::kvm::Kvm; -use crate::vstate::memory::{MaybeBounce, create_memfd}; +use crate::vstate::memory::{MaybeBounce, MemoryError, create_memfd}; use crate::vstate::vcpu::{Vcpu, VcpuError}; use crate::vstate::vm::{GUEST_MEMFD_FLAG_NO_DIRECT_MAP, GUEST_MEMFD_FLAG_SUPPORT_SHARED, Vm}; use crate::{EventManager, Vmm, VmmError, device_manager}; @@ -482,10 +482,10 @@ pub enum BuildMicrovmFromSnapshotError { /// Failed to load guest memory: {0} GuestMemory(#[from] BuildMicrovmFromSnapshotErrorGuestMemoryError), /// Userfault bitmap memfd error: {0} - UserfaultBitmapMemfd(#[from] crate::vstate::memory::MemoryError), + UserfaultBitmapMemfd(#[from] MemoryError), } -fn memfd_to_slice(memfd: &Option) -> Option<&mut [u8]> { +fn memfd_to_slice(memfd: &Option) -> Result, MemoryError> { if let Some(bitmap_file) = memfd { let len = u64_to_usize( bitmap_file @@ -507,16 +507,15 @@ fn memfd_to_slice(memfd: &Option) -> Option<&mut [u8]> { }; if bitmap_addr == libc::MAP_FAILED { - panic!( - "Failed to mmap userfault bitmap file: {}", - std::io::Error::last_os_error() - ); + return Err(MemoryError::Mmap(std::io::Error::last_os_error())); } // SAFETY: `bitmap_addr` is a valid memory address returned by `mmap`. - Some(unsafe { std::slice::from_raw_parts_mut(bitmap_addr.cast(), len) }) + Ok(Some(unsafe { + std::slice::from_raw_parts_mut(bitmap_addr.cast(), len) + })) } else { - None + Ok(None) } } @@ -616,7 +615,7 @@ pub fn build_microvm_from_snapshot( } }; - let mut userfault_bitmap = memfd_to_slice(&userfault_bitmap_memfd); + let mut userfault_bitmap = memfd_to_slice(&userfault_bitmap_memfd)?; if let Some(ref mut slice) = userfault_bitmap { // Set all bits so a fault on any page will cause a VM exit slice.fill(0xffu8); diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index eda747bc3a3..097747cbd48 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -819,21 +819,11 @@ impl Vmm { let fault_request_json = serde_json::to_string(&fault_request).expect("Failed to serialize fault request"); - let written = self - .uffd_socket + self.uffd_socket .as_ref() .expect("Uffd socket is not set") - .write(fault_request_json.as_bytes()) + .write_all(fault_request_json.as_bytes()) .expect("Failed to write to uffd socket"); - - if written != fault_request_json.len() { - panic!( - "Failed to write the entire fault request to the uffd socket: expected {}, \ - written {}", - fault_request_json.len(), - written - ); - } } fn active_event_in_uffd_socket(&self, source: RawFd, event_set: EventSet) -> bool { @@ -862,6 +852,7 @@ impl Vmm { break; } } + Err(e) if e.kind() == io::ErrorKind::Interrupted => continue, Err(e) => panic!("Read error: {}", e), } } @@ -875,11 +866,7 @@ impl Vmm { match result { Ok(fault_reply) => { let vcpu = fault_reply.vcpu.expect("vCPU must be set"); - - self.vcpus_handles - .get(vcpu as usize) - .expect("Invalid vcpu index") - .send_userfault_resolved(); + self.vcpus_handles[vcpu as usize].send_userfault_resolved(); total_consumed = parser.byte_offset(); } @@ -1037,7 +1024,7 @@ impl MutEventSubscriber for Vmm { if let Some(uffd_socket) = self.uffd_socket.as_ref() { if let Err(err) = ops.add(Events::new(uffd_socket, EventSet::IN)) { - panic!("Failed to register UFFD socket: {}", err); + error!("Failed to register UFFD socket: {}", err); } } } diff --git a/src/vmm/src/persist.rs b/src/vmm/src/persist.rs index 93c81ad3db7..4c40c7eacde 100644 --- a/src/vmm/src/persist.rs +++ b/src/vmm/src/persist.rs @@ -609,9 +609,7 @@ fn send_uffd_handshake( let backend_mappings = serde_json::to_string(backend_mappings).unwrap(); let socket = UnixStream::connect(mem_uds_path)?; - socket - .set_nonblocking(true) - .expect("Cannot set non-blocking"); + socket.set_nonblocking(true)?; socket.send_with_fds( &[backend_mappings.as_bytes()], diff --git a/src/vmm/src/vstate/memory.rs b/src/vmm/src/vstate/memory.rs index 0f319562683..77112db802f 100644 --- a/src/vmm/src/vstate/memory.rs +++ b/src/vmm/src/vstate/memory.rs @@ -482,8 +482,9 @@ impl GuestMemoryExtension for GuestMemoryMmap { /// Convert guest physical address to file offset fn gpa_to_offset(&self, gpa: GuestAddress) -> Option { - self.find_region(gpa).map(|r| { - gpa.0 - r.start_addr().0 + r.file_offset().expect("File offset is None").start() + self.find_region(gpa).and_then(|r| { + r.file_offset() + .map(|file_offset| gpa.0 - r.start_addr().0 + file_offset.start()) }) }