aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 23:28:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 23:28:47 -0500
commitb746f9c7941f227ad582b4f0bc981f3adcbc46b2 (patch)
treefe3da3dedfe8d66f90cdcfa3d9ce847fdc411c20 /drivers/virtio
parentce6513f758b1852a2f24f76f07d0fae304d24ad3 (diff)
parent2bf4fd31394a3f875ea093ee8a209f30b378cbf3 (diff)
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio updates from Rusty Russell: "Nothing really exciting: some groundwork for changing virtio endian, and some robustness fixes for broken virtio devices, plus minor tweaks" * tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: virtio_scsi: verify if queue is broken after virtqueue_get_buf() x86, asmlinkage, lguest: Pass in globals into assembler statement virtio: mmio: fix signature checking for BE guests virtio_ring: adapt to notify() returning bool virtio_net: verify if queue is broken after virtqueue_get_buf() virtio_console: verify if queue is broken after virtqueue_get_buf() virtio_blk: verify if queue is broken after virtqueue_get_buf() virtio_ring: add new function virtqueue_is_broken() virtio_test: verify if virtqueue_kick() succeeded virtio_net: verify if virtqueue_kick() succeeded virtio_ring: let virtqueue_{kick()/notify()} return a bool virtio_ring: change host notification API virtio_config: remove virtio_config_val virtio: use size-based config accessors. virtio_config: introduce size-based accessors. virtio_ring: plug kmemleak false positive. virtio: pm: use CONFIG_PM_SLEEP instead of CONFIG_PM
Diffstat (limited to 'drivers/virtio')
-rw-r--r--drivers/virtio/virtio_balloon.c14
-rw-r--r--drivers/virtio/virtio_mmio.c5
-rw-r--r--drivers/virtio/virtio_pci.c3
-rw-r--r--drivers/virtio/virtio_ring.c34
4 files changed, 39 insertions, 17 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 1f572c00a1be..c444654fc33f 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -275,9 +275,8 @@ static inline s64 towards_target(struct virtio_balloon *vb)
275 __le32 v; 275 __le32 v;
276 s64 target; 276 s64 target;
277 277
278 vb->vdev->config->get(vb->vdev, 278 virtio_cread(vb->vdev, struct virtio_balloon_config, num_pages, &v);
279 offsetof(struct virtio_balloon_config, num_pages), 279
280 &v, sizeof(v));
281 target = le32_to_cpu(v); 280 target = le32_to_cpu(v);
282 return target - vb->num_pages; 281 return target - vb->num_pages;
283} 282}
@@ -286,9 +285,8 @@ static void update_balloon_size(struct virtio_balloon *vb)
286{ 285{
287 __le32 actual = cpu_to_le32(vb->num_pages); 286 __le32 actual = cpu_to_le32(vb->num_pages);
288 287
289 vb->vdev->config->set(vb->vdev, 288 virtio_cwrite(vb->vdev, struct virtio_balloon_config, num_pages,
290 offsetof(struct virtio_balloon_config, actual), 289 &actual);
291 &actual, sizeof(actual));
292} 290}
293 291
294static int balloon(void *_vballoon) 292static int balloon(void *_vballoon)
@@ -513,7 +511,7 @@ static void virtballoon_remove(struct virtio_device *vdev)
513 kfree(vb); 511 kfree(vb);
514} 512}
515 513
516#ifdef CONFIG_PM 514#ifdef CONFIG_PM_SLEEP
517static int virtballoon_freeze(struct virtio_device *vdev) 515static int virtballoon_freeze(struct virtio_device *vdev)
518{ 516{
519 struct virtio_balloon *vb = vdev->priv; 517 struct virtio_balloon *vb = vdev->priv;
@@ -556,7 +554,7 @@ static struct virtio_driver virtio_balloon_driver = {
556 .probe = virtballoon_probe, 554 .probe = virtballoon_probe,
557 .remove = virtballoon_remove, 555 .remove = virtballoon_remove,
558 .config_changed = virtballoon_changed, 556 .config_changed = virtballoon_changed,
559#ifdef CONFIG_PM 557#ifdef CONFIG_PM_SLEEP
560 .freeze = virtballoon_freeze, 558 .freeze = virtballoon_freeze,
561 .restore = virtballoon_restore, 559 .restore = virtballoon_restore,
562#endif 560#endif
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 1ba0d6831015..c600ccfd6922 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -219,13 +219,14 @@ static void vm_reset(struct virtio_device *vdev)
219/* Transport interface */ 219/* Transport interface */
220 220
221/* the notify function used when creating a virt queue */ 221/* the notify function used when creating a virt queue */
222static void vm_notify(struct virtqueue *vq) 222static bool vm_notify(struct virtqueue *vq)
223{ 223{
224 struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); 224 struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
225 225
226 /* We write the queue's selector into the notification register to 226 /* We write the queue's selector into the notification register to
227 * signal the other end */ 227 * signal the other end */
228 writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); 228 writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY);
229 return true;
229} 230}
230 231
231/* Notify all virtqueues on an interrupt. */ 232/* Notify all virtqueues on an interrupt. */
@@ -470,7 +471,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
470 471
471 /* Check magic value */ 472 /* Check magic value */
472 magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); 473 magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
473 if (memcmp(&magic, "virt", 4) != 0) { 474 if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
474 dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); 475 dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
475 return -ENODEV; 476 return -ENODEV;
476 } 477 }
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 98917fc872a4..a37c69941d30 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -197,13 +197,14 @@ static void vp_reset(struct virtio_device *vdev)
197} 197}
198 198
199/* the notify function used when creating a virt queue */ 199/* the notify function used when creating a virt queue */
200static void vp_notify(struct virtqueue *vq) 200static bool vp_notify(struct virtqueue *vq)
201{ 201{
202 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); 202 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
203 203
204 /* we write the queue's selector into the notification register to 204 /* we write the queue's selector into the notification register to
205 * signal the other end */ 205 * signal the other end */
206 iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); 206 iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
207 return true;
207} 208}
208 209
209/* Handle a configuration change: Tell driver if it wants to know. */ 210/* Handle a configuration change: Tell driver if it wants to know. */
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 6b4a4db4404d..28b5338fff71 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -81,7 +81,7 @@ struct vring_virtqueue
81 u16 last_used_idx; 81 u16 last_used_idx;
82 82
83 /* How to notify other side. FIXME: commonalize hcalls! */ 83 /* How to notify other side. FIXME: commonalize hcalls! */
84 void (*notify)(struct virtqueue *vq); 84 bool (*notify)(struct virtqueue *vq);
85 85
86#ifdef DEBUG 86#ifdef DEBUG
87 /* They're supposed to lock for us. */ 87 /* They're supposed to lock for us. */
@@ -173,6 +173,8 @@ static inline int vring_add_indirect(struct vring_virtqueue *vq,
173 head = vq->free_head; 173 head = vq->free_head;
174 vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT; 174 vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
175 vq->vring.desc[head].addr = virt_to_phys(desc); 175 vq->vring.desc[head].addr = virt_to_phys(desc);
176 /* kmemleak gives a false positive, as it's hidden by virt_to_phys */
177 kmemleak_ignore(desc);
176 vq->vring.desc[head].len = i * sizeof(struct vring_desc); 178 vq->vring.desc[head].len = i * sizeof(struct vring_desc);
177 179
178 /* Update free pointer */ 180 /* Update free pointer */
@@ -428,13 +430,22 @@ EXPORT_SYMBOL_GPL(virtqueue_kick_prepare);
428 * @vq: the struct virtqueue 430 * @vq: the struct virtqueue
429 * 431 *
430 * This does not need to be serialized. 432 * This does not need to be serialized.
433 *
434 * Returns false if host notify failed or queue is broken, otherwise true.
431 */ 435 */
432void virtqueue_notify(struct virtqueue *_vq) 436bool virtqueue_notify(struct virtqueue *_vq)
433{ 437{
434 struct vring_virtqueue *vq = to_vvq(_vq); 438 struct vring_virtqueue *vq = to_vvq(_vq);
435 439
440 if (unlikely(vq->broken))
441 return false;
442
436 /* Prod other side to tell it about changes. */ 443 /* Prod other side to tell it about changes. */
437 vq->notify(_vq); 444 if (!vq->notify(_vq)) {
445 vq->broken = true;
446 return false;
447 }
448 return true;
438} 449}
439EXPORT_SYMBOL_GPL(virtqueue_notify); 450EXPORT_SYMBOL_GPL(virtqueue_notify);
440 451
@@ -447,11 +458,14 @@ EXPORT_SYMBOL_GPL(virtqueue_notify);
447 * 458 *
448 * Caller must ensure we don't call this with other virtqueue 459 * Caller must ensure we don't call this with other virtqueue
449 * operations at the same time (except where noted). 460 * operations at the same time (except where noted).
461 *
462 * Returns false if kick failed, otherwise true.
450 */ 463 */
451void virtqueue_kick(struct virtqueue *vq) 464bool virtqueue_kick(struct virtqueue *vq)
452{ 465{
453 if (virtqueue_kick_prepare(vq)) 466 if (virtqueue_kick_prepare(vq))
454 virtqueue_notify(vq); 467 return virtqueue_notify(vq);
468 return true;
455} 469}
456EXPORT_SYMBOL_GPL(virtqueue_kick); 470EXPORT_SYMBOL_GPL(virtqueue_kick);
457 471
@@ -742,7 +756,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
742 struct virtio_device *vdev, 756 struct virtio_device *vdev,
743 bool weak_barriers, 757 bool weak_barriers,
744 void *pages, 758 void *pages,
745 void (*notify)(struct virtqueue *), 759 bool (*notify)(struct virtqueue *),
746 void (*callback)(struct virtqueue *), 760 void (*callback)(struct virtqueue *),
747 const char *name) 761 const char *name)
748{ 762{
@@ -837,4 +851,12 @@ unsigned int virtqueue_get_vring_size(struct virtqueue *_vq)
837} 851}
838EXPORT_SYMBOL_GPL(virtqueue_get_vring_size); 852EXPORT_SYMBOL_GPL(virtqueue_get_vring_size);
839 853
854bool virtqueue_is_broken(struct virtqueue *_vq)
855{
856 struct vring_virtqueue *vq = to_vvq(_vq);
857
858 return vq->broken;
859}
860EXPORT_SYMBOL_GPL(virtqueue_is_broken);
861
840MODULE_LICENSE("GPL"); 862MODULE_LICENSE("GPL");