diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index a1e624491..69d80cc6b 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -34,7 +34,8 @@ use vm_memory::{ GuestMemoryError, GuestMemoryRegion, }; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; -use vm_virtio::{AccessPlatform, Translatable}; +use vm_virtio::AccessPlatform; +use vm_virtio::checked_descriptor::DescriptorChainExt; use vmm_sys_util::eventfd::EventFd; use crate::seccomp_filters::Thread; @@ -276,7 +277,14 @@ impl BalloonEpollHandler { { let data_chunk_size = size_of::(); - while let Some(desc) = desc_chain.next() { + let results: Vec<_> = desc_chain + .checked_iter(self.access_platform.as_deref()) + .collect(); + for result in results { + let desc = match result { + Ok(d) => d, + Err(_) => break, + }; if desc.is_write_only() { warn!("Skipping device-writable descriptor on inflate/deflate queue"); continue; @@ -298,19 +306,10 @@ impl BalloonEpollHandler { let mut offset = 0u64; while offset < desc.len() as u64 { - let Some(base) = desc.addr().checked_add(offset) else { + let Some(addr) = desc.addr().checked_add(offset) else { warn!("Address overflow in balloon descriptor"); break; }; - let addr = match base - .translate_gva(self.access_platform.as_deref(), data_chunk_size) - { - Ok(a) => a, - Err(e) => { - warn!("Failed to translate descriptor address: {e}"); - break; - } - }; let pfn: u32 = match desc_chain.memory().read_obj(addr) { Ok(v) => v, Err(e) => { @@ -368,21 +367,20 @@ impl BalloonEpollHandler { self.queues[queue_index].pop_descriptor_chain(self.mem.memory()) { let mut descs_len = 0; - while let Some(desc) = desc_chain.next() { - descs_len += desc.len(); - let addr = match desc - .addr() - .translate_gva(self.access_platform.as_deref(), desc.len() as usize) - { - Ok(a) => a, - Err(e) => { - warn!("Failed to translate reporting descriptor address: {e}"); - continue; - } + let results: Vec<_> = desc_chain + .checked_iter(self.access_platform.as_deref()) + .collect(); + for result in results { + let desc = match result { + Ok(d) => d, + Err(_) => break, }; - if let Err(e) = - Self::release_memory_range(desc_chain.memory(), addr, desc.len() as usize) - { + descs_len += desc.len(); + if let Err(e) = Self::release_memory_range( + desc_chain.memory(), + desc.addr(), + desc.len() as usize, + ) { warn!("Failed to release reported memory range: {e}"); } }