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
+28
View File
@@ -11,6 +11,7 @@
//! Implements virtio devices, queues, and transport mechanisms.
use std::io;
use std::sync::atomic::{AtomicU8, Ordering};
use serde::{Deserialize, Serialize};
use thiserror::Error;
@@ -69,6 +70,33 @@ const DEVICE_FEATURES_OK: u32 = 0x08;
const DEVICE_NEEDS_RESET: u32 = 0x40;
const DEVICE_FAILED: u32 = 0x80;
/// Returns true if `device_status` has the `DEVICE_NEEDS_RESET` bit set.
pub(crate) fn device_needs_reset(device_status: &AtomicU8) -> bool {
(device_status.load(Ordering::Acquire) & DEVICE_NEEDS_RESET as u8) != 0
}
/// Marks a virtio device as `NEEDS_RESET` and notifies the guest via a config
/// change interrupt. Used when a guest induced error (corrupted virtqueue,
/// malformed descriptor chain or similar) is detected and the device wants
/// to stop further queue processing without killing the worker thread.
///
/// `context` is included verbatim in the warning log to identify the cause.
pub(crate) fn mark_device_needs_reset(
device_status: &AtomicU8,
interrupt_cb: &dyn self::VirtioInterrupt,
context: std::fmt::Arguments<'_>,
) {
log::warn!(
"Corrupted request detected ({context}). Setting device status to 'NEEDS_RESET' and stopping processing queues until reset."
);
device_status.fetch_or(DEVICE_NEEDS_RESET as u8, Ordering::SeqCst);
if let Err(e) = interrupt_cb.trigger(self::VirtioInterruptType::Config) {
log::error!("Failed to signal config interrupt: {e:?}");
}
}
const VIRTIO_F_RING_INDIRECT_DESC: u32 = 28;
const VIRTIO_F_RING_EVENT_IDX: u32 = 29;
const VIRTIO_F_VERSION_1: u32 = 32;