From 4f583b1cfb113bf0acfde69ee4e94b7eda784c81 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:47:08 +0200 Subject: [PATCH] Store decoded MSI info instead of full capability in PciFeatureInfo --- pcid/src/driver_handler.rs | 6 +++++- pcid/src/driver_interface/mod.rs | 2 +- pcid/src/pci/msi.rs | 7 +++++++ storage/nvmed/src/main.rs | 7 +++++-- storage/nvmed/src/nvme/mod.rs | 12 ++++++------ 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/pcid/src/driver_handler.rs b/pcid/src/driver_handler.rs index 3358a501fc..77f1729829 100644 --- a/pcid/src/driver_handler.rs +++ b/pcid/src/driver_handler.rs @@ -199,7 +199,11 @@ impl DriverHandler { .iter() .find_map(|capability| capability.as_msi()) { - PciFeatureInfo::Msi(*info) + PciFeatureInfo::Msi(msi::MsiInfo { + log2_multiple_message_capable: info.multi_message_capable(), + is_64bit: info.has_64_bit_addr(), + has_per_vector_masking: info.is_pvt_capable(), + }) } else { return PcidClientResponse::Error( PcidServerResponseError::NonexistentFeature(feature), diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 483da35602..4ba2eb789e 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -132,7 +132,7 @@ impl PciFeature { } #[derive(Debug, Serialize, Deserialize)] pub enum PciFeatureInfo { - Msi(msi::MsiCapability), + Msi(msi::MsiInfo), MsiX(msi::MsixInfo), } diff --git a/pcid/src/pci/msi.rs b/pcid/src/pci/msi.rs index 179ae638f2..dab62c190f 100644 --- a/pcid/src/pci/msi.rs +++ b/pcid/src/pci/msi.rs @@ -23,6 +23,13 @@ impl MsiAddrAndData { } } +#[derive(Debug, Serialize, Deserialize)] +pub struct MsiInfo { + pub log2_multiple_message_capable: u8, + pub is_64bit: bool, + pub has_per_vector_masking: bool, +} + impl MsiCapability { pub const MC_PVT_CAPABLE_BIT: u16 = 1 << 8; pub const MC_64_BIT_ADDR_BIT: u16 = 1 << 7; diff --git a/storage/nvmed/src/main.rs b/storage/nvmed/src/main.rs index 501c1b74e8..4aee22d621 100644 --- a/storage/nvmed/src/main.rs +++ b/storage/nvmed/src/main.rs @@ -149,7 +149,7 @@ fn get_int_method( Ok((interrupt_method, interrupt_sources)) } else if has_msi { // Message signaled interrupts. - let capability_struct = match pcid_handle.feature_info(PciFeature::Msi).unwrap() { + let msi_info = match pcid_handle.feature_info(PciFeature::Msi).unwrap() { PciFeatureInfo::Msi(msi) => msi, _ => unreachable!(), }; @@ -171,7 +171,10 @@ fn get_int_method( (0, irq_handle) }; - let interrupt_method = InterruptMethod::Msi(capability_struct); + let interrupt_method = InterruptMethod::Msi { + msi_info, + log2_multiple_message_enabled: 0, + }; let interrupt_sources = InterruptSources::Msi(std::iter::once((msi_vector_number, irq_handle)).collect()); diff --git a/storage/nvmed/src/nvme/mod.rs b/storage/nvmed/src/nvme/mod.rs index 7781f477bc..993736b890 100644 --- a/storage/nvmed/src/nvme/mod.rs +++ b/storage/nvmed/src/nvme/mod.rs @@ -22,7 +22,7 @@ pub mod queues; use self::cq_reactor::NotifReq; pub use self::queues::{NvmeCmd, NvmeCmdQueue, NvmeComp, NvmeCompQueue}; -use pcid_interface::msi::{MsiCapability, MsixInfo, MsixTableEntry}; +use pcid_interface::msi::{MsiInfo, MsixInfo, MsixTableEntry}; use pcid_interface::PcidServerHandle; #[cfg(target_arch = "aarch64")] @@ -91,7 +91,7 @@ pub enum InterruptMethod { /// Traditional level-triggered, INTx# interrupt pins. Intx, /// Message signaled interrupts - Msi(MsiCapability), + Msi { msi_info: MsiInfo, log2_multiple_message_enabled: u8 }, /// Extended message signaled interrupts MsiX(MappedMsixRegs), } @@ -104,7 +104,7 @@ impl InterruptMethod { } } fn is_msi(&self) -> bool { - if let Self::Msi(_) = self { + if let Self::Msi { .. } = self { true } else { false @@ -289,7 +289,7 @@ impl Nvme { } match self.interrupt_method.get_mut().unwrap() { - &mut InterruptMethod::Intx | InterruptMethod::Msi(_) => { + &mut InterruptMethod::Intx | InterruptMethod::Msi { .. } => { self.regs.get_mut().unwrap().intms.write(0xFFFF_FFFF); self.regs.get_mut().unwrap().intmc.write(0x0000_0001); } @@ -371,13 +371,13 @@ impl Nvme { self.regs.write().unwrap().intmc.write(0x0000_0001); } } - &mut InterruptMethod::Msi(ref mut cap) => { + &mut InterruptMethod::Msi { msi_info: _, log2_multiple_message_enabled: log2_enabled_messages } => { let mut to_mask = 0x0000_0000; let mut to_clear = 0x0000_0000; for (vector, mask) in vectors { assert!( - vector < (1 << cap.multi_message_enable()), + vector < (1 << log2_enabled_messages), "nvmed: internal error: MSI vector out of range" ); let vector = vector as u8;