From a49584151511826169a76086f649725a1a7f84fb Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Fri, 1 May 2026 03:47:27 -0700 Subject: [PATCH] virtio-devices: iommu: log per-request errors IommuEpollHandler::request_queue() can fail because the guest put in a bad request or because of a fatal error. Handle those cases differently, letting the guest continue, but see the error if it can. This makes debugging from the guest easier as one mistake doesn't cause a VM reset if it's avoidable. Signed-off-by: Dylan Reid --- virtio-devices/src/iommu.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 3d2f1cf28..55c73b1ae 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -11,7 +11,7 @@ use std::{io, result}; use anyhow::anyhow; use event_monitor::event; -use log::{debug, error, info}; +use log::{debug, error, info, warn}; use seccompiler::SeccompAction; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -860,16 +860,25 @@ impl IommuEpollHandler { let mut used_descs = false; while let Some(mut desc_chain) = self.request_queue.pop_descriptor_chain(self.mem.memory()) { - let len = Request::parse( + // If the request fails to parse, that's the guest's error. Notify + // it with a 0 length response in the used queue. + let head_index = desc_chain.head_index(); + let len = match Request::parse( &mut desc_chain, &self.mapping, &self.ext_mapping.lock().unwrap(), self.msi_iova_space, self.input_range, - )?; + ) { + Ok(len) => len as u32, + Err(e) => { + warn!("Failed to parse virtio-iommu request: {e:?}"); + 0 + } + }; self.request_queue - .add_used(desc_chain.memory(), desc_chain.head_index(), len as u32) + .add_used(desc_chain.memory(), head_index, len) .map_err(Error::QueueAddUsed)?; used_descs = true;