138eb4a29SMichael S. Tsirkin /* 2a90fdce9SMichael S. Tsirkin * Virtio PCI driver - legacy device support 338eb4a29SMichael S. Tsirkin * 438eb4a29SMichael S. Tsirkin * This module allows virtio devices to be used over a virtual PCI device. 538eb4a29SMichael S. Tsirkin * This can be used with QEMU based VMMs like KVM or Xen. 638eb4a29SMichael S. Tsirkin * 738eb4a29SMichael S. Tsirkin * Copyright IBM Corp. 2007 8a90fdce9SMichael S. Tsirkin * Copyright Red Hat, Inc. 2014 938eb4a29SMichael S. Tsirkin * 1038eb4a29SMichael S. Tsirkin * Authors: 1138eb4a29SMichael S. Tsirkin * Anthony Liguori <aliguori@us.ibm.com> 12a90fdce9SMichael S. Tsirkin * Rusty Russell <rusty@rustcorp.com.au> 13a90fdce9SMichael S. Tsirkin * Michael S. Tsirkin <mst@redhat.com> 1438eb4a29SMichael S. Tsirkin * 1538eb4a29SMichael S. Tsirkin * This work is licensed under the terms of the GNU GPL, version 2 or later. 1638eb4a29SMichael S. Tsirkin * See the COPYING file in the top-level directory. 1738eb4a29SMichael S. Tsirkin * 1838eb4a29SMichael S. Tsirkin */ 1938eb4a29SMichael S. Tsirkin 205f4c9760SMichael S. Tsirkin #include "virtio_pci_common.h" 2138eb4a29SMichael S. Tsirkin 2238eb4a29SMichael S. Tsirkin /* virtio config->get_features() implementation */ 2338eb4a29SMichael S. Tsirkin static u64 vp_get_features(struct virtio_device *vdev) 2438eb4a29SMichael S. Tsirkin { 2538eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 2638eb4a29SMichael S. Tsirkin 2738eb4a29SMichael S. Tsirkin /* When someone needs more than 32 feature bits, we'll need to 2838eb4a29SMichael S. Tsirkin * steal a bit to indicate that the rest are somewhere else. */ 2938eb4a29SMichael S. Tsirkin return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); 3038eb4a29SMichael S. Tsirkin } 3138eb4a29SMichael S. Tsirkin 3238eb4a29SMichael S. Tsirkin /* virtio config->finalize_features() implementation */ 3338eb4a29SMichael S. Tsirkin static int vp_finalize_features(struct virtio_device *vdev) 3438eb4a29SMichael S. Tsirkin { 3538eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 3638eb4a29SMichael S. Tsirkin 3738eb4a29SMichael S. Tsirkin /* Give virtio_ring a chance to accept features. */ 3838eb4a29SMichael S. Tsirkin vring_transport_features(vdev); 3938eb4a29SMichael S. Tsirkin 4038eb4a29SMichael S. Tsirkin /* Make sure we don't have any features > 32 bits! */ 4138eb4a29SMichael S. Tsirkin BUG_ON((u32)vdev->features != vdev->features); 4238eb4a29SMichael S. Tsirkin 4338eb4a29SMichael S. Tsirkin /* We only support 32 feature bits. */ 4438eb4a29SMichael S. Tsirkin iowrite32(vdev->features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); 4538eb4a29SMichael S. Tsirkin 4638eb4a29SMichael S. Tsirkin return 0; 4738eb4a29SMichael S. Tsirkin } 4838eb4a29SMichael S. Tsirkin 4938eb4a29SMichael S. Tsirkin /* virtio config->get() implementation */ 5038eb4a29SMichael S. Tsirkin static void vp_get(struct virtio_device *vdev, unsigned offset, 5138eb4a29SMichael S. Tsirkin void *buf, unsigned len) 5238eb4a29SMichael S. Tsirkin { 5338eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 5438eb4a29SMichael S. Tsirkin void __iomem *ioaddr = vp_dev->ioaddr + 5538eb4a29SMichael S. Tsirkin VIRTIO_PCI_CONFIG(vp_dev) + offset; 5638eb4a29SMichael S. Tsirkin u8 *ptr = buf; 5738eb4a29SMichael S. Tsirkin int i; 5838eb4a29SMichael S. Tsirkin 5938eb4a29SMichael S. Tsirkin for (i = 0; i < len; i++) 6038eb4a29SMichael S. Tsirkin ptr[i] = ioread8(ioaddr + i); 6138eb4a29SMichael S. Tsirkin } 6238eb4a29SMichael S. Tsirkin 6338eb4a29SMichael S. Tsirkin /* the config->set() implementation. it's symmetric to the config->get() 6438eb4a29SMichael S. Tsirkin * implementation */ 6538eb4a29SMichael S. Tsirkin static void vp_set(struct virtio_device *vdev, unsigned offset, 6638eb4a29SMichael S. Tsirkin const void *buf, unsigned len) 6738eb4a29SMichael S. Tsirkin { 6838eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 6938eb4a29SMichael S. Tsirkin void __iomem *ioaddr = vp_dev->ioaddr + 7038eb4a29SMichael S. Tsirkin VIRTIO_PCI_CONFIG(vp_dev) + offset; 7138eb4a29SMichael S. Tsirkin const u8 *ptr = buf; 7238eb4a29SMichael S. Tsirkin int i; 7338eb4a29SMichael S. Tsirkin 7438eb4a29SMichael S. Tsirkin for (i = 0; i < len; i++) 7538eb4a29SMichael S. Tsirkin iowrite8(ptr[i], ioaddr + i); 7638eb4a29SMichael S. Tsirkin } 7738eb4a29SMichael S. Tsirkin 7838eb4a29SMichael S. Tsirkin /* config->{get,set}_status() implementations */ 7938eb4a29SMichael S. Tsirkin static u8 vp_get_status(struct virtio_device *vdev) 8038eb4a29SMichael S. Tsirkin { 8138eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 8238eb4a29SMichael S. Tsirkin return ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); 8338eb4a29SMichael S. Tsirkin } 8438eb4a29SMichael S. Tsirkin 8538eb4a29SMichael S. Tsirkin static void vp_set_status(struct virtio_device *vdev, u8 status) 8638eb4a29SMichael S. Tsirkin { 8738eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 8838eb4a29SMichael S. Tsirkin /* We should never be setting status to 0. */ 8938eb4a29SMichael S. Tsirkin BUG_ON(status == 0); 9038eb4a29SMichael S. Tsirkin iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 9138eb4a29SMichael S. Tsirkin } 9238eb4a29SMichael S. Tsirkin 9338eb4a29SMichael S. Tsirkin static void vp_reset(struct virtio_device *vdev) 9438eb4a29SMichael S. Tsirkin { 9538eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vdev); 9638eb4a29SMichael S. Tsirkin /* 0 status means a reset. */ 9738eb4a29SMichael S. Tsirkin iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 9838eb4a29SMichael S. Tsirkin /* Flush out the status write, and flush in device writes, 9938eb4a29SMichael S. Tsirkin * including MSi-X interrupts, if any. */ 10038eb4a29SMichael S. Tsirkin ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); 10138eb4a29SMichael S. Tsirkin /* Flush pending VQ/configuration callbacks. */ 10238eb4a29SMichael S. Tsirkin vp_synchronize_vectors(vdev); 10338eb4a29SMichael S. Tsirkin } 10438eb4a29SMichael S. Tsirkin 10538eb4a29SMichael S. Tsirkin static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) 10638eb4a29SMichael S. Tsirkin { 10738eb4a29SMichael S. Tsirkin /* Setup the vector used for configuration events */ 10838eb4a29SMichael S. Tsirkin iowrite16(vector, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); 10938eb4a29SMichael S. Tsirkin /* Verify we had enough resources to assign the vector */ 11038eb4a29SMichael S. Tsirkin /* Will also flush the write out to device */ 11138eb4a29SMichael S. Tsirkin return ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); 11238eb4a29SMichael S. Tsirkin } 11338eb4a29SMichael S. Tsirkin 11438eb4a29SMichael S. Tsirkin static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, 1150a9b3f47SMichael S. Tsirkin struct virtio_pci_vq_info *info, 11638eb4a29SMichael S. Tsirkin unsigned index, 11738eb4a29SMichael S. Tsirkin void (*callback)(struct virtqueue *vq), 11838eb4a29SMichael S. Tsirkin const char *name, 119f94682ddSMichael S. Tsirkin bool ctx, 12038eb4a29SMichael S. Tsirkin u16 msix_vec) 12138eb4a29SMichael S. Tsirkin { 12238eb4a29SMichael S. Tsirkin struct virtqueue *vq; 12338eb4a29SMichael S. Tsirkin u16 num; 12438eb4a29SMichael S. Tsirkin int err; 12569599206SSuzuki K Poulose u64 q_pfn; 12638eb4a29SMichael S. Tsirkin 12738eb4a29SMichael S. Tsirkin /* Select the queue we're interested in */ 12838eb4a29SMichael S. Tsirkin iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); 12938eb4a29SMichael S. Tsirkin 13038eb4a29SMichael S. Tsirkin /* Check if queue is either not available or already active. */ 13138eb4a29SMichael S. Tsirkin num = ioread16(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NUM); 13238eb4a29SMichael S. Tsirkin if (!num || ioread32(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN)) 13338eb4a29SMichael S. Tsirkin return ERR_PTR(-ENOENT); 13438eb4a29SMichael S. Tsirkin 1350a9b3f47SMichael S. Tsirkin info->msix_vector = msix_vec; 1360a9b3f47SMichael S. Tsirkin 1377a5589b2SAndy Lutomirski /* create the vring */ 1387a5589b2SAndy Lutomirski vq = vring_create_virtqueue(index, num, 1397a5589b2SAndy Lutomirski VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev, 140f94682ddSMichael S. Tsirkin true, false, ctx, 141f94682ddSMichael S. Tsirkin vp_notify, callback, name); 1427a5589b2SAndy Lutomirski if (!vq) 14338eb4a29SMichael S. Tsirkin return ERR_PTR(-ENOMEM); 14438eb4a29SMichael S. Tsirkin 14569599206SSuzuki K Poulose q_pfn = virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; 14669599206SSuzuki K Poulose if (q_pfn >> 32) { 14769599206SSuzuki K Poulose dev_err(&vp_dev->pci_dev->dev, 14869599206SSuzuki K Poulose "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n", 14969599206SSuzuki K Poulose 0x1ULL << (32 + PAGE_SHIFT - 30)); 15069599206SSuzuki K Poulose err = -E2BIG; 15169599206SSuzuki K Poulose goto out_del_vq; 15269599206SSuzuki K Poulose } 15369599206SSuzuki K Poulose 15438eb4a29SMichael S. Tsirkin /* activate the queue */ 15569599206SSuzuki K Poulose iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); 15638eb4a29SMichael S. Tsirkin 15738eb4a29SMichael S. Tsirkin vq->priv = (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY; 15838eb4a29SMichael S. Tsirkin 15938eb4a29SMichael S. Tsirkin if (msix_vec != VIRTIO_MSI_NO_VECTOR) { 16038eb4a29SMichael S. Tsirkin iowrite16(msix_vec, vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); 16138eb4a29SMichael S. Tsirkin msix_vec = ioread16(vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); 16238eb4a29SMichael S. Tsirkin if (msix_vec == VIRTIO_MSI_NO_VECTOR) { 16338eb4a29SMichael S. Tsirkin err = -EBUSY; 1647a5589b2SAndy Lutomirski goto out_deactivate; 16538eb4a29SMichael S. Tsirkin } 16638eb4a29SMichael S. Tsirkin } 16738eb4a29SMichael S. Tsirkin 16838eb4a29SMichael S. Tsirkin return vq; 16938eb4a29SMichael S. Tsirkin 1707a5589b2SAndy Lutomirski out_deactivate: 17138eb4a29SMichael S. Tsirkin iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); 17269599206SSuzuki K Poulose out_del_vq: 1737a5589b2SAndy Lutomirski vring_del_virtqueue(vq); 17438eb4a29SMichael S. Tsirkin return ERR_PTR(err); 17538eb4a29SMichael S. Tsirkin } 17638eb4a29SMichael S. Tsirkin 1770a9b3f47SMichael S. Tsirkin static void del_vq(struct virtio_pci_vq_info *info) 17838eb4a29SMichael S. Tsirkin { 1790a9b3f47SMichael S. Tsirkin struct virtqueue *vq = info->vq; 18038eb4a29SMichael S. Tsirkin struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); 18138eb4a29SMichael S. Tsirkin 18238eb4a29SMichael S. Tsirkin iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); 18338eb4a29SMichael S. Tsirkin 1842008c154SMichael S. Tsirkin if (vp_dev->msix_enabled) { 18538eb4a29SMichael S. Tsirkin iowrite16(VIRTIO_MSI_NO_VECTOR, 18638eb4a29SMichael S. Tsirkin vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); 18738eb4a29SMichael S. Tsirkin /* Flush the write out to device */ 18838eb4a29SMichael S. Tsirkin ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR); 18938eb4a29SMichael S. Tsirkin } 19038eb4a29SMichael S. Tsirkin 19138eb4a29SMichael S. Tsirkin /* Select and deactivate the queue */ 19238eb4a29SMichael S. Tsirkin iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); 19338eb4a29SMichael S. Tsirkin 1947a5589b2SAndy Lutomirski vring_del_virtqueue(vq); 19538eb4a29SMichael S. Tsirkin } 19638eb4a29SMichael S. Tsirkin 19738eb4a29SMichael S. Tsirkin static const struct virtio_config_ops virtio_pci_config_ops = { 19838eb4a29SMichael S. Tsirkin .get = vp_get, 19938eb4a29SMichael S. Tsirkin .set = vp_set, 20038eb4a29SMichael S. Tsirkin .get_status = vp_get_status, 20138eb4a29SMichael S. Tsirkin .set_status = vp_set_status, 20238eb4a29SMichael S. Tsirkin .reset = vp_reset, 20338eb4a29SMichael S. Tsirkin .find_vqs = vp_find_vqs, 20438eb4a29SMichael S. Tsirkin .del_vqs = vp_del_vqs, 20538eb4a29SMichael S. Tsirkin .get_features = vp_get_features, 20638eb4a29SMichael S. Tsirkin .finalize_features = vp_finalize_features, 20738eb4a29SMichael S. Tsirkin .bus_name = vp_bus_name, 20838eb4a29SMichael S. Tsirkin .set_vq_affinity = vp_set_vq_affinity, 209bbaba479SChristoph Hellwig .get_vq_affinity = vp_get_vq_affinity, 21038eb4a29SMichael S. Tsirkin }; 21138eb4a29SMichael S. Tsirkin 21238eb4a29SMichael S. Tsirkin /* the PCI probing function */ 213ff31d2e2SMichael S. Tsirkin int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) 21438eb4a29SMichael S. Tsirkin { 215ff31d2e2SMichael S. Tsirkin struct pci_dev *pci_dev = vp_dev->pci_dev; 21659a5b0f7SGerd Hoffmann int rc; 21738eb4a29SMichael S. Tsirkin 21838eb4a29SMichael S. Tsirkin /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ 21938eb4a29SMichael S. Tsirkin if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) 22038eb4a29SMichael S. Tsirkin return -ENODEV; 22138eb4a29SMichael S. Tsirkin 22238eb4a29SMichael S. Tsirkin if (pci_dev->revision != VIRTIO_PCI_ABI_VERSION) { 22338eb4a29SMichael S. Tsirkin printk(KERN_ERR "virtio_pci: expected ABI version %d, got %d\n", 22438eb4a29SMichael S. Tsirkin VIRTIO_PCI_ABI_VERSION, pci_dev->revision); 22538eb4a29SMichael S. Tsirkin return -ENODEV; 22638eb4a29SMichael S. Tsirkin } 22738eb4a29SMichael S. Tsirkin 228a0be1db4SWill Deacon rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); 229a0be1db4SWill Deacon if (rc) { 230a0be1db4SWill Deacon rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); 231a0be1db4SWill Deacon } else { 232a0be1db4SWill Deacon /* 233a0be1db4SWill Deacon * The virtio ring base address is expressed as a 32-bit PFN, 234a0be1db4SWill Deacon * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT. 235a0be1db4SWill Deacon */ 236a0be1db4SWill Deacon dma_set_coherent_mask(&pci_dev->dev, 237a0be1db4SWill Deacon DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT)); 238a0be1db4SWill Deacon } 239a0be1db4SWill Deacon 2407a5589b2SAndy Lutomirski if (rc) 2417a5589b2SAndy Lutomirski dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n"); 2427a5589b2SAndy Lutomirski 24359a5b0f7SGerd Hoffmann rc = pci_request_region(pci_dev, 0, "virtio-pci-legacy"); 24459a5b0f7SGerd Hoffmann if (rc) 24559a5b0f7SGerd Hoffmann return rc; 24659a5b0f7SGerd Hoffmann 24759a5b0f7SGerd Hoffmann rc = -ENOMEM; 248ff31d2e2SMichael S. Tsirkin vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); 249ff31d2e2SMichael S. Tsirkin if (!vp_dev->ioaddr) 25059a5b0f7SGerd Hoffmann goto err_iomap; 25138eb4a29SMichael S. Tsirkin 25238eb4a29SMichael S. Tsirkin vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; 25338eb4a29SMichael S. Tsirkin 25438eb4a29SMichael S. Tsirkin /* we use the subsystem vendor/device id as the virtio vendor/device 25538eb4a29SMichael S. Tsirkin * id. this allows us to use the same PCI vendor/device id for all 25638eb4a29SMichael S. Tsirkin * virtio devices and to identify the particular virtio driver by 25738eb4a29SMichael S. Tsirkin * the subsystem ids */ 25838eb4a29SMichael S. Tsirkin vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; 25938eb4a29SMichael S. Tsirkin vp_dev->vdev.id.device = pci_dev->subsystem_device; 26038eb4a29SMichael S. Tsirkin 261ff31d2e2SMichael S. Tsirkin vp_dev->vdev.config = &virtio_pci_config_ops; 262ff31d2e2SMichael S. Tsirkin 26338eb4a29SMichael S. Tsirkin vp_dev->config_vector = vp_config_vector; 26438eb4a29SMichael S. Tsirkin vp_dev->setup_vq = setup_vq; 26538eb4a29SMichael S. Tsirkin vp_dev->del_vq = del_vq; 26638eb4a29SMichael S. Tsirkin 26738eb4a29SMichael S. Tsirkin return 0; 26859a5b0f7SGerd Hoffmann 26959a5b0f7SGerd Hoffmann err_iomap: 27059a5b0f7SGerd Hoffmann pci_release_region(pci_dev, 0); 27159a5b0f7SGerd Hoffmann return rc; 27238eb4a29SMichael S. Tsirkin } 27338eb4a29SMichael S. Tsirkin 274ff31d2e2SMichael S. Tsirkin void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) 27538eb4a29SMichael S. Tsirkin { 276ff31d2e2SMichael S. Tsirkin struct pci_dev *pci_dev = vp_dev->pci_dev; 27738eb4a29SMichael S. Tsirkin 27838eb4a29SMichael S. Tsirkin pci_iounmap(pci_dev, vp_dev->ioaddr); 27959a5b0f7SGerd Hoffmann pci_release_region(pci_dev, 0); 28038eb4a29SMichael S. Tsirkin } 281