diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-15 17:35:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-15 17:35:02 -0400 |
commit | 2f3f056685198e9fc76c23bd88fbe2662ab7b044 (patch) | |
tree | 98ee7ade3620cac729ce85434fd85e84e411ea64 | |
parent | 4c5e8fc62d6a63065eeae80808c498d1dcfea4f4 (diff) | |
parent | 2eb98105f8c7f4b867f7f714a998f5b8c1bb009b (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.c | 3 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci_common.c | 30 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci_modern.c | 14 | ||||
-rw-r--r-- | include/linux/virtio_ring.h | 4 | ||||
-rw-r--r-- | include/uapi/linux/virtio_config.h | 16 |
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 | ||
594 | static 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 | |||
592 | static struct pci_driver virtio_pci_driver = { | 621 | static 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 | ||
602 | module_pci_driver(virtio_pci_driver); | 632 | module_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 | ||
156 | static 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 */ |
157 | static int vp_finalize_features(struct virtio_device *vdev) | 167 | static 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 | ||
41 | static inline void virtio_wmb(bool weak_barriers) | 41 | static 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 | ||
49 | static inline void virtio_store_mb(bool weak_barriers, | 49 | static 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 */ |