1f33f5fe2SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 25f4c9760SMichael S. Tsirkin #ifndef _DRIVERS_VIRTIO_VIRTIO_PCI_COMMON_H 35f4c9760SMichael S. Tsirkin #define _DRIVERS_VIRTIO_VIRTIO_PCI_COMMON_H 45f4c9760SMichael S. Tsirkin /* 55f4c9760SMichael S. Tsirkin * Virtio PCI driver - APIs for common functionality for all device versions 65f4c9760SMichael S. Tsirkin * 75f4c9760SMichael S. Tsirkin * This module allows virtio devices to be used over a virtual PCI device. 85f4c9760SMichael S. Tsirkin * This can be used with QEMU based VMMs like KVM or Xen. 95f4c9760SMichael S. Tsirkin * 105f4c9760SMichael S. Tsirkin * Copyright IBM Corp. 2007 115f4c9760SMichael S. Tsirkin * Copyright Red Hat, Inc. 2014 125f4c9760SMichael S. Tsirkin * 135f4c9760SMichael S. Tsirkin * Authors: 145f4c9760SMichael S. Tsirkin * Anthony Liguori <aliguori@us.ibm.com> 155f4c9760SMichael S. Tsirkin * Rusty Russell <rusty@rustcorp.com.au> 165f4c9760SMichael S. Tsirkin * Michael S. Tsirkin <mst@redhat.com> 175f4c9760SMichael S. Tsirkin */ 185f4c9760SMichael S. Tsirkin 195f4c9760SMichael S. Tsirkin #include <linux/module.h> 205f4c9760SMichael S. Tsirkin #include <linux/list.h> 215f4c9760SMichael S. Tsirkin #include <linux/pci.h> 225f4c9760SMichael S. Tsirkin #include <linux/slab.h> 235f4c9760SMichael S. Tsirkin #include <linux/interrupt.h> 245f4c9760SMichael S. Tsirkin #include <linux/virtio.h> 255f4c9760SMichael S. Tsirkin #include <linux/virtio_config.h> 265f4c9760SMichael S. Tsirkin #include <linux/virtio_ring.h> 275f4c9760SMichael S. Tsirkin #include <linux/virtio_pci.h> 28d89c8169SWu Zongyong #include <linux/virtio_pci_legacy.h> 29fd502729SJason Wang #include <linux/virtio_pci_modern.h> 305f4c9760SMichael S. Tsirkin #include <linux/highmem.h> 315f4c9760SMichael S. Tsirkin #include <linux/spinlock.h> 3292792ac7SFeng Liu #include <linux/mutex.h> 335f4c9760SMichael S. Tsirkin 340a9b3f47SMichael S. Tsirkin struct virtio_pci_vq_info { 350a9b3f47SMichael S. Tsirkin /* the actual virtqueue */ 360a9b3f47SMichael S. Tsirkin struct virtqueue *vq; 370a9b3f47SMichael S. Tsirkin 38*06909a44SJiri Pirko /* the list node for the virtqueues or slow_virtqueues list */ 390a9b3f47SMichael S. Tsirkin struct list_head node; 400a9b3f47SMichael S. Tsirkin 410a9b3f47SMichael S. Tsirkin /* MSI-X vector (or none) */ 4231532340SSolomon Tan unsigned int msix_vector; 430a9b3f47SMichael S. Tsirkin }; 440a9b3f47SMichael S. Tsirkin 45fd27ef6bSFeng Liu struct virtio_pci_admin_vq { 46fd27ef6bSFeng Liu /* Virtqueue info associated with this admin queue. */ 47fd27ef6bSFeng Liu struct virtio_pci_vq_info info; 4892792ac7SFeng Liu /* serializing admin commands execution and virtqueue deletion */ 4992792ac7SFeng Liu struct mutex cmd_lock; 50f51e146fSYishai Hadas u64 supported_cmds; 51fd27ef6bSFeng Liu /* Name of the admin queue: avq.$vq_index. */ 52fd27ef6bSFeng Liu char name[10]; 53fd27ef6bSFeng Liu u16 vq_index; 54fd27ef6bSFeng Liu }; 55fd27ef6bSFeng Liu 56b5d58094SJason Wang /* Our device structure */ 57b5d58094SJason Wang struct virtio_pci_device { 58b5d58094SJason Wang struct virtio_device vdev; 59b5d58094SJason Wang struct pci_dev *pci_dev; 604f0fc225SFeng Liu union { 61d89c8169SWu Zongyong struct virtio_pci_legacy_device ldev; 62b5d58094SJason Wang struct virtio_pci_modern_device mdev; 634f0fc225SFeng Liu }; 64d89c8169SWu Zongyong bool is_legacy; 65d89c8169SWu Zongyong 66b5d58094SJason Wang /* Where to read and clear interrupt */ 67b5d58094SJason Wang u8 __iomem *isr; 68b5d58094SJason Wang 69*06909a44SJiri Pirko /* Lists of queues and potentially slow path queues 70*06909a44SJiri Pirko * so we can dispatch IRQs. 71*06909a44SJiri Pirko */ 720a9b3f47SMichael S. Tsirkin spinlock_t lock; 730a9b3f47SMichael S. Tsirkin struct list_head virtqueues; 74*06909a44SJiri Pirko struct list_head slow_virtqueues; 750a9b3f47SMichael S. Tsirkin 76fd27ef6bSFeng Liu /* Array of all virtqueues reported in the 77fd27ef6bSFeng Liu * PCI common config num_queues field 78fd27ef6bSFeng Liu */ 790a9b3f47SMichael S. Tsirkin struct virtio_pci_vq_info **vqs; 800a9b3f47SMichael S. Tsirkin 81fd27ef6bSFeng Liu struct virtio_pci_admin_vq admin_vq; 82fd27ef6bSFeng Liu 832008c154SMichael S. Tsirkin /* MSI-X support */ 842008c154SMichael S. Tsirkin int msix_enabled; 850b0f9dc5SMichael S. Tsirkin int intx_enabled; 865f4c9760SMichael S. Tsirkin cpumask_var_t *msix_affinity_masks; 875f4c9760SMichael S. Tsirkin /* Name strings for interrupts. This size should be enough, 885f4c9760SMichael S. Tsirkin * and I'm too lazy to allocate each name separately. */ 895f4c9760SMichael S. Tsirkin char (*msix_names)[256]; 900b0f9dc5SMichael S. Tsirkin /* Number of available vectors */ 9131532340SSolomon Tan unsigned int msix_vectors; 920b0f9dc5SMichael S. Tsirkin /* Vectors allocated, excluding per-vq vectors if any */ 9331532340SSolomon Tan unsigned int msix_used_vectors; 940b0f9dc5SMichael S. Tsirkin 950a9b3f47SMichael S. Tsirkin /* Whether we have vector per vq */ 960a9b3f47SMichael S. Tsirkin bool per_vq_vectors; 975f4c9760SMichael S. Tsirkin 985f4c9760SMichael S. Tsirkin struct virtqueue *(*setup_vq)(struct virtio_pci_device *vp_dev, 990a9b3f47SMichael S. Tsirkin struct virtio_pci_vq_info *info, 10031532340SSolomon Tan unsigned int idx, 1015f4c9760SMichael S. Tsirkin void (*callback)(struct virtqueue *vq), 1025f4c9760SMichael S. Tsirkin const char *name, 103f94682ddSMichael S. Tsirkin bool ctx, 1045f4c9760SMichael S. Tsirkin u16 msix_vec); 1050a9b3f47SMichael S. Tsirkin void (*del_vq)(struct virtio_pci_vq_info *info); 1065f4c9760SMichael S. Tsirkin 1075f4c9760SMichael S. Tsirkin u16 (*config_vector)(struct virtio_pci_device *vp_dev, u16 vector); 108fd27ef6bSFeng Liu bool (*is_avq)(struct virtio_device *vdev, unsigned int index); 1095f4c9760SMichael S. Tsirkin }; 1105f4c9760SMichael S. Tsirkin 1110b0f9dc5SMichael S. Tsirkin /* Constants for MSI-X */ 1120b0f9dc5SMichael S. Tsirkin /* Use first vector for configuration changes, second and the rest for 1130b0f9dc5SMichael S. Tsirkin * virtqueues Thus, we need at least 2 vectors for MSI. */ 1140b0f9dc5SMichael S. Tsirkin enum { 1150b0f9dc5SMichael S. Tsirkin VP_MSIX_CONFIG_VECTOR = 0, 1160b0f9dc5SMichael S. Tsirkin VP_MSIX_VQ_VECTOR = 1, 1170b0f9dc5SMichael S. Tsirkin }; 1180b0f9dc5SMichael S. Tsirkin 1195f4c9760SMichael S. Tsirkin /* Convert a generic virtio device to our structure */ 1205f4c9760SMichael S. Tsirkin static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) 1215f4c9760SMichael S. Tsirkin { 1225f4c9760SMichael S. Tsirkin return container_of(vdev, struct virtio_pci_device, vdev); 1235f4c9760SMichael S. Tsirkin } 1245f4c9760SMichael S. Tsirkin 125eb4cecb4SJason Wang /* wait for pending irq handlers */ 126eb4cecb4SJason Wang void vp_synchronize_vectors(struct virtio_device *vdev); 1275f4c9760SMichael S. Tsirkin /* the notify function used when creating a virt queue */ 1285f4c9760SMichael S. Tsirkin bool vp_notify(struct virtqueue *vq); 1295f4c9760SMichael S. Tsirkin /* the config->del_vqs() implementation */ 1305f4c9760SMichael S. Tsirkin void vp_del_vqs(struct virtio_device *vdev); 1315f4c9760SMichael S. Tsirkin /* the config->find_vqs() implementation */ 13231532340SSolomon Tan int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs, 133ad9a1257SJiri Pirko struct virtqueue *vqs[], struct virtqueue_info vqs_info[], 134f94682ddSMichael S. Tsirkin struct irq_affinity *desc); 1355f4c9760SMichael S. Tsirkin const char *vp_bus_name(struct virtio_device *vdev); 1365f4c9760SMichael S. Tsirkin 1375f4c9760SMichael S. Tsirkin /* Setup the affinity for a virtqueue: 1385f4c9760SMichael S. Tsirkin * - force the affinity for per vq vector 1395f4c9760SMichael S. Tsirkin * - OR over all affinities for shared MSI 1405f4c9760SMichael S. Tsirkin * - ignore the affinity request if we're using INTX 1415f4c9760SMichael S. Tsirkin */ 14219e226e8SCaleb Raitto int vp_set_vq_affinity(struct virtqueue *vq, const struct cpumask *cpu_mask); 1435f4c9760SMichael S. Tsirkin 144bbaba479SChristoph Hellwig const struct cpumask *vp_get_vq_affinity(struct virtio_device *vdev, int index); 145bbaba479SChristoph Hellwig 14646506da5SMichael S. Tsirkin #if IS_ENABLED(CONFIG_VIRTIO_PCI_LEGACY) 147ff31d2e2SMichael S. Tsirkin int virtio_pci_legacy_probe(struct virtio_pci_device *); 148ff31d2e2SMichael S. Tsirkin void virtio_pci_legacy_remove(struct virtio_pci_device *); 14946506da5SMichael S. Tsirkin #else 15046506da5SMichael S. Tsirkin static inline int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) 15146506da5SMichael S. Tsirkin { 15246506da5SMichael S. Tsirkin return -ENODEV; 15346506da5SMichael S. Tsirkin } 15446506da5SMichael S. Tsirkin static inline void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) 15546506da5SMichael S. Tsirkin { 15646506da5SMichael S. Tsirkin } 15746506da5SMichael S. Tsirkin #endif 1581fcf0512SMichael S. Tsirkin int virtio_pci_modern_probe(struct virtio_pci_device *); 1591fcf0512SMichael S. Tsirkin void virtio_pci_modern_remove(struct virtio_pci_device *); 1605f4c9760SMichael S. Tsirkin 161c3fc3e09SYishai Hadas struct virtio_device *virtio_pci_vf_get_pf_dev(struct pci_dev *pdev); 162c3fc3e09SYishai Hadas 163f51e146fSYishai Hadas #define VIRTIO_LEGACY_ADMIN_CMD_BITMAP \ 164f51e146fSYishai Hadas (BIT_ULL(VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_WRITE) | \ 165f51e146fSYishai Hadas BIT_ULL(VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_READ) | \ 166f51e146fSYishai Hadas BIT_ULL(VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_WRITE) | \ 167f51e146fSYishai Hadas BIT_ULL(VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ) | \ 168f51e146fSYishai Hadas BIT_ULL(VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO)) 169f51e146fSYishai Hadas 170f51e146fSYishai Hadas /* Unlike modern drivers which support hardware virtio devices, legacy drivers 171f51e146fSYishai Hadas * assume software-based devices: e.g. they don't use proper memory barriers 172f51e146fSYishai Hadas * on ARM, use big endian on PPC, etc. X86 drivers are mostly ok though, more 173f51e146fSYishai Hadas * or less by chance. For now, only support legacy IO on X86. 174f51e146fSYishai Hadas */ 175f51e146fSYishai Hadas #ifdef CONFIG_VIRTIO_PCI_ADMIN_LEGACY 176f51e146fSYishai Hadas #define VIRTIO_ADMIN_CMD_BITMAP VIRTIO_LEGACY_ADMIN_CMD_BITMAP 177f51e146fSYishai Hadas #else 178f51e146fSYishai Hadas #define VIRTIO_ADMIN_CMD_BITMAP 0 179f51e146fSYishai Hadas #endif 180f51e146fSYishai Hadas 18192792ac7SFeng Liu int vp_modern_admin_cmd_exec(struct virtio_device *vdev, 18292792ac7SFeng Liu struct virtio_admin_cmd *cmd); 18392792ac7SFeng Liu 1845f4c9760SMichael S. Tsirkin #endif 185