diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
commit | b746f9c7941f227ad582b4f0bc981f3adcbc46b2 (patch) | |
tree | fe3da3dedfe8d66f90cdcfa3d9ce847fdc411c20 /drivers/virtio | |
parent | ce6513f758b1852a2f24f76f07d0fae304d24ad3 (diff) | |
parent | 2bf4fd31394a3f875ea093ee8a209f30b378cbf3 (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.c | 14 | ||||
-rw-r--r-- | drivers/virtio/virtio_mmio.c | 5 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci.c | 3 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 34 |
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 | ||
294 | static int balloon(void *_vballoon) | 292 | static 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 |
517 | static int virtballoon_freeze(struct virtio_device *vdev) | 515 | static 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 */ |
222 | static void vm_notify(struct virtqueue *vq) | 222 | static 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 */ |
200 | static void vp_notify(struct virtqueue *vq) | 200 | static 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 | */ |
432 | void virtqueue_notify(struct virtqueue *_vq) | 436 | bool 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 | } |
439 | EXPORT_SYMBOL_GPL(virtqueue_notify); | 450 | EXPORT_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 | */ |
451 | void virtqueue_kick(struct virtqueue *vq) | 464 | bool 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 | } |
456 | EXPORT_SYMBOL_GPL(virtqueue_kick); | 470 | EXPORT_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 | } |
838 | EXPORT_SYMBOL_GPL(virtqueue_get_vring_size); | 852 | EXPORT_SYMBOL_GPL(virtqueue_get_vring_size); |
839 | 853 | ||
854 | bool virtqueue_is_broken(struct virtqueue *_vq) | ||
855 | { | ||
856 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
857 | |||
858 | return vq->broken; | ||
859 | } | ||
860 | EXPORT_SYMBOL_GPL(virtqueue_is_broken); | ||
861 | |||
840 | MODULE_LICENSE("GPL"); | 862 | MODULE_LICENSE("GPL"); |