Skip to content

Commit 5c02c39

Browse files
committed
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio updates from Rusty Russell: "Main excitement is a virtio_scsi fix for alloc holding spinlock on the abort path, which I refuse to CC stable since (1) I discovered it myself, and (2) it's been there forever with no reports" * tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: virtio_scsi: don't call virtqueue_add_sgs(... GFP_NOIO) holding spinlock. virtio-rng: fixes for device registration/unregistration virtio-rng: fix boot with virtio-rng device virtio-rng: support multiple virtio-rng devices virtio_ccw: introduce device_lost in virtio_ccw_device virtio: virtio_break_device() to mark all virtqueues broken.
2 parents 3c81bdd + c77fba9 commit 5c02c39

File tree

5 files changed

+127
-59
lines changed

5 files changed

+127
-59
lines changed

drivers/char/hw_random/virtio-rng.c

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,88 +25,115 @@
2525
#include <linux/virtio_rng.h>
2626
#include <linux/module.h>
2727

28-
static struct virtqueue *vq;
29-
static unsigned int data_avail;
30-
static DECLARE_COMPLETION(have_data);
31-
static bool busy;
28+
static DEFINE_IDA(rng_index_ida);
29+
30+
struct virtrng_info {
31+
struct virtio_device *vdev;
32+
struct hwrng hwrng;
33+
struct virtqueue *vq;
34+
unsigned int data_avail;
35+
struct completion have_data;
36+
bool busy;
37+
char name[25];
38+
int index;
39+
};
3240

3341
static void random_recv_done(struct virtqueue *vq)
3442
{
43+
struct virtrng_info *vi = vq->vdev->priv;
44+
3545
/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
36-
if (!virtqueue_get_buf(vq, &data_avail))
46+
if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
3747
return;
3848

39-
complete(&have_data);
49+
complete(&vi->have_data);
4050
}
4151

4252
/* The host will fill any buffer we give it with sweet, sweet randomness. */
43-
static void register_buffer(u8 *buf, size_t size)
53+
static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
4454
{
4555
struct scatterlist sg;
4656

4757
sg_init_one(&sg, buf, size);
4858

4959
/* There should always be room for one buffer. */
50-
virtqueue_add_inbuf(vq, &sg, 1, buf, GFP_KERNEL);
60+
virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL);
5161

52-
virtqueue_kick(vq);
62+
virtqueue_kick(vi->vq);
5363
}
5464

5565
static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
5666
{
5767
int ret;
68+
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
5869

59-
if (!busy) {
60-
busy = true;
61-
init_completion(&have_data);
62-
register_buffer(buf, size);
70+
if (!vi->busy) {
71+
vi->busy = true;
72+
init_completion(&vi->have_data);
73+
register_buffer(vi, buf, size);
6374
}
6475

6576
if (!wait)
6677
return 0;
6778

68-
ret = wait_for_completion_killable(&have_data);
79+
ret = wait_for_completion_killable(&vi->have_data);
6980
if (ret < 0)
7081
return ret;
7182

72-
busy = false;
83+
vi->busy = false;
7384

74-
return data_avail;
85+
return vi->data_avail;
7586
}
7687

7788
static void virtio_cleanup(struct hwrng *rng)
7889
{
79-
if (busy)
80-
wait_for_completion(&have_data);
81-
}
90+
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
8291

83-
84-
static struct hwrng virtio_hwrng = {
85-
.name = "virtio",
86-
.cleanup = virtio_cleanup,
87-
.read = virtio_read,
88-
};
92+
if (vi->busy)
93+
wait_for_completion(&vi->have_data);
94+
}
8995

9096
static int probe_common(struct virtio_device *vdev)
9197
{
92-
int err;
98+
int err, index;
99+
struct virtrng_info *vi = NULL;
100+
101+
vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
102+
if (!vi)
103+
return -ENOMEM;
93104

94-
if (vq) {
95-
/* We only support one device for now */
96-
return -EBUSY;
105+
vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
106+
if (index < 0) {
107+
kfree(vi);
108+
return index;
97109
}
110+
sprintf(vi->name, "virtio_rng.%d", index);
111+
init_completion(&vi->have_data);
112+
113+
vi->hwrng = (struct hwrng) {
114+
.read = virtio_read,
115+
.cleanup = virtio_cleanup,
116+
.priv = (unsigned long)vi,
117+
.name = vi->name,
118+
};
119+
vdev->priv = vi;
120+
98121
/* We expect a single virtqueue. */
99-
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
100-
if (IS_ERR(vq)) {
101-
err = PTR_ERR(vq);
102-
vq = NULL;
122+
vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
123+
if (IS_ERR(vi->vq)) {
124+
err = PTR_ERR(vi->vq);
125+
vi->vq = NULL;
126+
kfree(vi);
127+
ida_simple_remove(&rng_index_ida, index);
103128
return err;
104129
}
105130

106-
err = hwrng_register(&virtio_hwrng);
131+
err = hwrng_register(&vi->hwrng);
107132
if (err) {
108133
vdev->config->del_vqs(vdev);
109-
vq = NULL;
134+
vi->vq = NULL;
135+
kfree(vi);
136+
ida_simple_remove(&rng_index_ida, index);
110137
return err;
111138
}
112139

@@ -115,11 +142,13 @@ static int probe_common(struct virtio_device *vdev)
115142

116143
static void remove_common(struct virtio_device *vdev)
117144
{
145+
struct virtrng_info *vi = vdev->priv;
118146
vdev->config->reset(vdev);
119-
busy = false;
120-
hwrng_unregister(&virtio_hwrng);
147+
vi->busy = false;
148+
hwrng_unregister(&vi->hwrng);
121149
vdev->config->del_vqs(vdev);
122-
vq = NULL;
150+
ida_simple_remove(&rng_index_ida, vi->index);
151+
kfree(vi);
123152
}
124153

125154
static int virtrng_probe(struct virtio_device *vdev)

drivers/s390/kvm/virtio_ccw.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <linux/module.h>
2828
#include <linux/io.h>
2929
#include <linux/kvm_para.h>
30+
#include <linux/notifier.h>
3031
#include <asm/setup.h>
3132
#include <asm/irq.h>
3233
#include <asm/cio.h>
@@ -62,6 +63,7 @@ struct virtio_ccw_device {
6263
struct vq_config_block *config_block;
6364
bool is_thinint;
6465
bool going_away;
66+
bool device_lost;
6567
void *airq_info;
6668
};
6769

@@ -1010,11 +1012,14 @@ static void virtio_ccw_remove(struct ccw_device *cdev)
10101012
unsigned long flags;
10111013
struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
10121014

1013-
if (vcdev && cdev->online)
1015+
if (vcdev && cdev->online) {
1016+
if (vcdev->device_lost)
1017+
virtio_break_device(&vcdev->vdev);
10141018
unregister_virtio_device(&vcdev->vdev);
1015-
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1016-
dev_set_drvdata(&cdev->dev, NULL);
1017-
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1019+
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1020+
dev_set_drvdata(&cdev->dev, NULL);
1021+
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1022+
}
10181023
cdev->handler = NULL;
10191024
}
10201025

@@ -1023,12 +1028,14 @@ static int virtio_ccw_offline(struct ccw_device *cdev)
10231028
unsigned long flags;
10241029
struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
10251030

1026-
if (vcdev) {
1027-
unregister_virtio_device(&vcdev->vdev);
1028-
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1029-
dev_set_drvdata(&cdev->dev, NULL);
1030-
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1031-
}
1031+
if (!vcdev)
1032+
return 0;
1033+
if (vcdev->device_lost)
1034+
virtio_break_device(&vcdev->vdev);
1035+
unregister_virtio_device(&vcdev->vdev);
1036+
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1037+
dev_set_drvdata(&cdev->dev, NULL);
1038+
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
10321039
return 0;
10331040
}
10341041

@@ -1096,8 +1103,26 @@ static int virtio_ccw_online(struct ccw_device *cdev)
10961103

10971104
static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event)
10981105
{
1099-
/* TODO: Check whether we need special handling here. */
1100-
return 0;
1106+
int rc;
1107+
struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
1108+
1109+
/*
1110+
* Make sure vcdev is set
1111+
* i.e. set_offline/remove callback not already running
1112+
*/
1113+
if (!vcdev)
1114+
return NOTIFY_DONE;
1115+
1116+
switch (event) {
1117+
case CIO_GONE:
1118+
vcdev->device_lost = true;
1119+
rc = NOTIFY_DONE;
1120+
break;
1121+
default:
1122+
rc = NOTIFY_DONE;
1123+
break;
1124+
}
1125+
return rc;
11011126
}
11021127

