diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-20 13:37:16 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-20 13:37:16 -0500 |
| commit | bb617b9b4519b0cef939c9c8e9c41470749f0d51 (patch) | |
| tree | 56616b232bde3d7f9469d2f7ef685a4a6c0b4cb9 | |
| parent | 1be969f4682b0aa1995e46fba51502de55f15ce8 (diff) | |
| parent | 8e5dadfe76cf2862ebf3e4f22adef29982df7766 (diff) | |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio/vhost fixes and cleanups from Michael Tsirkin:
"Fixes and cleanups all over the place"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
vhost/scsi: Use copy_to_iter() to send control queue response
vhost: return EINVAL if iovecs size does not match the message size
virtio-balloon: tweak config_changed implementation
virtio: don't allocate vqs when names[i] = NULL
virtio_pci: use queue idx instead of array idx to set up the vq
virtio: document virtio_config_ops restrictions
virtio: fix virtio_config_ops description
| -rw-r--r-- | drivers/misc/mic/vop/vop_main.c | 9 | ||||
| -rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 9 | ||||
| -rw-r--r-- | drivers/s390/virtio/virtio_ccw.c | 12 | ||||
| -rw-r--r-- | drivers/vhost/scsi.c | 20 | ||||
| -rw-r--r-- | drivers/vhost/vhost.c | 8 | ||||
| -rw-r--r-- | drivers/virtio/virtio_balloon.c | 98 | ||||
| -rw-r--r-- | drivers/virtio/virtio_mmio.c | 9 | ||||
| -rw-r--r-- | drivers/virtio/virtio_pci_common.c | 8 | ||||
| -rw-r--r-- | include/linux/virtio_config.h | 13 |
9 files changed, 126 insertions, 60 deletions
diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c index 6b212c8b78e7..2bfa3a903bf9 100644 --- a/drivers/misc/mic/vop/vop_main.c +++ b/drivers/misc/mic/vop/vop_main.c | |||
| @@ -394,16 +394,21 @@ static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs, | |||
| 394 | struct _vop_vdev *vdev = to_vopvdev(dev); | 394 | struct _vop_vdev *vdev = to_vopvdev(dev); |
| 395 | struct vop_device *vpdev = vdev->vpdev; | 395 | struct vop_device *vpdev = vdev->vpdev; |
| 396 | struct mic_device_ctrl __iomem *dc = vdev->dc; | 396 | struct mic_device_ctrl __iomem *dc = vdev->dc; |
| 397 | int i, err, retry; | 397 | int i, err, retry, queue_idx = 0; |
| 398 | 398 | ||
| 399 | /* We must have this many virtqueues. */ | 399 | /* We must have this many virtqueues. */ |
| 400 | if (nvqs > ioread8(&vdev->desc->num_vq)) | 400 | if (nvqs > ioread8(&vdev->desc->num_vq)) |
| 401 | return -ENOENT; | 401 | return -ENOENT; |
| 402 | 402 | ||
| 403 | for (i = 0; i < nvqs; ++i) { | 403 | for (i = 0; i < nvqs; ++i) { |
| 404 | if (!names[i]) { | ||
| 405 | vqs[i] = NULL; | ||
| 406 | continue; | ||
| 407 | } | ||
| 408 | |||
| 404 | dev_dbg(_vop_dev(vdev), "%s: %d: %s\n", | 409 | dev_dbg(_vop_dev(vdev), "%s: %d: %s\n", |
| 405 | __func__, i, names[i]); | 410 | __func__, i, names[i]); |
| 406 | vqs[i] = vop_find_vq(dev, i, callbacks[i], names[i], | 411 | vqs[i] = vop_find_vq(dev, queue_idx++, callbacks[i], names[i], |
| 407 | ctx ? ctx[i] : false); | 412 | ctx ? ctx[i] : false); |
| 408 | if (IS_ERR(vqs[i])) { | 413 | if (IS_ERR(vqs[i])) { |
| 409 | err = PTR_ERR(vqs[i]); | 414 | err = PTR_ERR(vqs[i]); |
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 183fc42a510a..2d7cd344f3bf 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c | |||
| @@ -153,10 +153,15 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs, | |||
| 153 | const bool * ctx, | 153 | const bool * ctx, |
| 154 | struct irq_affinity *desc) | 154 | struct irq_affinity *desc) |
| 155 | { | 155 | { |
| 156 | int i, ret; | 156 | int i, ret, queue_idx = 0; |
| 157 | 157 | ||
| 158 | for (i = 0; i < nvqs; ++i) { | 158 | for (i = 0; i < nvqs; ++i) { |
| 159 | vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i], | 159 | if (!names[i]) { |
| 160 | vqs[i] = NULL; | ||
| 161 | continue; | ||
| 162 | } | ||
| 163 | |||
| 164 | vqs[i] = rp_find_vq(vdev, queue_idx++, callbacks[i], names[i], | ||
| 160 | ctx ? ctx[i] : false); | 165 | ctx ? ctx[i] : false); |
| 161 | if (IS_ERR(vqs[i])) { | 166 | if (IS_ERR(vqs[i])) { |
| 162 | ret = PTR_ERR(vqs[i]); | 167 | ret = PTR_ERR(vqs[i]); |
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index fc9dbad476c0..ae1d56da671d 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c | |||
| @@ -635,7 +635,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
| 635 | { | 635 | { |
| 636 | struct virtio_ccw_device *vcdev = to_vc_device(vdev); | 636 | struct virtio_ccw_device *vcdev = to_vc_device(vdev); |
| 637 | unsigned long *indicatorp = NULL; | 637 | unsigned long *indicatorp = NULL; |
| 638 | int ret, i; | 638 | int ret, i, queue_idx = 0; |
| 639 | struct ccw1 *ccw; | 639 | struct ccw1 *ccw; |
| 640 | 640 | ||
| 641 | ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); | 641 | ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); |
| @@ -643,8 +643,14 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
| 643 | return -ENOMEM; | 643 | return -ENOMEM; |
| 644 | 644 | ||
| 645 | for (i = 0; i < nvqs; ++i) { | 645 | for (i = 0; i < nvqs; ++i) { |
| 646 | vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i], | 646 | if (!names[i]) { |
| 647 | ctx ? ctx[i] : false, ccw); | 647 | vqs[i] = NULL; |
| 648 | continue; | ||
| 649 | } | ||
| 650 | |||
| 651 | vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i], | ||
| 652 | names[i], ctx ? ctx[i] : false, | ||
| 653 | ccw); | ||
| 648 | if (IS_ERR(vqs[i])) { | 654 | if (IS_ERR(vqs[i])) { |
| 649 | ret = PTR_ERR(vqs[i]); | 655 | ret = PTR_ERR(vqs[i]); |
| 650 | vqs[i] = NULL; | 656 | vqs[i] = NULL; |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 8e10ab436d1f..344684f3e2e4 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
| @@ -1127,16 +1127,18 @@ vhost_scsi_send_tmf_reject(struct vhost_scsi *vs, | |||
| 1127 | struct vhost_virtqueue *vq, | 1127 | struct vhost_virtqueue *vq, |
| 1128 | struct vhost_scsi_ctx *vc) | 1128 | struct vhost_scsi_ctx *vc) |
| 1129 | { | 1129 | { |
| 1130 | struct virtio_scsi_ctrl_tmf_resp __user *resp; | ||
| 1131 | struct virtio_scsi_ctrl_tmf_resp rsp; | 1130 | struct virtio_scsi_ctrl_tmf_resp rsp; |
| 1131 | struct iov_iter iov_iter; | ||
| 1132 | int ret; | 1132 | int ret; |
| 1133 | 1133 | ||
| 1134 | pr_debug("%s\n", __func__); | 1134 | pr_debug("%s\n", __func__); |
| 1135 | memset(&rsp, 0, sizeof(rsp)); | 1135 | memset(&rsp, 0, sizeof(rsp)); |
| 1136 | rsp.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; | 1136 | rsp.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; |
| 1137 | resp = vq->iov[vc->out].iov_base; | 1137 | |
| 1138 | ret = __copy_to_user(resp, &rsp, sizeof(rsp)); | 1138 | iov_iter_init(&iov_iter, READ, &vq->iov[vc->out], vc->in, sizeof(rsp)); |
| 1139 | if (!ret) | 1139 | |
| 1140 | ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); | ||
| 1141 | if (likely(ret == sizeof(rsp))) | ||
| 1140 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); | 1142 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); |
| 1141 | else | 1143 | else |
| 1142 | pr_err("Faulted on virtio_scsi_ctrl_tmf_resp\n"); | 1144 | pr_err("Faulted on virtio_scsi_ctrl_tmf_resp\n"); |
| @@ -1147,16 +1149,18 @@ vhost_scsi_send_an_resp(struct vhost_scsi *vs, | |||
| 1147 | struct vhost_virtqueue *vq, | 1149 | struct vhost_virtqueue *vq, |
| 1148 | struct vhost_scsi_ctx *vc) | 1150 | struct vhost_scsi_ctx *vc) |
| 1149 | { | 1151 | { |
| 1150 | struct virtio_scsi_ctrl_an_resp __user *resp; | ||
| 1151 | struct virtio_scsi_ctrl_an_resp rsp; | 1152 | struct virtio_scsi_ctrl_an_resp rsp; |
| 1153 | struct iov_iter iov_iter; | ||
| 1152 | int ret; | 1154 | int ret; |
| 1153 | 1155 | ||
| 1154 | pr_debug("%s\n", __func__); | 1156 | pr_debug("%s\n", __func__); |
| 1155 | memset(&rsp, 0, sizeof(rsp)); /* event_actual = 0 */ | 1157 | memset(&rsp, 0, sizeof(rsp)); /* event_actual = 0 */ |
| 1156 | rsp.response = VIRTIO_SCSI_S_OK; | 1158 | rsp.response = VIRTIO_SCSI_S_OK; |
| 1157 | resp = vq->iov[vc->out].iov_base; | 1159 | |
| 1158 | ret = __copy_to_user(resp, &rsp, sizeof(rsp)); | 1160 | iov_iter_init(&iov_iter, READ, &vq->iov[vc->out], vc->in, sizeof(rsp)); |
| 1159 | if (!ret) | 1161 | |
| 1162 | ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); | ||
| 1163 | if (likely(ret == sizeof(rsp))) | ||
| 1160 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); | 1164 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); |
| 1161 | else | 1165 | else |
| 1162 | pr_err("Faulted on virtio_scsi_ctrl_an_resp\n"); | 1166 | pr_err("Faulted on virtio_scsi_ctrl_an_resp\n"); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 9f7942cbcbb2..bac939af8dbb 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -1034,8 +1034,10 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev, | |||
| 1034 | int type, ret; | 1034 | int type, ret; |
| 1035 | 1035 | ||
| 1036 | ret = copy_from_iter(&type, sizeof(type), from); | 1036 | ret = copy_from_iter(&type, sizeof(type), from); |
| 1037 | if (ret != sizeof(type)) | 1037 | if (ret != sizeof(type)) { |
| 1038 | ret = -EINVAL; | ||
| 1038 | goto done; | 1039 | goto done; |
| 1040 | } | ||
| 1039 | 1041 | ||
| 1040 | switch (type) { | 1042 | switch (type) { |
| 1041 | case VHOST_IOTLB_MSG: | 1043 | case VHOST_IOTLB_MSG: |
| @@ -1054,8 +1056,10 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev, | |||
| 1054 | 1056 | ||
| 1055 | iov_iter_advance(from, offset); | 1057 | iov_iter_advance(from, offset); |
| 1056 | ret = copy_from_iter(&msg, sizeof(msg), from); | 1058 | ret = copy_from_iter(&msg, sizeof(msg), from); |
| 1057 | if (ret != sizeof(msg)) | 1059 | if (ret != sizeof(msg)) { |
| 1060 | ret = -EINVAL; | ||
| 1058 | goto done; | 1061 | goto done; |
| 1062 | } | ||
| 1059 | if (vhost_process_iotlb_msg(dev, &msg)) { | 1063 | if (vhost_process_iotlb_msg(dev, &msg)) { |
| 1060 | ret = -EFAULT; | 1064 | ret = -EFAULT; |
| 1061 | goto done; | 1065 | goto done; |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 728ecd1eea30..fb12fe205f86 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
| @@ -61,6 +61,10 @@ enum virtio_balloon_vq { | |||
| 61 | VIRTIO_BALLOON_VQ_MAX | 61 | VIRTIO_BALLOON_VQ_MAX |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | enum virtio_balloon_config_read { | ||
| 65 | VIRTIO_BALLOON_CONFIG_READ_CMD_ID = 0, | ||
| 66 | }; | ||
| 67 | |||
| 64 | struct virtio_balloon { | 68 | struct virtio_balloon { |
| 65 | struct virtio_device *vdev; | 69 | struct virtio_device *vdev; |
| 66 | struct virtqueue *inflate_vq, *deflate_vq, *stats_vq, *free_page_vq; | 70 | struct virtqueue *inflate_vq, *deflate_vq, *stats_vq, *free_page_vq; |
| @@ -77,14 +81,20 @@ struct virtio_balloon { | |||
| 77 | /* Prevent updating balloon when it is being canceled. */ | 81 | /* Prevent updating balloon when it is being canceled. */ |
| 78 | spinlock_t stop_update_lock; | 82 | spinlock_t stop_update_lock; |
| 79 | bool stop_update; | 83 | bool stop_update; |
| 84 | /* Bitmap to indicate if reading the related config fields are needed */ | ||
| 85 | unsigned long config_read_bitmap; | ||
| 80 | 86 | ||
| 81 | /* The list of allocated free pages, waiting to be given back to mm */ | 87 | /* The list of allocated free pages, waiting to be given back to mm */ |
| 82 | struct list_head free_page_list; | 88 | struct list_head free_page_list; |
| 83 | spinlock_t free_page_list_lock; | 89 | spinlock_t free_page_list_lock; |
| 84 | /* The number of free page blocks on the above list */ | 90 | /* The number of free page blocks on the above list */ |
| 85 | unsigned long num_free_page_blocks; | 91 | unsigned long num_free_page_blocks; |
| 86 | /* The cmd id received from host */ | 92 | /* |
| 87 | u32 cmd_id_received; | 93 | * The cmd id received from host. |
| 94 | * Read it via virtio_balloon_cmd_id_received to get the latest value | ||
| 95 | * sent from host. | ||
| 96 | */ | ||
| 97 | u32 cmd_id_received_cache; | ||
| 88 | /* The cmd id that is actively in use */ | 98 | /* The cmd id that is actively in use */ |
| 89 | __virtio32 cmd_id_active; | 99 | __virtio32 cmd_id_active; |
| 90 | /* Buffer to store the stop sign */ | 100 | /* Buffer to store the stop sign */ |
| @@ -390,37 +400,31 @@ static unsigned long return_free_pages_to_mm(struct virtio_balloon *vb, | |||
| 390 | return num_returned; | 400 | return num_returned; |
| 391 | } | 401 | } |
| 392 | 402 | ||
| 403 | static void virtio_balloon_queue_free_page_work(struct virtio_balloon *vb) | ||
| 404 | { | ||
| 405 | if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) | ||
| 406 | return; | ||
| 407 | |||
| 408 | /* No need to queue the work if the bit was already set. */ | ||
| 409 | if (test_and_set_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID, | ||
| 410 | &vb->config_read_bitmap)) | ||
| 411 | return; | ||
| 412 | |||
| 413 | queue_work(vb->balloon_wq, &vb->report_free_page_work); | ||
| 414 | } | ||
| 415 | |||
| 393 | static void virtballoon_changed(struct virtio_device *vdev) | 416 | static void virtballoon_changed(struct virtio_device *vdev) |
| 394 | { | 417 | { |
| 395 | struct virtio_balloon *vb = vdev->priv; | 418 | struct virtio_balloon *vb = vdev->priv; |
| 396 | unsigned long flags; | 419 | unsigned long flags; |
| 397 | s64 diff = towards_target(vb); | ||
| 398 | |||
| 399 | if (diff) { | ||
| 400 | spin_lock_irqsave(&vb->stop_update_lock, flags); | ||
| 401 | if (!vb->stop_update) | ||
| 402 | queue_work(system_freezable_wq, | ||
| 403 | &vb->update_balloon_size_work); | ||
| 404 | spin_unlock_irqrestore(&vb->stop_update_lock, flags); | ||
| 405 | } | ||
| 406 | 420 | ||
| 407 | if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { | 421 | spin_lock_irqsave(&vb->stop_update_lock, flags); |
| 408 | virtio_cread(vdev, struct virtio_balloon_config, | 422 | if (!vb->stop_update) { |
| 409 | free_page_report_cmd_id, &vb->cmd_id_received); | 423 | queue_work(system_freezable_wq, |
| 410 | if (vb->cmd_id_received == VIRTIO_BALLOON_CMD_ID_DONE) { | 424 | &vb->update_balloon_size_work); |
| 411 | /* Pass ULONG_MAX to give back all the free pages */ | 425 | virtio_balloon_queue_free_page_work(vb); |
| 412 | return_free_pages_to_mm(vb, ULONG_MAX); | ||
| 413 | } else if (vb->cmd_id_received != VIRTIO_BALLOON_CMD_ID_STOP && | ||
| 414 | vb->cmd_id_received != | ||
| 415 | virtio32_to_cpu(vdev, vb->cmd_id_active)) { | ||
| 416 | spin_lock_irqsave(&vb->stop_update_lock, flags); | ||
| 417 | if (!vb->stop_update) { | ||
| 418 | queue_work(vb->balloon_wq, | ||
| 419 | &vb->report_free_page_work); | ||
| 420 | } | ||
| 421 | spin_unlock_irqrestore(&vb->stop_update_lock, flags); | ||
| 422 | } | ||
| 423 | } | 426 | } |
| 427 | spin_unlock_irqrestore(&vb->stop_update_lock, flags); | ||
| 424 | } | 428 | } |
| 425 | 429 | ||
| 426 | static void update_balloon_size(struct virtio_balloon *vb) | 430 | static void update_balloon_size(struct virtio_balloon *vb) |
| @@ -527,6 +531,17 @@ static int init_vqs(struct virtio_balloon *vb) | |||
| 527 | return 0; | 531 | return 0; |
| 528 | } | 532 | } |
| 529 | 533 | ||
| 534 | static u32 virtio_balloon_cmd_id_received(struct virtio_balloon *vb) | ||
| 535 | { | ||
| 536 | if (test_and_clear_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID, | ||
| 537 | &vb->config_read_bitmap)) | ||
| 538 | virtio_cread(vb->vdev, struct virtio_balloon_config, | ||
| 539 | free_page_report_cmd_id, | ||
| 540 | &vb->cmd_id_received_cache); | ||
| 541 | |||
| 542 | return vb->cmd_id_received_cache; | ||
| 543 | } | ||
| 544 | |||
| 530 | static int send_cmd_id_start(struct virtio_balloon *vb) | 545 | static int send_cmd_id_start(struct virtio_balloon *vb) |
| 531 | { | 546 | { |
| 532 | struct scatterlist sg; | 547 | struct scatterlist sg; |
| @@ -537,7 +552,8 @@ static int send_cmd_id_start(struct virtio_balloon *vb) | |||
| 537 | while (virtqueue_get_buf(vq, &unused)) | 552 | while (virtqueue_get_buf(vq, &unused)) |
| 538 | ; | 553 | ; |
| 539 | 554 | ||
| 540 | vb->cmd_id_active = cpu_to_virtio32(vb->vdev, vb->cmd_id_received); | 555 | vb->cmd_id_active = virtio32_to_cpu(vb->vdev, |
| 556 | virtio_balloon_cmd_id_received(vb)); | ||
| 541 | sg_init_one(&sg, &vb->cmd_id_active, sizeof(vb->cmd_id_active)); | 557 | sg_init_one(&sg, &vb->cmd_id_active, sizeof(vb->cmd_id_active)); |
| 542 | err = virtqueue_add_outbuf(vq, &sg, 1, &vb->cmd_id_active, GFP_KERNEL); | 558 | err = virtqueue_add_outbuf(vq, &sg, 1, &vb->cmd_id_active, GFP_KERNEL); |
| 543 | if (!err) | 559 | if (!err) |
| @@ -620,7 +636,8 @@ static int send_free_pages(struct virtio_balloon *vb) | |||
| 620 | * stop the reporting. | 636 | * stop the reporting. |
| 621 | */ | 637 | */ |
| 622 | cmd_id_active = virtio32_to_cpu(vb->vdev, vb->cmd_id_active); | 638 | cmd_id_active = virtio32_to_cpu(vb->vdev, vb->cmd_id_active); |
| 623 | if (cmd_id_active != vb->cmd_id_received) | 639 | if (unlikely(cmd_id_active != |
| 640 | virtio_balloon_cmd_id_received(vb))) | ||
| 624 | break; | 641 | break; |
| 625 | 642 | ||
| 626 | /* | 643 | /* |
| @@ -637,11 +654,9 @@ static int send_free_pages(struct virtio_balloon *vb) | |||
| 637 | return 0; | 654 | return 0; |
| 638 | } | 655 | } |
| 639 | 656 | ||
| 640 | static void report_free_page_func(struct work_struct *work) | 657 | static void virtio_balloon_report_free_page(struct virtio_balloon *vb) |
| 641 | { | 658 | { |
| 642 | int err; | 659 | int err; |
| 643 | struct virtio_balloon *vb = container_of(work, struct virtio_balloon, | ||
| 644 | report_free_page_work); | ||
| 645 | struct device *dev = &vb->vdev->dev; | 660 | struct device *dev = &vb->vdev->dev; |
| 646 | 661 | ||
| 647 | /* Start by sending the received cmd id to host with an outbuf. */ | 662 | /* Start by sending the received cmd id to host with an outbuf. */ |
| @@ -659,6 +674,23 @@ static void report_free_page_func(struct work_struct *work) | |||
| 659 | dev_err(dev, "Failed to send a stop id, err = %d\n", err); | 674 | dev_err(dev, "Failed to send a stop id, err = %d\n", err); |
| 660 | } | 675 | } |
| 661 | 676 | ||
| 677 | static void report_free_page_func(struct work_struct *work) | ||
| 678 | { | ||
| 679 | struct virtio_balloon *vb = container_of(work, struct virtio_balloon, | ||
| 680 | report_free_page_work); | ||
| 681 | u32 cmd_id_received; | ||
| 682 | |||
| 683 | cmd_id_received = virtio_balloon_cmd_id_received(vb); | ||
| 684 | if (cmd_id_received == VIRTIO_BALLOON_CMD_ID_DONE) { | ||
| 685 | /* Pass ULONG_MAX to give back all the free pages */ | ||
| 686 | return_free_pages_to_mm(vb, ULONG_MAX); | ||
| 687 | } else if (cmd_id_received != VIRTIO_BALLOON_CMD_ID_STOP && | ||
| 688 | cmd_id_received != | ||
| 689 | virtio32_to_cpu(vb->vdev, vb->cmd_id_active)) { | ||
| 690 | virtio_balloon_report_free_page(vb); | ||
| 691 | } | ||
| 692 | } | ||
| 693 | |||
| 662 | #ifdef CONFIG_BALLOON_COMPACTION | 694 | #ifdef CONFIG_BALLOON_COMPACTION |
| 663 | /* | 695 | /* |
| 664 | * virtballoon_migratepage - perform the balloon page migration on behalf of | 696 | * virtballoon_migratepage - perform the balloon page migration on behalf of |
| @@ -885,7 +917,7 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
| 885 | goto out_del_vqs; | 917 | goto out_del_vqs; |
| 886 | } | 918 | } |
| 887 | INIT_WORK(&vb->report_free_page_work, report_free_page_func); | 919 | INIT_WORK(&vb->report_free_page_work, report_free_page_func); |
| 888 | vb->cmd_id_received = VIRTIO_BALLOON_CMD_ID_STOP; | 920 | vb->cmd_id_received_cache = VIRTIO_BALLOON_CMD_ID_STOP; |
| 889 | vb->cmd_id_active = cpu_to_virtio32(vb->vdev, | 921 | vb->cmd_id_active = cpu_to_virtio32(vb->vdev, |
| 890 | VIRTIO_BALLOON_CMD_ID_STOP); | 922 | VIRTIO_BALLOON_CMD_ID_STOP); |
| 891 | vb->cmd_id_stop = cpu_to_virtio32(vb->vdev, | 923 | vb->cmd_id_stop = cpu_to_virtio32(vb->vdev, |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 4cd9ea5c75be..d9dd0f789279 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
| @@ -468,7 +468,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
| 468 | { | 468 | { |
| 469 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); | 469 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 470 | unsigned int irq = platform_get_irq(vm_dev->pdev, 0); | 470 | unsigned int irq = platform_get_irq(vm_dev->pdev, 0); |
| 471 | int i, err; | 471 | int i, err, queue_idx = 0; |
| 472 | 472 | ||
| 473 | err = request_irq(irq, vm_interrupt, IRQF_SHARED, | 473 | err = request_irq(irq, vm_interrupt, IRQF_SHARED, |
| 474 | dev_name(&vdev->dev), vm_dev); | 474 | dev_name(&vdev->dev), vm_dev); |
| @@ -476,7 +476,12 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
| 476 | return err; | 476 | return err; |
| 477 | 477 | ||
| 478 | for (i = 0; i < nvqs; ++i) { | 478 | for (i = 0; i < nvqs; ++i) { |
| 479 | vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i], | 479 | if (!names[i]) { |
| 480 | vqs[i] = NULL; | ||
| 481 | continue; | ||
| 482 | } | ||
| 483 | |||
| 484 | vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i], | ||
| 480 | ctx ? ctx[i] : false); | 485 | ctx ? ctx[i] : false); |
| 481 | if (IS_ERR(vqs[i])) { | 486 | if (IS_ERR(vqs[i])) { |
| 482 | vm_del_vqs(vdev); | 487 | vm_del_vqs(vdev); |
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 465a6f5142cc..d0584c040c60 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c | |||
| @@ -285,7 +285,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, | |||
| 285 | { | 285 | { |
| 286 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 286 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
| 287 | u16 msix_vec; | 287 | u16 msix_vec; |
| 288 | int i, err, nvectors, allocated_vectors; | 288 | int i, err, nvectors, allocated_vectors, queue_idx = 0; |
| 289 | 289 | ||
| 290 | vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); | 290 | vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); |
| 291 | if (!vp_dev->vqs) | 291 | if (!vp_dev->vqs) |
| @@ -321,7 +321,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, | |||
| 321 | msix_vec = allocated_vectors++; | 321 | msix_vec = allocated_vectors++; |
| 322 | else | 322 | else |
| 323 | msix_vec = VP_MSIX_VQ_VECTOR; | 323 | msix_vec = VP_MSIX_VQ_VECTOR; |
| 324 | vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i], | 324 | vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i], |
| 325 | ctx ? ctx[i] : false, | 325 | ctx ? ctx[i] : false, |
| 326 | msix_vec); | 326 | msix_vec); |
| 327 | if (IS_ERR(vqs[i])) { | 327 | if (IS_ERR(vqs[i])) { |
| @@ -356,7 +356,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, | |||
| 356 | const char * const names[], const bool *ctx) | 356 | const char * const names[], const bool *ctx) |
| 357 | { | 357 | { |
| 358 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 358 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
| 359 | int i, err; | 359 | int i, err, queue_idx = 0; |
| 360 | 360 | ||
| 361 | vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); | 361 | vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); |
| 362 | if (!vp_dev->vqs) | 362 | if (!vp_dev->vqs) |
| @@ -374,7 +374,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, | |||
| 374 | vqs[i] = NULL; | 374 | vqs[i] = NULL; |
| 375 | continue; | 375 | continue; |
| 376 | } | 376 | } |
| 377 | vqs[i] = vp_setup_vq(vdev, i, callbacks[i], names[i], | 377 | vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i], |
| 378 | ctx ? ctx[i] : false, | 378 | ctx ? ctx[i] : false, |
| 379 | VIRTIO_MSI_NO_VECTOR); | 379 | VIRTIO_MSI_NO_VECTOR); |
| 380 | if (IS_ERR(vqs[i])) { | 380 | if (IS_ERR(vqs[i])) { |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 32baf8e26735..987b6491b946 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
| @@ -12,6 +12,11 @@ struct irq_affinity; | |||
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * virtio_config_ops - operations for configuring a virtio device | 14 | * virtio_config_ops - operations for configuring a virtio device |
| 15 | * Note: Do not assume that a transport implements all of the operations | ||
| 16 | * getting/setting a value as a simple read/write! Generally speaking, | ||
| 17 | * any of @get/@set, @get_status/@set_status, or @get_features/ | ||
| 18 | * @finalize_features are NOT safe to be called from an atomic | ||
| 19 | * context. | ||
| 15 | * @get: read the value of a configuration field | 20 | * @get: read the value of a configuration field |
| 16 | * vdev: the virtio_device | 21 | * vdev: the virtio_device |
| 17 | * offset: the offset of the configuration field | 22 | * offset: the offset of the configuration field |
| @@ -22,7 +27,7 @@ struct irq_affinity; | |||
| 22 | * offset: the offset of the configuration field | 27 | * offset: the offset of the configuration field |
| 23 | * buf: the buffer to read the field value from. | 28 | * buf: the buffer to read the field value from. |
| 24 | * len: the length of the buffer | 29 | * len: the length of the buffer |
| 25 | * @generation: config generation counter | 30 | * @generation: config generation counter (optional) |
| 26 | * vdev: the virtio_device | 31 | * vdev: the virtio_device |
| 27 | * Returns the config generation counter | 32 | * Returns the config generation counter |
| 28 | * @get_status: read the status byte | 33 | * @get_status: read the status byte |
| @@ -48,17 +53,17 @@ struct irq_affinity; | |||
| 48 | * @del_vqs: free virtqueues found by find_vqs(). | 53 | * @del_vqs: free virtqueues found by find_vqs(). |
| 49 | * @get_features: get the array of feature bits for this device. | 54 | * @get_features: get the array of feature bits for this device. |
| 50 | * vdev: the virtio_device | 55 | * vdev: the virtio_device |
| 51 | * Returns the first 32 feature bits (all we currently need). | 56 | * Returns the first 64 feature bits (all we currently need). |
| 52 | * @finalize_features: confirm what device features we'll be using. | 57 | * @finalize_features: confirm what device features we'll be using. |
| 53 | * vdev: the virtio_device | 58 | * vdev: the virtio_device |
| 54 | * This gives the final feature bits for the device: it can change | 59 | * This gives the final feature bits for the device: it can change |
| 55 | * the dev->feature bits if it wants. | 60 | * the dev->feature bits if it wants. |
| 56 | * Returns 0 on success or error status | 61 | * Returns 0 on success or error status |
| 57 | * @bus_name: return the bus name associated with the device | 62 | * @bus_name: return the bus name associated with the device (optional) |
| 58 | * vdev: the virtio_device | 63 | * vdev: the virtio_device |
| 59 | * This returns a pointer to the bus name a la pci_name from which | 64 | * This returns a pointer to the bus name a la pci_name from which |
| 60 | * the caller can then copy. | 65 | * the caller can then copy. |
| 61 | * @set_vq_affinity: set the affinity for a virtqueue. | 66 | * @set_vq_affinity: set the affinity for a virtqueue (optional). |
| 62 | * @get_vq_affinity: get the affinity for a virtqueue (optional). | 67 | * @get_vq_affinity: get the affinity for a virtqueue (optional). |
| 63 | */ | 68 | */ |
| 64 | typedef void vq_callback_t(struct virtqueue *); | 69 | typedef void vq_callback_t(struct virtqueue *); |
