From e923f9a6780122efed95fb18ef398122fff9a3b9 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 9 May 2026 23:38:53 +0200 Subject: [PATCH] virtio-devices: Make config_generation an Arc Convert the u8 field to Arc so the interrupt path can mutate it without holding the common config mutex. Reads at offset 0x15 use Acquire ordering. State serialization preserves the value. Update the three unit tests that construct VirtioPciCommonConfig directly. Signed-off-by: Anatol Belski --- .../src/transport/pci_common_config.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/virtio-devices/src/transport/pci_common_config.rs b/virtio-devices/src/transport/pci_common_config.rs index 1ca86a220..8098ba0eb 100644 --- a/virtio-devices/src/transport/pci_common_config.rs +++ b/virtio-devices/src/transport/pci_common_config.rs @@ -126,7 +126,7 @@ pub fn get_vring_size(t: VringType, queue_size: u16) -> u64 { pub struct VirtioPciCommonConfig { pub device: Arc>, pub driver_status: Arc, - pub config_generation: u8, + pub config_generation: Arc, pub device_feature_select: u32, pub driver_feature_select: u32, pub queue_select: u16, @@ -139,7 +139,7 @@ impl VirtioPciCommonConfig { VirtioPciCommonConfig { device, driver_status: Arc::new(AtomicU8::new(state.driver_status)), - config_generation: state.config_generation, + config_generation: Arc::new(AtomicU8::new(state.config_generation)), device_feature_select: state.device_feature_select, driver_feature_select: state.driver_feature_select, queue_select: state.queue_select, @@ -151,7 +151,7 @@ impl VirtioPciCommonConfig { fn state(&self) -> VirtioPciCommonConfigState { VirtioPciCommonConfigState { driver_status: self.driver_status.load(Ordering::Acquire), - config_generation: self.config_generation, + config_generation: self.config_generation.load(Ordering::Acquire), device_feature_select: self.device_feature_select, driver_feature_select: self.driver_feature_select, queue_select: self.queue_select, @@ -216,7 +216,7 @@ impl VirtioPciCommonConfig { // The driver is only allowed to do aligned, properly sized access. match offset { 0x14 => self.driver_status.load(Ordering::Acquire), - 0x15 => self.config_generation, + 0x15 => self.config_generation.load(Ordering::Acquire), _ => { warn!("invalid virtio config byte read: 0x{offset:x}"); 0 @@ -461,7 +461,7 @@ mod unit_tests { let mut regs = VirtioPciCommonConfig { device: dev.clone(), driver_status: Arc::new(AtomicU8::new(0xaa)), - config_generation: 0x55, + config_generation: Arc::new(AtomicU8::new(0x55)), device_feature_select: 0x0, driver_feature_select: 0x0, queue_select: 0xff, @@ -513,7 +513,7 @@ mod unit_tests { let mut regs = VirtioPciCommonConfig { device: dev.clone(), driver_status: Arc::new(AtomicU8::new(0)), - config_generation: 0, + config_generation: Arc::new(AtomicU8::new(0)), device_feature_select: 0, driver_feature_select: 0, queue_select: 0, @@ -541,7 +541,7 @@ mod unit_tests { let mut regs = VirtioPciCommonConfig { device: dev, driver_status: Arc::new(AtomicU8::new(0x55)), - config_generation: 0xab, + config_generation: Arc::new(AtomicU8::new(0xab)), device_feature_select: 1, driver_feature_select: 1, queue_select: 7, @@ -552,7 +552,7 @@ mod unit_tests { regs.reset(); assert_eq!(regs.driver_status.load(Ordering::Acquire), 0); - assert_eq!(regs.config_generation, 0xab); // unchanged across reset + assert_eq!(regs.config_generation.load(Ordering::Acquire), 0xab); // unchanged across reset assert_eq!(regs.device_feature_select, 0); assert_eq!(regs.driver_feature_select, 0); assert_eq!(regs.queue_select, 0);