From 1eac37bd5fd202b09add2616f554e826b595621d Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 28 Nov 2022 14:44:34 +0100 Subject: [PATCH] pci: msi: Move MsiConfig to the new restore design Signed-off-by: Sebastien Boeuf --- pci/src/msi.rs | 51 ++++++++++++++++++++++++++++++++++++++++--------- pci/src/vfio.rs | 2 +- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/pci/src/msi.rs b/pci/src/msi.rs index 5a6b07b51..625842014 100644 --- a/pci/src/msi.rs +++ b/pci/src/msi.rs @@ -39,13 +39,15 @@ pub fn msi_num_enabled_vectors(msg_ctl: u16) -> usize { } #[derive(Error, Debug)] -enum Error { +pub enum Error { #[error("Failed enabling the interrupt route: {0}")] EnableInterruptRoute(io::Error), #[error("Failed updating the interrupt route: {0}")] UpdateInterruptRoute(io::Error), } +pub const MSI_CONFIG_ID: &str = "msi_config"; + #[derive(Clone, Copy, Default, Versionize)] pub struct MsiCap { // Message Control Register @@ -172,7 +174,7 @@ impl MsiCap { } #[derive(Versionize)] -struct MsiConfigState { +pub struct MsiConfigState { cap: MsiCap, } @@ -184,16 +186,47 @@ pub struct MsiConfig { } impl MsiConfig { - pub fn new(msg_ctl: u16, interrupt_source_group: Arc) -> Self { - let cap = MsiCap { - msg_ctl, - ..Default::default() + pub fn new( + msg_ctl: u16, + interrupt_source_group: Arc, + state: Option, + ) -> Result { + let cap = if let Some(state) = state { + if state.cap.enabled() { + for idx in 0..state.cap.num_enabled_vectors() { + let config = MsiIrqSourceConfig { + high_addr: state.cap.msg_addr_hi, + low_addr: state.cap.msg_addr_lo, + data: state.cap.msg_data as u32, + devid: 0, + }; + + interrupt_source_group + .update( + idx as InterruptIndex, + InterruptSourceConfig::MsiIrq(config), + state.cap.vector_masked(idx), + ) + .map_err(Error::UpdateInterruptRoute)?; + } + + interrupt_source_group + .enable() + .map_err(Error::EnableInterruptRoute)?; + } + + state.cap + } else { + MsiCap { + msg_ctl, + ..Default::default() + } }; - MsiConfig { + Ok(MsiConfig { cap, interrupt_source_group, - } + }) } fn state(&self) -> MsiConfigState { @@ -281,7 +314,7 @@ impl Pausable for MsiConfig {} impl Snapshottable for MsiConfig { fn id(&self) -> String { - String::from("msi_config") + String::from(MSI_CONFIG_ID) } fn snapshot(&mut self) -> std::result::Result { diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index 2b6a3cb3f..7db98fdc1 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -735,7 +735,7 @@ impl VfioCommon { }) .unwrap(); - let msi_config = MsiConfig::new(msg_ctl, interrupt_source_group.clone()); + let msi_config = MsiConfig::new(msg_ctl, interrupt_source_group.clone(), None).unwrap(); self.interrupt.msi = Some(VfioMsi { cfg: msi_config,