From 6669ec1b860afb26c25bbf6482910365ce9e3640 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 7 May 2026 13:01:45 +0200 Subject: [PATCH] virtio-devices: net: Drop per handler NEEDS_RESET bookkeeping spawn_virtio_thread now marks the device as NEEDS_RESET and notifies the guest whenever the worker thread exits with an error, so the per handler needs_reset() gate and the handle_queue_iterator_error() helper in net are redundant. Let virtqueue iterator errors propagate out of the worker thread through DeviceError::NetQueuePair. Drop the unused device_status field and the device_needs_reset and mark_device_needs_reset imports. No functional change for the guest. NEEDS_RESET is still set and the config interrupt is still raised on virtqueue corruption. Signed-off-by: Anatol Belski --- virtio-devices/src/net.rs | 51 ++++++--------------------------------- 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index 56d2161ef..e8d1af1e5 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -42,7 +42,7 @@ use super::{ }; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; -use crate::{GuestMemoryMmap, VirtioInterrupt, device_needs_reset, mark_device_needs_reset}; +use crate::{GuestMemoryMmap, VirtioInterrupt}; /// Control queue // Event available on the control queue. @@ -174,7 +174,6 @@ struct NetEpollHandler { queue_index_base: u16, queue_pair: (Queue, Queue), queue_evt_pair: (EventFd, EventFd), - device_status: Arc, } impl NetEpollHandler { @@ -188,9 +187,6 @@ impl NetEpollHandler { } fn handle_rx_event(&mut self) -> result::Result<(), DeviceError> { - if self.needs_reset() { - return Ok(()); - } let queue_evt = &self.queue_evt_pair.0; if let Err(e) = queue_evt.read() { error!("Failed to get rx queue event: {e:?}"); @@ -219,34 +215,13 @@ impl NetEpollHandler { Ok(()) } - fn handle_queue_iterator_error(&mut self, err: &virtio_queue::Error) { - // The guest submitted a corrupted VirtQ request, and the error - // was logged during queue processing. Ignoring it would let the - // guest keep spamming the VMM with bad requests and trigger - // excessive error logging, so mark the device as NEEDS_RESET to - // stop request processing (see self.needs_reset() usage) until - // the guest resets and reactivates the device. - mark_device_needs_reset( - &self.device_status, - self.interrupt_cb.as_ref(), - format_args!("virtqueue error: {err:?}"), - ); - } - fn process_tx(&mut self) -> result::Result<(), DeviceError> { - if self.needs_reset() { - return Ok(()); - } let res = self .net - .process_tx(&self.mem.memory(), &mut self.queue_pair.1); + .process_tx(&self.mem.memory(), &mut self.queue_pair.1) + .map_err(DeviceError::NetQueuePair)?; - if let Err(net_util::NetQueuePairError::QueueIteratorFailed(err)) = res { - self.handle_queue_iterator_error(&err); - return Ok(()); - } - - if res.map_err(DeviceError::NetQueuePair)? { + if res { self.signal_used_queue(self.queue_index_base + 1)?; debug!("Signalling TX queue"); } else { @@ -270,19 +245,12 @@ impl NetEpollHandler { } fn handle_rx_tap_event(&mut self) -> result::Result<(), DeviceError> { - if self.needs_reset() { - return Ok(()); - } let res = self .net - .process_rx(&self.mem.memory(), &mut self.queue_pair.0); + .process_rx(&self.mem.memory(), &mut self.queue_pair.0) + .map_err(DeviceError::NetQueuePair)?; - if let Err(net_util::NetQueuePairError::QueueIteratorFailed(err)) = res { - self.handle_queue_iterator_error(&err); - return Ok(()); - } - - if res.map_err(DeviceError::NetQueuePair)? { + if res { self.signal_used_queue(self.queue_index_base)?; debug!("Signalling RX queue"); } else { @@ -332,10 +300,6 @@ impl NetEpollHandler { Ok(()) } - - fn needs_reset(&self) -> bool { - device_needs_reset(&self.device_status) - } } impl EpollHelperHandler for NetEpollHandler { @@ -837,7 +801,6 @@ impl VirtioDevice for Net { interrupt_cb: interrupt_cb.clone(), kill_evt, pause_evt, - device_status: self.device_status.clone(), }; let paused = self.common.paused.clone();