In preparation to support VIRTIO_F_DMB, read the shared memory id of the Device Memory Buffer. A device that negotiates VIRTIO_F_DMB reports it in a read-only le16 at the end of the common configuration structure, and it names the VIRTIO_PCI_CAP_SHARED_MEMORY_CFG capability that virtio_pci_find_shm_cap() has to find to map the region.
Add the dmb_shm_id field, VIRTIO_PCI_COMMON_DMB_SHM_ID for the offset check_offsets() asserts it against, and vp_modern_get_dmb_shm_id() to read the register. vp_modern_probe() capped the common cfg mapping at the end of admin_queue_num, exactly where the new field starts, so extend it to the end of dmb_shm_id. vp_modern_map_capability() takes that as an upper bound, so a device with a shorter common cfg maps what it has and mdev->common_len records how much. The offset and VIRTIO_F_DMB are provisional until the virtio Technical Committee allocates them. Link: https://lore.kernel.org/virtio-comment/[email protected]/ Assisted-by: Kiro:claude-opus-5 checkpatch sparse Signed-off-by: Alexander Graf <[email protected]> --- drivers/virtio/virtio_pci_modern_dev.c | 23 ++++++++++++++++++++++- include/linux/virtio_pci_modern.h | 1 + include/uapi/linux/virtio_pci.h | 10 ++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c index 413a8c353463..7fbfcb305a62 100644 --- a/drivers/virtio/virtio_pci_modern_dev.c +++ b/drivers/virtio/virtio_pci_modern_dev.c @@ -211,6 +211,8 @@ static inline void check_offsets(void) offsetof(struct virtio_pci_modern_common_cfg, admin_queue_index)); BUILD_BUG_ON(VIRTIO_PCI_COMMON_ADM_Q_NUM != offsetof(struct virtio_pci_modern_common_cfg, admin_queue_num)); + BUILD_BUG_ON(VIRTIO_PCI_COMMON_DMB_SHM_ID != + offsetof(struct virtio_pci_modern_common_cfg, dmb_shm_id)); } /* @@ -300,7 +302,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) mdev->common = vp_modern_map_capability(mdev, common, sizeof(struct virtio_pci_common_cfg), 4, 0, offsetofend(struct virtio_pci_modern_common_cfg, - admin_queue_num), + dmb_shm_id), &mdev->common_len, NULL); if (!mdev->common) goto err_map_common; @@ -752,6 +754,25 @@ u16 vp_modern_avq_index(struct virtio_pci_modern_device *mdev) } EXPORT_SYMBOL_GPL(vp_modern_avq_index); +/* + * vp_modern_get_dmb_shm_id - read the Device Memory Buffer shared memory id + * @mdev: the modern virtio-pci device + * + * The value identifies the VIRTIO_PCI_CAP_SHARED_MEMORY_CFG capability that + * describes the Device Memory Buffer region. Only valid once VIRTIO_F_DMB + * has been negotiated. + * + * Returns the shared memory id. + */ +u16 vp_modern_get_dmb_shm_id(struct virtio_pci_modern_device *mdev) +{ + struct virtio_pci_modern_common_cfg __iomem *cfg; + + cfg = (struct virtio_pci_modern_common_cfg __iomem *)mdev->common; + return vp_ioread16(&cfg->dmb_shm_id); +} +EXPORT_SYMBOL_GPL(vp_modern_get_dmb_shm_id); + MODULE_VERSION("0.1"); MODULE_DESCRIPTION("Modern Virtio PCI Device"); MODULE_AUTHOR("Jason Wang <[email protected]>"); diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h index 9a3f2fc53bd6..c396f8e6055b 100644 --- a/include/linux/virtio_pci_modern.h +++ b/include/linux/virtio_pci_modern.h @@ -162,4 +162,5 @@ int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); u16 vp_modern_avq_num(struct virtio_pci_modern_device *mdev); u16 vp_modern_avq_index(struct virtio_pci_modern_device *mdev); +u16 vp_modern_get_dmb_shm_id(struct virtio_pci_modern_device *mdev); #endif diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h index e732e3456e27..052a1047f48f 100644 --- a/include/uapi/linux/virtio_pci.h +++ b/include/uapi/linux/virtio_pci.h @@ -193,6 +193,15 @@ struct virtio_pci_modern_common_cfg { __le16 admin_queue_index; /* read-only */ __le16 admin_queue_num; /* read-only */ + + /* + * Reports the shmid of the Device Memory Buffer region. The feature + * is a specification proposal before the virtio Technical Committee, + * and both this offset and the VIRTIO_F_DMB feature bit are + * provisional: neither has been allocated, so a device must not rely + * on either until they have been. + */ + __le16 dmb_shm_id; /* read-only */ }; /* Fields in VIRTIO_PCI_CAP_PCI_CFG: */ @@ -235,6 +244,7 @@ struct virtio_pci_cfg_cap { #define VIRTIO_PCI_COMMON_Q_RESET 58 #define VIRTIO_PCI_COMMON_ADM_Q_IDX 60 #define VIRTIO_PCI_COMMON_ADM_Q_NUM 62 +#define VIRTIO_PCI_COMMON_DMB_SHM_ID 64 #endif /* VIRTIO_PCI_NO_MODERN */

