diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-08 15:58:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-08 15:58:51 -0500 |
commit | 900add27f55660158e7cac07674882befec49297 (patch) | |
tree | b3537ac60c6ab0001bfe1b3c4ed6c2a20bc82738 | |
parent | 32abeb09abdaa86f42b5ee904fb60bf8012803ad (diff) | |
parent | 03e9f8a05bce7330bcd9c5cc54c8e42d0fcbf993 (diff) |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio bugfixes from Michael Tsirkin:
"A couple of minor bugfixes"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
virtio_net: fix return value check in receive_mergeable()
virtio_mmio: add cleanup for virtio_mmio_remove
virtio_mmio: add cleanup for virtio_mmio_probe
-rw-r--r-- | drivers/net/virtio_net.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_mmio.c | 57 |
2 files changed, 48 insertions, 11 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 19a985ef9104..559b215c0169 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -756,7 +756,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, | |||
756 | int num_skb_frags; | 756 | int num_skb_frags; |
757 | 757 | ||
758 | buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx); | 758 | buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx); |
759 | if (unlikely(!ctx)) { | 759 | if (unlikely(!buf)) { |
760 | pr_debug("%s: rx error: %d buffers out of %d missing\n", | 760 | pr_debug("%s: rx error: %d buffers out of %d missing\n", |
761 | dev->name, num_buf, | 761 | dev->name, num_buf, |
762 | virtio16_to_cpu(vi->vdev, | 762 | virtio16_to_cpu(vi->vdev, |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 74dc7170fd35..a9192fe4f345 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -493,7 +493,16 @@ static const struct virtio_config_ops virtio_mmio_config_ops = { | |||
493 | }; | 493 | }; |
494 | 494 | ||
495 | 495 | ||
496 | static void virtio_mmio_release_dev_empty(struct device *_d) {} | 496 | static void virtio_mmio_release_dev(struct device *_d) |
497 | { | ||
498 | struct virtio_device *vdev = | ||
499 | container_of(_d, struct virtio_device, dev); | ||
500 | struct virtio_mmio_device *vm_dev = | ||
501 | container_of(vdev, struct virtio_mmio_device, vdev); | ||
502 | struct platform_device *pdev = vm_dev->pdev; | ||
503 | |||
504 | devm_kfree(&pdev->dev, vm_dev); | ||
505 | } | ||
497 | 506 | ||
498 | /* Platform device */ | 507 | /* Platform device */ |
499 | 508 | ||
@@ -513,25 +522,30 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
513 | return -EBUSY; | 522 | return -EBUSY; |
514 | 523 | ||
515 | vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); | 524 | vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); |
516 | if (!vm_dev) | 525 | if (!vm_dev) { |
517 | return -ENOMEM; | 526 | rc = -ENOMEM; |
527 | goto free_mem; | ||
528 | } | ||
518 | 529 | ||
519 | vm_dev->vdev.dev.parent = &pdev->dev; | 530 | vm_dev->vdev.dev.parent = &pdev->dev; |
520 | vm_dev->vdev.dev.release = virtio_mmio_release_dev_empty; | 531 | vm_dev->vdev.dev.release = virtio_mmio_release_dev; |
521 | vm_dev->vdev.config = &virtio_mmio_config_ops; | 532 | vm_dev->vdev.config = &virtio_mmio_config_ops; |
522 | vm_dev->pdev = pdev; | 533 | vm_dev->pdev = pdev; |
523 | INIT_LIST_HEAD(&vm_dev->virtqueues); | 534 | INIT_LIST_HEAD(&vm_dev->virtqueues); |
524 | spin_lock_init(&vm_dev->lock); | 535 | spin_lock_init(&vm_dev->lock); |
525 | 536 | ||
526 | vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 537 | vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
527 | if (vm_dev->base == NULL) | 538 | if (vm_dev->base == NULL) { |
528 | return -EFAULT; | 539 | rc = -EFAULT; |
540 | goto free_vmdev; | ||
541 | } | ||
529 | 542 | ||
530 | /* Check magic value */ | 543 | /* Check magic value */ |
531 | magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); | 544 | magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); |
532 | if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { | 545 | if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { |
533 | dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); | 546 | dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); |
534 | return -ENODEV; | 547 | rc = -ENODEV; |
548 | goto unmap; | ||
535 | } | 549 | } |
536 | 550 | ||
537 | /* Check device version */ | 551 | /* Check device version */ |
@@ -539,7 +553,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
539 | if (vm_dev->version < 1 || vm_dev->version > 2) { | 553 | if (vm_dev->version < 1 || vm_dev->version > 2) { |
540 | dev_err(&pdev->dev, "Version %ld not supported!\n", | 554 | dev_err(&pdev->dev, "Version %ld not supported!\n", |
541 | vm_dev->version); | 555 | vm_dev->version); |
542 | return -ENXIO; | 556 | rc = -ENXIO; |
557 | goto unmap; | ||
543 | } | 558 | } |
544 | 559 | ||
545 | vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); | 560 | vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); |
@@ -548,7 +563,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
548 | * virtio-mmio device with an ID 0 is a (dummy) placeholder | 563 | * virtio-mmio device with an ID 0 is a (dummy) placeholder |
549 | * with no function. End probing now with no error reported. | 564 | * with no function. End probing now with no error reported. |
550 | */ | 565 | */ |
551 | return -ENODEV; | 566 | rc = -ENODEV; |
567 | goto unmap; | ||
552 | } | 568 | } |
553 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); | 569 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); |
554 | 570 | ||
@@ -573,13 +589,34 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
573 | 589 | ||
574 | platform_set_drvdata(pdev, vm_dev); | 590 | platform_set_drvdata(pdev, vm_dev); |
575 | 591 | ||
576 | return register_virtio_device(&vm_dev->vdev); | 592 | rc = register_virtio_device(&vm_dev->vdev); |
593 | if (rc) { | ||
594 | iounmap(vm_dev->base); | ||
595 | devm_release_mem_region(&pdev->dev, mem->start, | ||
596 | resource_size(mem)); | ||
597 | put_device(&vm_dev->vdev.dev); | ||
598 | } | ||
599 | return rc; | ||
600 | unmap: | ||
601 | iounmap(vm_dev->base); | ||
602 | free_mem: | ||
603 | devm_release_mem_region(&pdev->dev, mem->start, | ||
604 | resource_size(mem)); | ||
605 | free_vmdev: | ||
606 | devm_kfree(&pdev->dev, vm_dev); | ||
607 | return rc; | ||
577 | } | 608 | } |
578 | 609 | ||
579 | static int virtio_mmio_remove(struct platform_device *pdev) | 610 | static int virtio_mmio_remove(struct platform_device *pdev) |
580 | { | 611 | { |
581 | struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); | 612 | struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); |
613 | struct resource *mem; | ||
582 | 614 | ||
615 | iounmap(vm_dev->base); | ||
616 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
617 | if (mem) | ||
618 | devm_release_mem_region(&pdev->dev, mem->start, | ||
619 | resource_size(mem)); | ||
583 | unregister_virtio_device(&vm_dev->vdev); | 620 | unregister_virtio_device(&vm_dev->vdev); |
584 | 621 | ||
585 | return 0; | 622 | return 0; |