virtio-devices: balloon: Use checked descriptor iterator

Replace manual translate_gva calls with checked_iter in both the
inflate/deflate and reporting queue handlers.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-05-13 16:23:04 +02:00
committed by Rob Bradford
parent 33e3f4e29e
commit 39264eea50

View File

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