Commit e0f121c5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull virtio updates from Michael Tsirkin:
 "Some bug fixes/cleanups.

  The deprecated scsi passthrough for virtio_blk is removed"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  virtio_balloon: Fix memory leaks on errors in virtballoon_probe()
  virtio-balloon: Fix memory leak when unloading while hinting is in progress
  virtio_balloon: prevent pfn array overflow
  virtio-blk: remove VIRTIO_BLK_F_SCSI support
  virtio-pci: check name when counting MSI-X vectors
  virtio-balloon: initialize all vq callbacks
  virtio-mmio: convert to devm_platform_ioremap_resource
parents 9b7fa288 1ad6f58e
CONFIG_VIRTIO_BLK=y CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_SCSI_VIRTIO=y CONFIG_SCSI_VIRTIO=y
CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_NET=y
CONFIG_NET_FAILOVER=y CONFIG_NET_FAILOVER=y
......
...@@ -432,16 +432,6 @@ config VIRTIO_BLK ...@@ -432,16 +432,6 @@ config VIRTIO_BLK
This is the virtual block driver for virtio. It can be used with This is the virtual block driver for virtio. It can be used with
QEMU based VMMs (like KVM or Xen). Say Y or M. QEMU based VMMs (like KVM or Xen). Say Y or M.
config VIRTIO_BLK_SCSI
bool "SCSI passthrough request for the Virtio block driver"
depends on VIRTIO_BLK
select BLK_SCSI_REQUEST
---help---
Enable support for SCSI passthrough (e.g. the SG_IO ioctl) on
virtio-blk devices. This is only supported for the legacy
virtio protocol and not enabled by default by any hypervisor.
You probably want to use virtio-scsi instead.
config BLK_DEV_RBD config BLK_DEV_RBD
tristate "Rados block device (RBD)" tristate "Rados block device (RBD)"
depends on INET && BLOCK depends on INET && BLOCK
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/virtio_blk.h> #include <linux/virtio_blk.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/string_helpers.h> #include <linux/string_helpers.h>
#include <scsi/scsi_cmnd.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/blk-mq.h> #include <linux/blk-mq.h>
#include <linux/blk-mq-virtio.h> #include <linux/blk-mq-virtio.h>
...@@ -56,11 +55,6 @@ struct virtio_blk { ...@@ -56,11 +55,6 @@ struct virtio_blk {
}; };
struct virtblk_req { struct virtblk_req {
#ifdef CONFIG_VIRTIO_BLK_SCSI
struct scsi_request sreq; /* for SCSI passthrough, must be first */
u8 sense[SCSI_SENSE_BUFFERSIZE];
struct virtio_scsi_inhdr in_hdr;
#endif
struct virtio_blk_outhdr out_hdr; struct virtio_blk_outhdr out_hdr;
u8 status; u8 status;
struct scatterlist sg[]; struct scatterlist sg[];
...@@ -78,80 +72,6 @@ static inline blk_status_t virtblk_result(struct virtblk_req *vbr) ...@@ -78,80 +72,6 @@ static inline blk_status_t virtblk_result(struct virtblk_req *vbr)
} }
} }
/*
* If this is a packet command we need a couple of additional headers. Behind
* the normal outhdr we put a segment with the scsi command block, and before
* the normal inhdr we put the sense data and the inhdr with additional status
* information.
*/
#ifdef CONFIG_VIRTIO_BLK_SCSI
static int virtblk_add_req_scsi(struct virtqueue *vq, struct virtblk_req *vbr,
struct scatterlist *data_sg, bool have_data)
{
struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6];
unsigned int num_out = 0, num_in = 0;
sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr));
sgs[num_out++] = &hdr;
sg_init_one(&cmd, vbr->sreq.cmd, vbr->sreq.cmd_len);
sgs[num_out++] = &cmd;
if (have_data) {
if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT))
sgs[num_out++] = data_sg;
else
sgs[num_out + num_in++] = data_sg;
}
sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE);
sgs[num_out + num_in++] = &sense;
sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
sgs[num_out + num_in++] = &inhdr;
sg_init_one(&status, &vbr->status, sizeof(vbr->status));
sgs[num_out + num_in++] = &status;
return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
}
static inline void virtblk_scsi_request_done(struct request *req)
{
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
struct virtio_blk *vblk = req->q->queuedata;
struct scsi_request *sreq = &vbr->sreq;
sreq->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
sreq->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
sreq->result = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
}
static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long data)
{
struct gendisk *disk = bdev->bd_disk;
struct virtio_blk *vblk = disk->private_data;
/*
* Only allow the generic SCSI ioctls if the host can support it.
*/
if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
return -ENOTTY;
return scsi_cmd_blk_ioctl(bdev, mode, cmd,
(void __user *)data);
}
#else
static inline int virtblk_add_req_scsi(struct virtqueue *vq,
struct virtblk_req *vbr, struct scatterlist *data_sg,
bool have_data)
{
return -EIO;
}
static inline void virtblk_scsi_request_done(struct request *req)
{
}
#define virtblk_ioctl NULL
#endif /* CONFIG_VIRTIO_BLK_SCSI */
static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr, static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr,
struct scatterlist *data_sg, bool have_data) struct scatterlist *data_sg, bool have_data)
{ {
...@@ -216,13 +136,6 @@ static inline void virtblk_request_done(struct request *req) ...@@ -216,13 +136,6 @@ static inline void virtblk_request_done(struct request *req)
req->special_vec.bv_offset); req->special_vec.bv_offset);
} }
switch (req_op(req)) {
case REQ_OP_SCSI_IN:
case REQ_OP_SCSI_OUT:
virtblk_scsi_request_done(req);
break;
}
blk_mq_end_request(req, virtblk_result(vbr)); blk_mq_end_request(req, virtblk_result(vbr));
} }
...@@ -299,10 +212,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -299,10 +212,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
type = VIRTIO_BLK_T_WRITE_ZEROES; type = VIRTIO_BLK_T_WRITE_ZEROES;
unmap = !(req->cmd_flags & REQ_NOUNMAP); unmap = !(req->cmd_flags & REQ_NOUNMAP);
break; break;
case REQ_OP_SCSI_IN:
case REQ_OP_SCSI_OUT:
type = VIRTIO_BLK_T_SCSI_CMD;
break;
case REQ_OP_DRV_IN: case REQ_OP_DRV_IN:
type = VIRTIO_BLK_T_GET_ID; type = VIRTIO_BLK_T_GET_ID;
break; break;
...@@ -333,9 +242,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -333,9 +242,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
} }
spin_lock_irqsave(&vblk->vqs[qid].lock, flags); spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
if (blk_rq_is_scsi(req))
err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
else
err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
if (err) { if (err) {
virtqueue_kick(vblk->vqs[qid].vq); virtqueue_kick(vblk->vqs[qid].vq);
...@@ -404,10 +310,6 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) ...@@ -404,10 +310,6 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
} }
static const struct block_device_operations virtblk_fops = { static const struct block_device_operations virtblk_fops = {
.ioctl = virtblk_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = blkdev_compat_ptr_ioctl,
#endif
.owner = THIS_MODULE, .owner = THIS_MODULE,
.getgeo = virtblk_getgeo, .getgeo = virtblk_getgeo,
}; };
...@@ -686,9 +588,6 @@ static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq, ...@@ -686,9 +588,6 @@ static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq,
struct virtio_blk *vblk = set->driver_data; struct virtio_blk *vblk = set->driver_data;
struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq); struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
#ifdef CONFIG_VIRTIO_BLK_SCSI
vbr->sreq.sense = vbr->sense;
#endif
sg_init_table(vbr->sg, vblk->sg_elems); sg_init_table(vbr->sg, vblk->sg_elems);
return 0; return 0;
} }
...@@ -701,23 +600,11 @@ static int virtblk_map_queues(struct blk_mq_tag_set *set) ...@@ -701,23 +600,11 @@ static int virtblk_map_queues(struct blk_mq_tag_set *set)
vblk->vdev, 0); vblk->vdev, 0);
} }
#ifdef CONFIG_VIRTIO_BLK_SCSI
static void virtblk_initialize_rq(struct request *req)
{
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
scsi_req_init(&vbr->sreq);
}
#endif
static const struct blk_mq_ops virtio_mq_ops = { static const struct blk_mq_ops virtio_mq_ops = {
.queue_rq = virtio_queue_rq, .queue_rq = virtio_queue_rq,
.commit_rqs = virtio_commit_rqs, .commit_rqs = virtio_commit_rqs,
.complete = virtblk_request_done, .complete = virtblk_request_done,
.init_request = virtblk_init_request, .init_request = virtblk_init_request,
#ifdef CONFIG_VIRTIO_BLK_SCSI
.initialize_rq_fn = virtblk_initialize_rq,
#endif
.map_queues = virtblk_map_queues, .map_queues = virtblk_map_queues,
}; };
...@@ -994,9 +881,6 @@ static const struct virtio_device_id id_table[] = { ...@@ -994,9 +881,6 @@ static const struct virtio_device_id id_table[] = {
static unsigned int features_legacy[] = { static unsigned int features_legacy[] = {
VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
#ifdef CONFIG_VIRTIO_BLK_SCSI
VIRTIO_BLK_F_SCSI,
#endif
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
} }
......
...@@ -158,6 +158,8 @@ static void set_page_pfns(struct virtio_balloon *vb, ...@@ -158,6 +158,8 @@ static void set_page_pfns(struct virtio_balloon *vb,
{ {
unsigned int i; unsigned int i;
BUILD_BUG_ON(VIRTIO_BALLOON_PAGES_PER_PAGE > VIRTIO_BALLOON_ARRAY_PFNS_MAX);
/* /*
* Set balloon pfns pointing at this page. * Set balloon pfns pointing at this page.
* Note that the first pfn points at start of the page. * Note that the first pfn points at start of the page.
...@@ -475,7 +477,9 @@ static int init_vqs(struct virtio_balloon *vb) ...@@ -475,7 +477,9 @@ static int init_vqs(struct virtio_balloon *vb)
names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate"; names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate";
callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack; callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack;
names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate"; names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate";
callbacks[VIRTIO_BALLOON_VQ_STATS] = NULL;
names[VIRTIO_BALLOON_VQ_STATS] = NULL; names[VIRTIO_BALLOON_VQ_STATS] = NULL;
callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL; names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) { if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
...@@ -899,8 +903,7 @@ static int virtballoon_probe(struct virtio_device *vdev) ...@@ -899,8 +903,7 @@ static int virtballoon_probe(struct virtio_device *vdev)
vb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb); vb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb);
if (IS_ERR(vb->vb_dev_info.inode)) { if (IS_ERR(vb->vb_dev_info.inode)) {
err = PTR_ERR(vb->vb_dev_info.inode); err = PTR_ERR(vb->vb_dev_info.inode);
kern_unmount(balloon_mnt); goto out_kern_unmount;
goto out_del_vqs;
} }
vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops; vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops;
#endif #endif
...@@ -911,13 +914,13 @@ static int virtballoon_probe(struct virtio_device *vdev) ...@@ -911,13 +914,13 @@ static int virtballoon_probe(struct virtio_device *vdev)
*/ */
if (virtqueue_get_vring_size(vb->free_page_vq) < 2) { if (virtqueue_get_vring_size(vb->free_page_vq) < 2) {
err = -ENOSPC; err = -ENOSPC;
goto out_del_vqs; goto out_iput;
} }
vb->balloon_wq = alloc_workqueue("balloon-wq", vb->balloon_wq = alloc_workqueue("balloon-wq",
WQ_FREEZABLE | WQ_CPU_INTENSIVE, 0); WQ_FREEZABLE | WQ_CPU_INTENSIVE, 0);
if (!vb->balloon_wq) { if (!vb->balloon_wq) {
err = -ENOMEM; err = -ENOMEM;
goto out_del_vqs; goto out_iput;
} }
INIT_WORK(&vb->report_free_page_work, report_free_page_func); INIT_WORK(&vb->report_free_page_work, report_free_page_func);
vb->cmd_id_received_cache = VIRTIO_BALLOON_CMD_ID_STOP; vb->cmd_id_received_cache = VIRTIO_BALLOON_CMD_ID_STOP;
...@@ -951,6 +954,12 @@ static int virtballoon_probe(struct virtio_device *vdev) ...@@ -951,6 +954,12 @@ static int virtballoon_probe(struct virtio_device *vdev)
out_del_balloon_wq: out_del_balloon_wq:
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
destroy_workqueue(vb->balloon_wq); destroy_workqueue(vb->balloon_wq);
out_iput:
#ifdef CONFIG_BALLOON_COMPACTION
iput(vb->vb_dev_info.inode);
out_kern_unmount:
kern_unmount(balloon_mnt);
#endif
out_del_vqs: out_del_vqs:
vdev->config->del_vqs(vdev); vdev->config->del_vqs(vdev);
out_free_vb: out_free_vb:
...@@ -966,6 +975,10 @@ static void remove_common(struct virtio_balloon *vb) ...@@ -966,6 +975,10 @@ static void remove_common(struct virtio_balloon *vb)
leak_balloon(vb, vb->num_pages); leak_balloon(vb, vb->num_pages);
update_balloon_size(vb); update_balloon_size(vb);
/* There might be free pages that are being reported: release them. */
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
return_free_pages_to_mm(vb, ULONG_MAX);
/* Now we reset the device so we can clean up the queues. */ /* Now we reset the device so we can clean up the queues. */
vb->vdev->config->reset(vb->vdev); vb->vdev->config->reset(vb->vdev);
......
...@@ -531,18 +531,9 @@ static void virtio_mmio_release_dev(struct device *_d) ...@@ -531,18 +531,9 @@ static void virtio_mmio_release_dev(struct device *_d)
static int virtio_mmio_probe(struct platform_device *pdev) static int virtio_mmio_probe(struct platform_device *pdev)
{ {
struct virtio_mmio_device *vm_dev; struct virtio_mmio_device *vm_dev;
struct resource *mem;
unsigned long magic; unsigned long magic;
int rc; int rc;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
return -EINVAL;
if (!devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem), pdev->name))
return -EBUSY;
vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL);
if (!vm_dev) if (!vm_dev)
return -ENOMEM; return -ENOMEM;
...@@ -554,9 +545,9 @@ static int virtio_mmio_probe(struct platform_device *pdev) ...@@ -554,9 +545,9 @@ static int virtio_mmio_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&vm_dev->virtqueues); INIT_LIST_HEAD(&vm_dev->virtqueues);
spin_lock_init(&vm_dev->lock); spin_lock_init(&vm_dev->lock);
vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
if (vm_dev->base == NULL) if (IS_ERR(vm_dev->base))
return -EFAULT; return PTR_ERR(vm_dev->base);
/* Check magic value */ /* Check magic value */
magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
......
...@@ -294,7 +294,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, ...@@ -294,7 +294,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
/* Best option: one for change interrupt, one per vq. */ /* Best option: one for change interrupt, one per vq. */
nvectors = 1; nvectors = 1;
for (i = 0; i < nvqs; ++i) for (i = 0; i < nvqs; ++i)
if (callbacks[i]) if (names[i] && callbacks[i])
++nvectors; ++nvectors;
} else { } else {
/* Second best: one for change, shared for all vqs. */ /* Second best: one for change, shared for all vqs. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment