From 490e338e16453f15b8be247d80ef0b01c1ce2e37 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Fri, 10 Apr 2026 11:49:05 -0700 Subject: [PATCH] pci: synchronize VfioMsix::cap and VfioMsix::bar Currently, when snapshoting a running VFIO device with MSI-X enabled, we get a snapshot where `msix_config.state.enabled` is not consistent with `msix_state.cap.msg_ctl`, ```jsonc { "snapshots": { "vfio_common": { "snapshots": { "msix_config": { "snapshots": {}, "state": { "enabled": true // ... } }, // .. }, "state": { "msix_state": { "cap": { "msg_ctl": 3, "table": 1, "pba": 2049 }, // ... } // ... } } }, // ... } ``` The root cause is, after a `MsixCap` is parsed from the device PCI config space and propagated to a corresponding `MsixConfig`, `MsixCap::msg_ctl` is never get updated at runtime, only `MsixConfig::msg_ctl` is updated. This commit makes `VfioMsix::update` update both `VfioMsix::bar` (of type `MsixConfig`) and `VfioMsix::cap` (of type `MsixCap`). Signed-off-by: Changyuan Lyu --- pci/src/vfio.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index 7dc6f9c3b..51e3aa927 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -157,11 +157,14 @@ impl VfioMsix { // Update "Message Control" word if offset == 2 && data.len() == 2 { - self.bar.set_msg_ctl(LittleEndian::read_u16(data)); + let data = LittleEndian::read_u16(data); + self.bar.set_msg_ctl(data); + self.cap.set_msg_ctl(data); } else if offset == 0 && data.len() == 4 { // Some guests update MSI-X control through the dword config write path. - self.bar - .set_msg_ctl((LittleEndian::read_u32(data) >> 16) as u16); + let data = (LittleEndian::read_u32(data) >> 16) as u16; + self.bar.set_msg_ctl(data); + self.cap.set_msg_ctl(data); } let new_enabled = self.bar.enabled();