aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-15 17:35:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-15 17:35:02 -0400
commit2f3f056685198e9fc76c23bd88fbe2662ab7b044 (patch)
tree98ee7ade3620cac729ce85434fd85e84e411ea64
parent4c5e8fc62d6a63065eeae80808c498d1dcfea4f4 (diff)
parent2eb98105f8c7f4b867f7f714a998f5b8c1bb009b (diff)
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio updates from Michael Tsirkin: "virtio, vhost: features, fixes - PCI virtual function support for virtio - DMA barriers for virtio strong barriers - bugfixes" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio: update the comments for transport features virtio_pci: support enabling VFs vhost: fix info leak due to uninitialized memory virtio_ring: switch to dma_XX barriers for rpmsg
-rw-r--r--drivers/vhost/vhost.c3
-rw-r--r--drivers/virtio/virtio_pci_common.c30
-rw-r--r--drivers/virtio/virtio_pci_modern.c14
-rw-r--r--include/linux/virtio_ring.h4
-rw-r--r--include/uapi/linux/virtio_config.h16
5 files changed, 61 insertions, 6 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index ce8c95b6365b..a502f1af4a21 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -2349,6 +2349,9 @@ struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type)
2349 struct vhost_msg_node *node = kmalloc(sizeof *node, GFP_KERNEL); 2349 struct vhost_msg_node *node = kmalloc(sizeof *node, GFP_KERNEL);
2350 if (!node) 2350 if (!node)
2351 return NULL; 2351 return NULL;
2352
2353 /* Make sure all padding within the structure is initialized. */
2354 memset(&node->msg, 0, sizeof node->msg);
2352 node->vq = vq; 2355 node->vq = vq;
2353 node->msg.type = type; 2356 node->msg.type = type;
2354 return node; 2357 return node;
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index b563a4499cc8..705aebd74e56 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -578,6 +578,8 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
578 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); 578 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
579 struct device *dev = get_device(&vp_dev->vdev.dev); 579 struct device *dev = get_device(&vp_dev->vdev.dev);
580 580
581 pci_disable_sriov(pci_dev);
582
581 unregister_virtio_device(&vp_dev->vdev); 583 unregister_virtio_device(&vp_dev->vdev);
582 584
583 if (vp_dev->ioaddr) 585 if (vp_dev->ioaddr)
@@ -589,6 +591,33 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
589 put_device(dev); 591 put_device(dev);
590} 592}
591 593
594static int virtio_pci_sriov_configure(struct pci_dev *pci_dev, int num_vfs)
595{
596 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
597 struct virtio_device *vdev = &vp_dev->vdev;
598 int ret;
599
600 if (!(vdev->config->get_status(vdev) & VIRTIO_CONFIG_S_DRIVER_OK))
601 return -EBUSY;
602
603 if (!__virtio_test_bit(vdev, VIRTIO_F_SR_IOV))
604 return -EINVAL;
605
606 if (pci_vfs_assigned(pci_dev))
607 return -EPERM;
608
609 if (num_vfs == 0) {
610 pci_disable_sriov(pci_dev);
611 return 0;
612 }
613
614 ret = pci_enable_sriov(pci_dev, num_vfs);
615 if (ret < 0)
616 return ret;
617
618 return num_vfs;
619}
620
592static struct pci_driver virtio_pci_driver = { 621static struct pci_driver virtio_pci_driver = {
593 .name = "virtio-pci", 622 .name = "virtio-pci",
594 .id_table = virtio_pci_id_table, 623 .id_table = virtio_pci_id_table,
@@ -597,6 +626,7 @@ static struct pci_driver virtio_pci_driver = {
597#ifdef CONFIG_PM_SLEEP 626#ifdef CONFIG_PM_SLEEP
598 .driver.pm = &virtio_pci_pm_ops, 627 .driver.pm = &virtio_pci_pm_ops,
599#endif 628#endif
629 .sriov_configure = virtio_pci_sriov_configure,
600}; 630};
601 631
602module_pci_driver(virtio_pci_driver); 632module_pci_driver(virtio_pci_driver);
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 2555d80f6eec..07571daccfec 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -153,14 +153,28 @@ static u64 vp_get_features(struct virtio_device *vdev)
153 return features; 153 return features;
154} 154}
155 155
156static void vp_transport_features(struct virtio_device *vdev, u64 features)
157{
158 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
159 struct pci_dev *pci_dev = vp_dev->pci_dev;
160
161 if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
162 pci_find_ext_capability(pci_dev, PCI_EXT_CAP_ID_SRIOV))
163 __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
164}
165
156/* virtio config->finalize_features() implementation */ 166/* virtio config->finalize_features() implementation */
157static int vp_finalize_features(struct virtio_device *vdev) 167static int vp_finalize_features(struct virtio_device *vdev)
158{ 168{
159 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 169 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
170 u64 features = vdev->features;
160 171
161 /* Give virtio_ring a chance to accept features. */ 172 /* Give virtio_ring a chance to accept features. */
162 vring_transport_features(vdev); 173 vring_transport_features(vdev);
163 174
175 /* Give virtio_pci a chance to accept features. */
176 vp_transport_features(vdev, features);
177
164 if (!__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) { 178 if (!__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) {
165 dev_err(&vdev->dev, "virtio: device uses modern interface " 179 dev_err(&vdev->dev, "virtio: device uses modern interface "
166 "but does not have VIRTIO_F_VERSION_1\n"); 180 "but does not have VIRTIO_F_VERSION_1\n");
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index bbf32524ab27..fab02133a919 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -35,7 +35,7 @@ static inline void virtio_rmb(bool weak_barriers)
35 if (weak_barriers) 35 if (weak_barriers)
36 virt_rmb(); 36 virt_rmb();
37 else 37 else
38 rmb(); 38 dma_rmb();
39} 39}
40 40
41static inline void virtio_wmb(bool weak_barriers) 41static inline void virtio_wmb(bool weak_barriers)
@@ -43,7 +43,7 @@ static inline void virtio_wmb(bool weak_barriers)
43 if (weak_barriers) 43 if (weak_barriers)
44 virt_wmb(); 44 virt_wmb();
45 else 45 else
46 wmb(); 46 dma_wmb();
47} 47}
48 48
49static inline void virtio_store_mb(bool weak_barriers, 49static inline void virtio_store_mb(bool weak_barriers,
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
index 308e2096291f..449132c76b1c 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -45,11 +45,14 @@
45/* We've given up on this device. */ 45/* We've given up on this device. */
46#define VIRTIO_CONFIG_S_FAILED 0x80 46#define VIRTIO_CONFIG_S_FAILED 0x80
47 47
48/* Some virtio feature bits (currently bits 28 through 32) are reserved for the 48/*
49 * transport being used (eg. virtio_ring), the rest are per-device feature 49 * Virtio feature bits VIRTIO_TRANSPORT_F_START through
50 * bits. */ 50 * VIRTIO_TRANSPORT_F_END are reserved for the transport
51 * being used (e.g. virtio_ring, virtio_pci etc.), the
52 * rest are per-device feature bits.
53 */
51#define VIRTIO_TRANSPORT_F_START 28 54#define VIRTIO_TRANSPORT_F_START 28
52#define VIRTIO_TRANSPORT_F_END 34 55#define VIRTIO_TRANSPORT_F_END 38
53 56
54#ifndef VIRTIO_CONFIG_NO_LEGACY 57#ifndef VIRTIO_CONFIG_NO_LEGACY
55/* Do we get callbacks when the ring is completely used, even if we've 58/* Do we get callbacks when the ring is completely used, even if we've
@@ -71,4 +74,9 @@
71 * this is for compatibility with legacy systems. 74 * this is for compatibility with legacy systems.
72 */ 75 */
73#define VIRTIO_F_IOMMU_PLATFORM 33 76#define VIRTIO_F_IOMMU_PLATFORM 33
77
78/*
79 * Does the device support Single Root I/O Virtualization?
80 */
81#define VIRTIO_F_SR_IOV 37
74#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ 82#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */