virtio-devices: Factor out NEEDS_RESET helpers

Both block and net implement the same DEVICE_NEEDS_RESET bookkeeping
when a corrupted virtqueue request is detected. They set the bit,
trigger a config change interrupt and log a warning. Move that logic
into shared device_needs_reset and mark_device_needs_reset helpers in
lib.rs and update both call sites to use them.

No functional change.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-05-06 10:14:50 +02:00
committed by Rob Bradford
parent 4eb1717fb0
commit 22856fffdd
3 changed files with 50 additions and 40 deletions
+11 -20
View File
@@ -50,7 +50,7 @@ use super::{
};
use crate::seccomp_filters::Thread;
use crate::thread_helper::spawn_virtio_thread;
use crate::{GuestMemoryMmap, VirtioInterrupt};
use crate::{GuestMemoryMmap, VirtioInterrupt, device_needs_reset, mark_device_needs_reset};
const SECTOR_SHIFT: u8 = 9;
pub const SECTOR_SIZE: u64 = 0x01 << SECTOR_SHIFT;
@@ -174,7 +174,7 @@ fn has_feature(features: u64, feature_flag: u64) -> bool {
impl BlockEpollHandler {
fn needs_reset(&self) -> bool {
(self.device_status.load(Ordering::Acquire) & crate::DEVICE_NEEDS_RESET as u8) != 0
device_needs_reset(&self.device_status)
}
fn check_request(
@@ -209,25 +209,16 @@ impl BlockEpollHandler {
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. We cannot just ignore the
// error, as the guest could continue spamming the VMM with bad
// requests, triggering excessive error logging. So we mark
// the device "NEEDS_RESET", effectively stopping all request
// processing (see self.needs_reset() usage) until the guest
// resets and reactivates the device.
warn!(
"Corrupted request detected (virtqueue error: {err:?}). \
Setting device status to 'NEEDS_RESET' and stopping processing queues until reset."
// 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:?}"),
);
self.device_status
.fetch_or(crate::DEVICE_NEEDS_RESET as u8, Ordering::SeqCst);
// Let the guest know that the device status has changed.
if let Err(e) = self.interrupt_cb.trigger(VirtioInterruptType::Config) {
error!("Failed to signal config interrupt: {e:?}");
}
}
fn process_queue_submit(&mut self) -> Result<()> {