From fcc55507ea69fc50e9eda73fe3da9e7b2a2a40d6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:07:05 +0100 Subject: [PATCH] Move the notify_multiplier field into a separate PciCapabilityNotify type It only exists for VIRTIO_PCI_CAP_NOTIFY_CFG and could conflict with fields of other capability types. --- virtio-core/src/probe.rs | 11 +++++++---- virtio-core/src/spec/transport_pci.rs | 28 ++++++++++++++++----------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/virtio-core/src/probe.rs b/virtio-core/src/probe.rs index 1509187450..2a258bda28 100644 --- a/virtio-core/src/probe.rs +++ b/virtio-core/src/probe.rs @@ -1,9 +1,9 @@ - -use std::ptr::NonNull; use std::fs::File; +use std::ptr::NonNull; use std::sync::Arc; + +use pcid_interface::msi::{MsixCapability, MsixTableEntry}; use pcid_interface::*; -use pcid_interface::msi::{self, MsixTableEntry, MsixCapability}; use crate::spec::*; use crate::transport::{Error, StandardTransport, Transport}; @@ -131,7 +131,10 @@ pub fn probe_device<'a>(pcid_handle: &mut PcidServerHandle) -> Result // SAFETY: The capability type is `Notify`, so its safe to access // the `notify_multiplier` field. - let multiplier = unsafe { capability.notify_multiplier() }; + let multiplier = unsafe { + (&*(capability as *const PciCapability as *const PciCapabilityNotify)) + .notify_off_multiplier() + }; notify_addr = Some((address, multiplier)); } diff --git a/virtio-core/src/spec/transport_pci.rs b/virtio-core/src/spec/transport_pci.rs index a27fcd6df6..cadfaad2de 100644 --- a/virtio-core/src/spec/transport_pci.rs +++ b/virtio-core/src/spec/transport_pci.rs @@ -41,13 +41,11 @@ pub struct PciCapability { pub offset: u32, /// Length of the structure, in bytes. pub length: u32, - // FIXME move out of PciCapability type - notify_multiplier: u32, } // The size of `PciCapability` is 13 bytes since the generic // PCI fields are *not* included. -const_assert_eq!(core::mem::size_of::(), 17); +const_assert_eq!(core::mem::size_of::(), 13); #[derive(Debug, Copy, Clone)] #[repr(u8)] @@ -70,14 +68,6 @@ pub enum CfgType { const_assert_eq!(core::mem::size_of::(), 1); -impl PciCapability { - /// ## Safety - /// Undefined if accessed from a capability type other than [`CfgType::Notify`]. - pub unsafe fn notify_multiplier(&self) -> u32 { - self.notify_multiplier - } -} - #[derive(Debug)] #[repr(C)] pub struct CommonCfg { @@ -164,5 +154,21 @@ pub struct CommonCfg { const_assert_eq!(core::mem::size_of::(), 64); +#[derive(Debug, Copy, Clone)] +#[repr(C, packed)] +pub struct PciCapabilityNotify { + pub cap: PciCapability, + /// Multiplier for queue_notify_off. + notify_off_multiplier: u32, +} + +impl PciCapabilityNotify { + pub fn notify_off_multiplier(&self) -> u32 { + self.notify_off_multiplier + } +} + +const_assert_eq!(core::mem::size_of::(), 17); + /// Vector value used to disable MSI for queue pub const VIRTIO_MSI_NO_VECTOR: u16 = 0xffff;