virtio-devices: switch driver_status to Arc<AtomicU8>

Signed-off-by: Peter Oskolkov <posk@google.com>
This commit is contained in:
Peter Oskolkov
2026-03-12 09:51:50 -07:00
committed by Bo Chen
parent f77c6ef78b
commit 21bd3ae916
2 changed files with 13 additions and 11 deletions

View File

@@ -6,7 +6,7 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::sync::atomic::{AtomicU16, Ordering};
use std::sync::atomic::{AtomicU8, AtomicU16, Ordering};
use std::sync::{Arc, Mutex};
use byteorder::{ByteOrder, LittleEndian};
@@ -125,7 +125,7 @@ pub fn get_vring_size(t: VringType, queue_size: u16) -> u64 {
/// le64 queue_used; // 0x30 // read-write
pub struct VirtioPciCommonConfig {
pub access_platform: Option<Arc<dyn AccessPlatform>>,
pub driver_status: u8,
pub driver_status: Arc<AtomicU8>,
pub config_generation: u8,
pub device_feature_select: u32,
pub driver_feature_select: u32,
@@ -141,7 +141,7 @@ impl VirtioPciCommonConfig {
) -> Self {
VirtioPciCommonConfig {
access_platform,
driver_status: state.driver_status,
driver_status: Arc::new(AtomicU8::new(state.driver_status)),
config_generation: state.config_generation,
device_feature_select: state.device_feature_select,
driver_feature_select: state.driver_feature_select,
@@ -153,7 +153,7 @@ impl VirtioPciCommonConfig {
fn state(&self) -> VirtioPciCommonConfigState {
VirtioPciCommonConfigState {
driver_status: self.driver_status,
driver_status: self.driver_status.load(Ordering::Acquire),
config_generation: self.config_generation,
device_feature_select: self.device_feature_select,
driver_feature_select: self.driver_feature_select,
@@ -223,7 +223,7 @@ impl VirtioPciCommonConfig {
debug!("read_common_config_byte: offset 0x{offset:x}");
// The driver is only allowed to do aligned, properly sized access.
match offset {
0x14 => self.driver_status,
0x14 => self.driver_status.load(Ordering::Acquire),
0x15 => self.config_generation,
_ => {
warn!("invalid virtio config byte read: 0x{offset:x}");
@@ -235,7 +235,7 @@ impl VirtioPciCommonConfig {
fn write_common_config_byte(&mut self, offset: u64, value: u8) {
debug!("write_common_config_byte: offset 0x{offset:x}");
match offset {
0x14 => self.driver_status = value,
0x14 => self.driver_status.store(value, Ordering::Release),
_ => {
warn!("invalid virtio config byte write: 0x{offset:x}");
}
@@ -437,7 +437,7 @@ mod unit_tests {
fn write_base_regs() {
let mut regs = VirtioPciCommonConfig {
access_platform: None,
driver_status: 0xaa,
driver_status: Arc::new(AtomicU8::new(0xaa)),
config_generation: 0x55,
device_feature_select: 0x0,
driver_feature_select: 0x0,

View File

@@ -660,13 +660,13 @@ impl VirtioPciDevice {
fn is_driver_ready(&self) -> bool {
let ready_bits =
(DEVICE_ACKNOWLEDGE | DEVICE_DRIVER | DEVICE_DRIVER_OK | DEVICE_FEATURES_OK) as u8;
self.common_config.driver_status == ready_bits
&& self.common_config.driver_status & DEVICE_FAILED as u8 == 0
let driver_status = self.common_config.driver_status.load(Ordering::SeqCst);
driver_status == ready_bits && (driver_status & DEVICE_FAILED as u8) == 0
}
/// Determines if the driver has requested the device (re)init / reset itself
fn is_driver_init(&self) -> bool {
self.common_config.driver_status == DEVICE_INIT as u8
self.common_config.driver_status.load(Ordering::SeqCst) == DEVICE_INIT as u8
}
pub fn config_bar_addr(&self) -> u64 {
@@ -1238,7 +1238,9 @@ impl PciDevice for VirtioPciDevice {
self.common_config.queue_select = 0;
} else {
error!("Attempt to reset device when not implemented in underlying device");
self.common_config.driver_status = crate::DEVICE_FAILED as u8;
self.common_config
.driver_status
.store(crate::DEVICE_FAILED as u8, Ordering::SeqCst);
}
}