11031128
static struct ccw_device_id virtio_ids[] = {

drivers/scsi/virtio_scsi.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,10 @@ static void virtscsi_event_done(struct virtqueue *vq)
393393
* @cmd : command structure
394394
* @req_size : size of the request buffer
395395
* @resp_size : size of the response buffer
396-
* @gfp : flags to use for memory allocations
397396
*/
398397
static int virtscsi_add_cmd(struct virtqueue *vq,
399398
struct virtio_scsi_cmd *cmd,
400-
size_t req_size, size_t resp_size, gfp_t gfp)
399+
size_t req_size, size_t resp_size)
401400
{
402401
struct scsi_cmnd *sc = cmd->sc;
403402
struct scatterlist *sgs[4], req, resp;
@@ -429,19 +428,19 @@ static int virtscsi_add_cmd(struct virtqueue *vq,
429428
if (in)
430429
sgs[out_num + in_num++] = in->sgl;
431430

432-
return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, gfp);
431+
return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, GFP_ATOMIC);
433432
}
434433

435434
static int virtscsi_kick_cmd(struct virtio_scsi_vq *vq,
436435
struct virtio_scsi_cmd *cmd,
437-
size_t req_size, size_t resp_size, gfp_t gfp)
436+
size_t req_size, size_t resp_size)
438437
{
439438
unsigned long flags;
440439
int err;
441440
bool needs_kick = false;
442441

443442
spin_lock_irqsave(&vq->vq_lock, flags);
444-
err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size, gfp);
443+
err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size);
445444
if (!err)
446445
needs_kick = virtqueue_kick_prepare(vq->vq);
447446

@@ -484,8 +483,7 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
484483
memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len);
485484

486485
if (virtscsi_kick_cmd(req_vq, cmd,
487-
sizeof cmd->req.cmd, sizeof cmd->resp.cmd,
488-
GFP_ATOMIC) != 0)
486+
sizeof cmd->req.cmd, sizeof cmd->resp.cmd) != 0)
489487
return SCSI_MLQUEUE_HOST_BUSY;
490488
return 0;
491489
}
@@ -542,8 +540,7 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
542540

543541
cmd->comp = &comp;
544542
if (virtscsi_kick_cmd(&vscsi->ctrl_vq, cmd,
545-
sizeof cmd->req.tmf, sizeof cmd->resp.tmf,
546-
GFP_NOIO) < 0)
543+
sizeof cmd->req.tmf, sizeof cmd->resp.tmf) < 0)
547544
goto out;
548545

549546
wait_for_completion(&comp);

drivers/virtio/virtio_ring.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,4 +865,19 @@ bool virtqueue_is_broken(struct virtqueue *_vq)
865865
}
866866
EXPORT_SYMBOL_GPL(virtqueue_is_broken);
867867

868+
/*
869+
* This should prevent the device from being used, allowing drivers to
870+
* recover. You may need to grab appropriate locks to flush.
871+
*/
872+
void virtio_break_device(struct virtio_device *dev)
873+
{
874+
struct virtqueue *_vq;
875+
876+
list_for_each_entry(_vq, &dev->vqs, list) {
877+
struct vring_virtqueue *vq = to_vvq(_vq);
878+
vq->broken = true;
879+
}
880+
}
881+
EXPORT_SYMBOL_GPL(virtio_break_device);
882+
868883
MODULE_LICENSE("GPL");

include/linux/virtio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ static inline struct virtio_device *dev_to_virtio(struct device *_dev)
106106
int register_virtio_device(struct virtio_device *dev);
107107
void unregister_virtio_device(struct virtio_device *dev);
108108

109+
void virtio_break_device(struct virtio_device *dev);
110+
109111
/**
110112
* virtio_driver - operations for a virtio I/O driver
111113
* @driver: underlying device driver (populate name and owner).

0 commit comments

Comments
 (0)