Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+310 -166
+37 -46
drivers/block/virtio_blk.c
··· 292 292 req_done = true; 293 293 } 294 294 } 295 + if (unlikely(virtqueue_is_broken(vq))) 296 + break; 295 297 } while (!virtqueue_enable_cb(vq)); 296 298 /* In case queue is stopped waiting for more buffers. */ 297 299 if (req_done) ··· 458 456 static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 459 457 { 460 458 struct virtio_blk *vblk = bd->bd_disk->private_data; 461 - struct virtio_blk_geometry vgeo; 462 - int err; 463 459 464 460 /* see if the host passed in geometry config */ 465 - err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, 466 - offsetof(struct virtio_blk_config, geometry), 467 - &vgeo); 468 - 469 - if (!err) { 470 - geo->heads = vgeo.heads; 471 - geo->sectors = vgeo.sectors; 472 - geo->cylinders = vgeo.cylinders; 461 + if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GEOMETRY)) { 462 + virtio_cread(vblk->vdev, struct virtio_blk_config, 463 + geometry.cylinders, &geo->cylinders); 464 + virtio_cread(vblk->vdev, struct virtio_blk_config, 465 + geometry.heads, &geo->heads); 466 + virtio_cread(vblk->vdev, struct virtio_blk_config, 467 + geometry.sectors, &geo->sectors); 473 468 } else { 474 469 /* some standard values, similar to sd */ 475 470 geo->heads = 1 << 6; ··· 528 529 goto done; 529 530 530 531 /* Host must always specify the capacity. */ 531 - vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 532 - &capacity, sizeof(capacity)); 532 + virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity); 533 533 534 534 /* If capacity is too big, truncate with warning. */ 535 535 if ((sector_t)capacity != capacity) { ··· 606 608 u8 writeback; 607 609 int err; 608 610 609 - err = virtio_config_val(vdev, VIRTIO_BLK_F_CONFIG_WCE, 610 - offsetof(struct virtio_blk_config, wce), 611 - &writeback); 611 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE, 612 + struct virtio_blk_config, wce, 613 + &writeback); 612 614 if (err) 613 615 writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); 614 616 ··· 640 642 struct virtio_blk *vblk = disk->private_data; 641 643 struct virtio_device *vdev = vblk->vdev; 642 644 int i; 643 - u8 writeback; 644 645 645 646 BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE)); 646 647 for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; ) ··· 649 652 if (i < 0) 650 653 return -EINVAL; 651 654 652 - writeback = i; 653 - vdev->config->set(vdev, 654 - offsetof(struct virtio_blk_config, wce), 655 - &writeback, sizeof(writeback)); 656 - 655 + virtio_cwrite8(vdev, offsetof(struct virtio_blk_config, wce), i); 657 656 virtblk_update_cache_mode(vdev); 658 657 return count; 659 658 } ··· 692 699 index = err; 693 700 694 701 /* We need to know how many segments before we allocate. */ 695 - err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, 696 - offsetof(struct virtio_blk_config, seg_max), 697 - &sg_elems); 702 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SEG_MAX, 703 + struct virtio_blk_config, seg_max, 704 + &sg_elems); 698 705 699 706 /* We need at least one SG element, whatever they say. */ 700 707 if (err || !sg_elems) ··· 765 772 set_disk_ro(vblk->disk, 1); 766 773 767 774 /* Host must always specify the capacity. */ 768 - vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 769 - &cap, sizeof(cap)); 775 + virtio_cread(vdev, struct virtio_blk_config, capacity, &cap); 770 776 771 777 /* If capacity is too big, truncate with warning. */ 772 778 if ((sector_t)cap != cap) { ··· 786 794 787 795 /* Host can optionally specify maximum segment size and number of 788 796 * segments. */ 789 - err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, 790 - offsetof(struct virtio_blk_config, size_max), 791 - &v); 797 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, 798 + struct virtio_blk_config, size_max, &v); 792 799 if (!err) 793 800 blk_queue_max_segment_size(q, v); 794 801 else 795 802 blk_queue_max_segment_size(q, -1U); 796 803 797 804 /* Host can optionally specify the block size of the device */ 798 - err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, 799 - offsetof(struct virtio_blk_config, blk_size), 800 - &blk_size); 805 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE, 806 + struct virtio_blk_config, blk_size, 807 + &blk_size); 801 808 if (!err) 802 809 blk_queue_logical_block_size(q, blk_size); 803 810 else 804 811 blk_size = queue_logical_block_size(q); 805 812 806 813 /* Use topology information if available */ 807 - err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 808 - offsetof(struct virtio_blk_config, physical_block_exp), 809 - &physical_block_exp); 814 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, 815 + struct virtio_blk_config, physical_block_exp, 816 + &physical_block_exp); 810 817 if (!err && physical_block_exp) 811 818 blk_queue_physical_block_size(q, 812 819 blk_size * (1 << physical_block_exp)); 813 820 814 - err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 815 - offsetof(struct virtio_blk_config, alignment_offset), 816 - &alignment_offset); 821 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, 822 + struct virtio_blk_config, alignment_offset, 823 + &alignment_offset); 817 824 if (!err && alignment_offset) 818 825 blk_queue_alignment_offset(q, blk_size * alignment_offset); 819 826 820 - err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 821 - offsetof(struct virtio_blk_config, min_io_size), 822 - &min_io_size); 827 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, 828 + struct virtio_blk_config, min_io_size, 829 + &min_io_size); 823 830 if (!err && min_io_size) 824 831 blk_queue_io_min(q, blk_size * min_io_size); 825 832 826 - err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 827 - offsetof(struct virtio_blk_config, opt_io_size), 828 - &opt_io_size); 833 + err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, 834 + struct virtio_blk_config, opt_io_size, 835 + &opt_io_size); 829 836 if (!err && opt_io_size) 830 837 blk_queue_io_opt(q, blk_size * opt_io_size); 831 838 ··· 890 899 ida_simple_remove(&vd_index_ida, index); 891 900 } 892 901 893 - #ifdef CONFIG_PM 902 + #ifdef CONFIG_PM_SLEEP 894 903 static int virtblk_freeze(struct virtio_device *vdev) 895 904 { 896 905 struct virtio_blk *vblk = vdev->priv; ··· 950 959 .probe = virtblk_probe, 951 960 .remove = virtblk_remove, 952 961 .config_changed = virtblk_config_changed, 953 - #ifdef CONFIG_PM 962 + #ifdef CONFIG_PM_SLEEP 954 963 .freeze = virtblk_freeze, 955 964 .restore = virtblk_restore, 956 965 #endif
+2 -2
drivers/char/hw_random/virtio-rng.c
··· 133 133 remove_common(vdev); 134 134 } 135 135 136 - #ifdef CONFIG_PM 136 + #ifdef CONFIG_PM_SLEEP 137 137 static int virtrng_freeze(struct virtio_device *vdev) 138 138 { 139 139 remove_common(vdev); ··· 157 157 .id_table = id_table, 158 158 .probe = virtrng_probe, 159 159 .remove = virtrng_remove, 160 - #ifdef CONFIG_PM 160 + #ifdef CONFIG_PM_SLEEP 161 161 .freeze = virtrng_freeze, 162 162 .restore = virtrng_restore, 163 163 #endif
+11 -14
drivers/char/virtio_console.c
··· 577 577 spin_lock(&portdev->c_ovq_lock); 578 578 if (virtqueue_add_outbuf(vq, sg, 1, &cpkt, GFP_ATOMIC) == 0) { 579 579 virtqueue_kick(vq); 580 - while (!virtqueue_get_buf(vq, &len)) 580 + while (!virtqueue_get_buf(vq, &len) 581 + && !virtqueue_is_broken(vq)) 581 582 cpu_relax(); 582 583 } 583 584 spin_unlock(&portdev->c_ovq_lock); ··· 651 650 * we need to kmalloc a GFP_ATOMIC buffer each time the 652 651 * console driver writes something out. 653 652 */ 654 - while (!virtqueue_get_buf(out_vq, &len)) 653 + while (!virtqueue_get_buf(out_vq, &len) 654 + && !virtqueue_is_broken(out_vq)) 655 655 cpu_relax(); 656 656 done: 657 657 spin_unlock_irqrestore(&port->outvq_lock, flags); ··· 1839 1837 struct port *port; 1840 1838 u16 rows, cols; 1841 1839 1842 - vdev->config->get(vdev, 1843 - offsetof(struct virtio_console_config, cols), 1844 - &cols, sizeof(u16)); 1845 - vdev->config->get(vdev, 1846 - offsetof(struct virtio_console_config, rows), 1847 - &rows, sizeof(u16)); 1840 + virtio_cread(vdev, struct virtio_console_config, cols, &cols); 1841 + virtio_cread(vdev, struct virtio_console_config, rows, &rows); 1848 1842 1849 1843 port = find_port_by_id(portdev, 0); 1850 1844 set_console_size(port, rows, cols); ··· 2012 2014 2013 2015 /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ 2014 2016 if (!is_rproc_serial(vdev) && 2015 - virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, 2016 - offsetof(struct virtio_console_config, 2017 - max_nr_ports), 2018 - &portdev->config.max_nr_ports) == 0) { 2017 + virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT, 2018 + struct virtio_console_config, max_nr_ports, 2019 + &portdev->config.max_nr_ports) == 0) { 2019 2020 multiport = true; 2020 2021 } 2021 2022 ··· 2139 2142 static unsigned int rproc_serial_features[] = { 2140 2143 }; 2141 2144 2142 - #ifdef CONFIG_PM 2145 + #ifdef CONFIG_PM_SLEEP 2143 2146 static int virtcons_freeze(struct virtio_device *vdev) 2144 2147 { 2145 2148 struct ports_device *portdev; ··· 2217 2220 .probe = virtcons_probe, 2218 2221 .remove = virtcons_remove, 2219 2222 .config_changed = config_intr, 2220 - #ifdef CONFIG_PM 2223 + #ifdef CONFIG_PM_SLEEP 2221 2224 .freeze = virtcons_freeze, 2222 2225 .restore = virtcons_restore, 2223 2226 #endif
+2 -1
drivers/lguest/lguest_device.c
··· 229 229 * make a hypercall. We hand the physical address of the virtqueue so the Host 230 230 * knows which virtqueue we're talking about. 231 231 */ 232 - static void lg_notify(struct virtqueue *vq) 232 + static bool lg_notify(struct virtqueue *vq) 233 233 { 234 234 /* 235 235 * We store our virtqueue information in the "priv" pointer of the ··· 238 238 struct lguest_vq_info *lvq = vq->priv; 239 239 240 240 hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0); 241 + return true; 241 242 } 242 243 243 244 /* An extern declaration inside a C file is bad form. Don't do it. */
+4 -2
drivers/lguest/x86/core.c
··· 157 157 * stack, then the address of this call. This stack layout happens to 158 158 * exactly match the stack layout created by an interrupt... 159 159 */ 160 - asm volatile("pushf; lcall *lguest_entry" 160 + asm volatile("pushf; lcall *%4" 161 161 /* 162 162 * This is how we tell GCC that %eax ("a") and %ebx ("b") 163 163 * are changed by this routine. The "=" means output. ··· 169 169 * physical address of the Guest's top-level page 170 170 * directory. 171 171 */ 172 - : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)) 172 + : "0"(pages), 173 + "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)), 174 + "m"(lguest_entry) 173 175 /* 174 176 * We tell gcc that all these registers could change, 175 177 * which means we don't have to save and restore them in
+12 -11
drivers/net/caif/caif_virtio.c
··· 686 686 goto err; 687 687 688 688 /* Get the CAIF configuration from virtio config space, if available */ 689 - #define GET_VIRTIO_CONFIG_OPS(_v, _var, _f) \ 690 - ((_v)->config->get(_v, offsetof(struct virtio_caif_transf_config, _f), \ 691 - &_var, \ 692 - FIELD_SIZEOF(struct virtio_caif_transf_config, _f))) 693 - 694 689 if (vdev->config->get) { 695 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_hr, headroom); 696 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_hr, headroom); 697 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_tr, tailroom); 698 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_tr, tailroom); 699 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->mtu, mtu); 700 - GET_VIRTIO_CONFIG_OPS(vdev, cfv->mru, mtu); 690 + virtio_cread(vdev, struct virtio_caif_transf_config, headroom, 691 + &cfv->tx_hr); 692 + virtio_cread(vdev, struct virtio_caif_transf_config, headroom, 693 + &cfv->rx_hr); 694 + virtio_cread(vdev, struct virtio_caif_transf_config, tailroom, 695 + &cfv->tx_tr); 696 + virtio_cread(vdev, struct virtio_caif_transf_config, tailroom, 697 + &cfv->rx_tr); 698 + virtio_cread(vdev, struct virtio_caif_transf_config, mtu, 699 + &cfv->mtu); 700 + virtio_cread(vdev, struct virtio_caif_transf_config, mtu, 701 + &cfv->mru); 701 702 } else { 702 703 cfv->tx_hr = CFV_DEF_HEADROOM; 703 704 cfv->rx_hr = CFV_DEF_HEADROOM;
+26 -18
drivers/net/virtio_net.c
··· 591 591 } while (rq->vq->num_free); 592 592 if (unlikely(rq->num > rq->max)) 593 593 rq->max = rq->num; 594 - virtqueue_kick(rq->vq); 594 + if (unlikely(!virtqueue_kick(rq->vq))) 595 + return false; 595 596 return !oom; 596 597 } 597 598 ··· 798 797 err = xmit_skb(sq, skb); 799 798 800 799 /* This should not happen! */ 801 - if (unlikely(err)) { 800 + if (unlikely(err) || unlikely(!virtqueue_kick(sq->vq))) { 802 801 dev->stats.tx_fifo_errors++; 803 802 if (net_ratelimit()) 804 803 dev_warn(&dev->dev, ··· 807 806 kfree_skb(skb); 808 807 return NETDEV_TX_OK; 809 808 } 810 - virtqueue_kick(sq->vq); 811 809 812 810 /* Don't wait up for transmitted skbs to be freed. */ 813 811 skb_orphan(skb); ··· 865 865 BUG_ON(virtqueue_add_sgs(vi->cvq, sgs, out_num, in_num, vi, GFP_ATOMIC) 866 866 < 0); 867 867 868 - virtqueue_kick(vi->cvq); 868 + if (unlikely(!virtqueue_kick(vi->cvq))) 869 + return status == VIRTIO_NET_OK; 869 870 870 871 /* Spin for a response, the kick causes an ioport write, trapping 871 872 * into the hypervisor, so the request should be handled immediately. 872 873 */ 873 - while (!virtqueue_get_buf(vi->cvq, &tmp)) 874 + while (!virtqueue_get_buf(vi->cvq, &tmp) && 875 + !virtqueue_is_broken(vi->cvq)) 874 876 cpu_relax(); 875 877 876 878 return status == VIRTIO_NET_OK; ··· 900 898 return -EINVAL; 901 899 } 902 900 } else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { 903 - vdev->config->set(vdev, offsetof(struct virtio_net_config, mac), 904 - addr->sa_data, dev->addr_len); 901 + unsigned int i; 902 + 903 + /* Naturally, this has an atomicity problem. */ 904 + for (i = 0; i < dev->addr_len; i++) 905 + virtio_cwrite8(vdev, 906 + offsetof(struct virtio_net_config, mac) + 907 + i, addr->sa_data[i]); 905 908 } 906 909 907 910 eth_commit_mac_addr_change(dev, p); ··· 1288 1281 if (!vi->config_enable) 1289 1282 goto done; 1290 1283 1291 - if (virtio_config_val(vi->vdev, VIRTIO_NET_F_STATUS, 1292 - offsetof(struct virtio_net_config, status), 1293 - &v) < 0) 1284 + if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS, 1285 + struct virtio_net_config, status, &v) < 0) 1294 1286 goto done; 1295 1287 1296 1288 if (v & VIRTIO_NET_S_ANNOUNCE) { ··· 1513 1507 u16 max_queue_pairs; 1514 1508 1515 1509 /* Find if host supports multiqueue virtio_net device */ 1516 - err = virtio_config_val(vdev, VIRTIO_NET_F_MQ, 1517 - offsetof(struct virtio_net_config, 1518 - max_virtqueue_pairs), &max_queue_pairs); 1510 + err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ, 1511 + struct virtio_net_config, 1512 + max_virtqueue_pairs, &max_queue_pairs); 1519 1513 1520 1514 /* We need at least 2 queue's */ 1521 1515 if (err || max_queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || ··· 1567 1561 dev->vlan_features = dev->features; 1568 1562 1569 1563 /* Configuration may specify what MAC to use. Otherwise random. */ 1570 - if (virtio_config_val_len(vdev, VIRTIO_NET_F_MAC, 1571 - offsetof(struct virtio_net_config, mac), 1572 - dev->dev_addr, dev->addr_len) < 0) 1564 + if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) 1565 + virtio_cread_bytes(vdev, 1566 + offsetof(struct virtio_net_config, mac), 1567 + dev->dev_addr, dev->addr_len); 1568 + else 1573 1569 eth_hw_addr_random(dev); 1574 1570 1575 1571 /* Set up our device-specific information */ ··· 1712 1704 free_netdev(vi->dev); 1713 1705 } 1714 1706 1715 - #ifdef CONFIG_PM 1707 + #ifdef CONFIG_PM_SLEEP 1716 1708 static int virtnet_freeze(struct virtio_device *vdev) 1717 1709 { 1718 1710 struct virtnet_info *vi = vdev->priv; ··· 1803 1795 .probe = virtnet_probe, 1804 1796 .remove = virtnet_remove, 1805 1797 .config_changed = virtnet_config_changed, 1806 - #ifdef CONFIG_PM 1798 + #ifdef CONFIG_PM_SLEEP 1807 1799 .freeze = virtnet_freeze, 1808 1800 .restore = virtnet_restore, 1809 1801 #endif
+2 -1
drivers/remoteproc/remoteproc_virtio.c
··· 30 30 #include "remoteproc_internal.h" 31 31 32 32 /* kick the remote processor, and let it know which virtqueue to poke at */ 33 - static void rproc_virtio_notify(struct virtqueue *vq) 33 + static bool rproc_virtio_notify(struct virtqueue *vq) 34 34 { 35 35 struct rproc_vring *rvring = vq->priv; 36 36 struct rproc *rproc = rvring->rvdev->rproc; ··· 39 39 dev_dbg(&rproc->dev, "kicking vq index: %d\n", notifyid); 40 40 41 41 rproc->ops->kick(rproc, notifyid); 42 + return true; 42 43 } 43 44 44 45 /**
+6 -2
drivers/s390/kvm/kvm_virtio.c
··· 166 166 * make a hypercall. We hand the address of the virtqueue so the Host 167 167 * knows which virtqueue we're talking about. 168 168 */ 169 - static void kvm_notify(struct virtqueue *vq) 169 + static bool kvm_notify(struct virtqueue *vq) 170 170 { 171 + long rc; 171 172 struct kvm_vqconfig *config = vq->priv; 172 173 173 - kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address); 174 + rc = kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address); 175 + if (rc < 0) 176 + return false; 177 + return true; 174 178 } 175 179 176 180 /*
+4 -1
drivers/s390/kvm/virtio_ccw.c
··· 162 162 return __rc; 163 163 } 164 164 165 - static void virtio_ccw_kvm_notify(struct virtqueue *vq) 165 + static bool virtio_ccw_kvm_notify(struct virtqueue *vq) 166 166 { 167 167 struct virtio_ccw_vq_info *info = vq->priv; 168 168 struct virtio_ccw_device *vcdev; ··· 171 171 vcdev = to_vc_device(info->vq->vdev); 172 172 ccw_device_get_schid(vcdev->cdev, &schid); 173 173 info->cookie = do_kvm_notify(schid, vq->index, info->cookie); 174 + if (info->cookie < 0) 175 + return false; 176 + return true; 174 177 } 175 178 176 179 static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
+9 -10
drivers/scsi/virtio_scsi.c
··· 224 224 virtqueue_disable_cb(vq); 225 225 while ((buf = virtqueue_get_buf(vq, &len)) != NULL) 226 226 fn(vscsi, buf); 227 + 228 + if (unlikely(virtqueue_is_broken(vq))) 229 + break; 227 230 } while (!virtqueue_enable_cb(vq)); 228 231 spin_unlock_irqrestore(&virtscsi_vq->vq_lock, flags); 229 232 } ··· 713 710 #define virtscsi_config_get(vdev, fld) \ 714 711 ({ \ 715 712 typeof(((struct virtio_scsi_config *)0)->fld) __val; \ 716 - vdev->config->get(vdev, \ 717 - offsetof(struct virtio_scsi_config, fld), \ 718 - &__val, sizeof(__val)); \ 713 + virtio_cread(vdev, struct virtio_scsi_config, fld, &__val); \ 719 714 __val; \ 720 715 }) 721 716 722 717 #define virtscsi_config_set(vdev, fld, val) \ 723 - (void)({ \ 718 + do { \ 724 719 typeof(((struct virtio_scsi_config *)0)->fld) __val = (val); \ 725 - vdev->config->set(vdev, \ 726 - offsetof(struct virtio_scsi_config, fld), \ 727 - &__val, sizeof(__val)); \ 728 - }) 720 + virtio_cwrite(vdev, struct virtio_scsi_config, fld, &__val); \ 721 + } while(0) 729 722 730 723 static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) 731 724 { ··· 953 954 scsi_host_put(shost); 954 955 } 955 956 956 - #ifdef CONFIG_PM 957 + #ifdef CONFIG_PM_SLEEP 957 958 static int virtscsi_freeze(struct virtio_device *vdev) 958 959 { 959 960 virtscsi_remove_vqs(vdev); ··· 987 988 .id_table = id_table, 988 989 .probe = virtscsi_probe, 989 990 .scan = virtscsi_scan, 990 - #ifdef CONFIG_PM 991 + #ifdef CONFIG_PM_SLEEP 991 992 .freeze = virtscsi_freeze, 992 993 .restore = virtscsi_restore, 993 994 #endif
+6 -8
drivers/virtio/virtio_balloon.c
··· 275 275 __le32 v; 276 276 s64 target; 277 277 278 - vb->vdev->config->get(vb->vdev, 279 - offsetof(struct virtio_balloon_config, num_pages), 280 - &v, sizeof(v)); 278 + virtio_cread(vb->vdev, struct virtio_balloon_config, num_pages, &v); 279 + 281 280 target = le32_to_cpu(v); 282 281 return target - vb->num_pages; 283 282 } ··· 285 286 { 286 287 __le32 actual = cpu_to_le32(vb->num_pages); 287 288 288 - vb->vdev->config->set(vb->vdev, 289 - offsetof(struct virtio_balloon_config, actual), 290 - &actual, sizeof(actual)); 289 + virtio_cwrite(vb->vdev, struct virtio_balloon_config, num_pages, 290 + &actual); 291 291 } 292 292 293 293 static int balloon(void *_vballoon) ··· 511 513 kfree(vb); 512 514 } 513 515 514 - #ifdef CONFIG_PM 516 + #ifdef CONFIG_PM_SLEEP 515 517 static int virtballoon_freeze(struct virtio_device *vdev) 516 518 { 517 519 struct virtio_balloon *vb = vdev->priv; ··· 554 556 .probe = virtballoon_probe, 555 557 .remove = virtballoon_remove, 556 558 .config_changed = virtballoon_changed, 557 - #ifdef CONFIG_PM 559 + #ifdef CONFIG_PM_SLEEP 558 560 .freeze = virtballoon_freeze, 559 561 .restore = virtballoon_restore, 560 562 #endif
+3 -2
drivers/virtio/virtio_mmio.c
··· 219 219 /* Transport interface */ 220 220 221 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 224 struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); 225 225 226 226 /* We write the queue's selector into the notification register to 227 227 * signal the other end */ 228 228 writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); 229 + return true; 229 230 } 230 231 231 232 /* Notify all virtqueues on an interrupt. */ ··· 471 470 472 471 /* Check magic value */ 473 472 magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); 474 - if (memcmp(&magic, "virt", 4) != 0) { 473 + if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { 475 474 dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); 476 475 return -ENODEV; 477 476 }
+2 -1
drivers/virtio/virtio_pci.c
··· 197 197 } 198 198 199 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 202 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); 203 203 204 204 /* we write the queue's selector into the notification register to 205 205 * signal the other end */ 206 206 iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); 207 + return true; 207 208 } 208 209 209 210 /* Handle a configuration change: Tell driver if it wants to know. */
+28 -6
drivers/virtio/virtio_ring.c
··· 81 81 u16 last_used_idx; 82 82 83 83 /* How to notify other side. FIXME: commonalize hcalls! */ 84 - void (*notify)(struct virtqueue *vq); 84 + bool (*notify)(struct virtqueue *vq); 85 85 86 86 #ifdef DEBUG 87 87 /* They're supposed to lock for us. */ ··· 173 173 head = vq->free_head; 174 174 vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT; 175 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 178 vq->vring.desc[head].len = i * sizeof(struct vring_desc); 177 179 178 180 /* Update free pointer */ ··· 430 428 * @vq: the struct virtqueue 431 429 * 432 430 * This does not need to be serialized. 431 + * 432 + * Returns false if host notify failed or queue is broken, otherwise true. 433 433 */ 434 - void virtqueue_notify(struct virtqueue *_vq) 434 + bool virtqueue_notify(struct virtqueue *_vq) 435 435 { 436 436 struct vring_virtqueue *vq = to_vvq(_vq); 437 437 438 + if (unlikely(vq->broken)) 439 + return false; 440 + 438 441 /* Prod other side to tell it about changes. */ 439 - vq->notify(_vq); 442 + if (!vq->notify(_vq)) { 443 + vq->broken = true; 444 + return false; 445 + } 446 + return true; 440 447 } 441 448 EXPORT_SYMBOL_GPL(virtqueue_notify); 442 449 ··· 458 447 * 459 448 * Caller must ensure we don't call this with other virtqueue 460 449 * operations at the same time (except where noted). 450 + * 451 + * Returns false if kick failed, otherwise true. 461 452 */ 462 - void virtqueue_kick(struct virtqueue *vq) 453 + bool virtqueue_kick(struct virtqueue *vq) 463 454 { 464 455 if (virtqueue_kick_prepare(vq)) 465 - virtqueue_notify(vq); 456 + return virtqueue_notify(vq); 457 + return true; 466 458 } 467 459 EXPORT_SYMBOL_GPL(virtqueue_kick); 468 460 ··· 756 742 struct virtio_device *vdev, 757 743 bool weak_barriers, 758 744 void *pages, 759 - void (*notify)(struct virtqueue *), 745 + bool (*notify)(struct virtqueue *), 760 746 void (*callback)(struct virtqueue *), 761 747 const char *name) 762 748 { ··· 850 836 return vq->vring.num; 851 837 } 852 838 EXPORT_SYMBOL_GPL(virtqueue_get_vring_size); 839 + 840 + bool virtqueue_is_broken(struct virtqueue *_vq) 841 + { 842 + struct vring_virtqueue *vq = to_vvq(_vq); 843 + 844 + return vq->broken; 845 + } 846 + EXPORT_SYMBOL_GPL(virtqueue_is_broken); 853 847 854 848 MODULE_LICENSE("GPL");
+4 -2
include/linux/virtio.h
··· 51 51 void *data, 52 52 gfp_t gfp); 53 53 54 - void virtqueue_kick(struct virtqueue *vq); 54 + bool virtqueue_kick(struct virtqueue *vq); 55 55 56 56 bool virtqueue_kick_prepare(struct virtqueue *vq); 57 57 58 - void virtqueue_notify(struct virtqueue *vq); 58 + bool virtqueue_notify(struct virtqueue *vq); 59 59 60 60 void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); 61 61 ··· 72 72 void *virtqueue_detach_unused_buf(struct virtqueue *vq); 73 73 74 74 unsigned int virtqueue_get_vring_size(struct virtqueue *vq); 75 + 76 + bool virtqueue_is_broken(struct virtqueue *vq); 75 77 76 78 /** 77 79 * virtio_device - representation of a device using virtio
+134 -27
include/linux/virtio_config.h
··· 96 96 return test_bit(fbit, vdev->features); 97 97 } 98 98 99 - /** 100 - * virtio_config_val - look for a feature and get a virtio config entry. 101 - * @vdev: the virtio device 102 - * @fbit: the feature bit 103 - * @offset: the type to search for. 104 - * @v: a pointer to the value to fill in. 105 - * 106 - * The return value is -ENOENT if the feature doesn't exist. Otherwise 107 - * the config value is copied into whatever is pointed to by v. */ 108 - #define virtio_config_val(vdev, fbit, offset, v) \ 109 - virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(*v)) 110 - 111 - #define virtio_config_val_len(vdev, fbit, offset, v, len) \ 112 - virtio_config_buf((vdev), (fbit), (offset), (v), (len)) 113 - 114 - static inline int virtio_config_buf(struct virtio_device *vdev, 115 - unsigned int fbit, 116 - unsigned int offset, 117 - void *buf, unsigned len) 118 - { 119 - if (!virtio_has_feature(vdev, fbit)) 120 - return -ENOENT; 121 - 122 - vdev->config->get(vdev, offset, buf, len); 123 - return 0; 124 - } 125 - 126 99 static inline 127 100 struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, 128 101 vq_callback_t *c, const char *n) ··· 135 162 return 0; 136 163 } 137 164 165 + /* Config space accessors. */ 166 + #define virtio_cread(vdev, structname, member, ptr) \ 167 + do { \ 168 + /* Must match the member's type, and be integer */ \ 169 + if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 170 + (*ptr) = 1; \ 171 + \ 172 + switch (sizeof(*ptr)) { \ 173 + case 1: \ 174 + *(ptr) = virtio_cread8(vdev, \ 175 + offsetof(structname, member)); \ 176 + break; \ 177 + case 2: \ 178 + *(ptr) = virtio_cread16(vdev, \ 179 + offsetof(structname, member)); \ 180 + break; \ 181 + case 4: \ 182 + *(ptr) = virtio_cread32(vdev, \ 183 + offsetof(structname, member)); \ 184 + break; \ 185 + case 8: \ 186 + *(ptr) = virtio_cread64(vdev, \ 187 + offsetof(structname, member)); \ 188 + break; \ 189 + default: \ 190 + BUG(); \ 191 + } \ 192 + } while(0) 193 + 194 + /* Config space accessors. */ 195 + #define virtio_cwrite(vdev, structname, member, ptr) \ 196 + do { \ 197 + /* Must match the member's type, and be integer */ \ 198 + if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ 199 + BUG_ON((*ptr) == 1); \ 200 + \ 201 + switch (sizeof(*ptr)) { \ 202 + case 1: \ 203 + virtio_cwrite8(vdev, \ 204 + offsetof(structname, member), \ 205 + *(ptr)); \ 206 + break; \ 207 + case 2: \ 208 + virtio_cwrite16(vdev, \ 209 + offsetof(structname, member), \ 210 + *(ptr)); \ 211 + break; \ 212 + case 4: \ 213 + virtio_cwrite32(vdev, \ 214 + offsetof(structname, member), \ 215 + *(ptr)); \ 216 + break; \ 217 + case 8: \ 218 + virtio_cwrite64(vdev, \ 219 + offsetof(structname, member), \ 220 + *(ptr)); \ 221 + break; \ 222 + default: \ 223 + BUG(); \ 224 + } \ 225 + } while(0) 226 + 227 + static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) 228 + { 229 + u8 ret; 230 + vdev->config->get(vdev, offset, &ret, sizeof(ret)); 231 + return ret; 232 + } 233 + 234 + static inline void virtio_cread_bytes(struct virtio_device *vdev, 235 + unsigned int offset, 236 + void *buf, size_t len) 237 + { 238 + vdev->config->get(vdev, offset, buf, len); 239 + } 240 + 241 + static inline void virtio_cwrite8(struct virtio_device *vdev, 242 + unsigned int offset, u8 val) 243 + { 244 + vdev->config->set(vdev, offset, &val, sizeof(val)); 245 + } 246 + 247 + static inline u16 virtio_cread16(struct virtio_device *vdev, 248 + unsigned int offset) 249 + { 250 + u16 ret; 251 + vdev->config->get(vdev, offset, &ret, sizeof(ret)); 252 + return ret; 253 + } 254 + 255 + static inline void virtio_cwrite16(struct virtio_device *vdev, 256 + unsigned int offset, u16 val) 257 + { 258 + vdev->config->set(vdev, offset, &val, sizeof(val)); 259 + } 260 + 261 + static inline u32 virtio_cread32(struct virtio_device *vdev, 262 + unsigned int offset) 263 + { 264 + u32 ret; 265 + vdev->config->get(vdev, offset, &ret, sizeof(ret)); 266 + return ret; 267 + } 268 + 269 + static inline void virtio_cwrite32(struct virtio_device *vdev, 270 + unsigned int offset, u32 val) 271 + { 272 + vdev->config->set(vdev, offset, &val, sizeof(val)); 273 + } 274 + 275 + static inline u64 virtio_cread64(struct virtio_device *vdev, 276 + unsigned int offset) 277 + { 278 + u64 ret; 279 + vdev->config->get(vdev, offset, &ret, sizeof(ret)); 280 + return ret; 281 + } 282 + 283 + static inline void virtio_cwrite64(struct virtio_device *vdev, 284 + unsigned int offset, u64 val) 285 + { 286 + vdev->config->set(vdev, offset, &val, sizeof(val)); 287 + } 288 + 289 + /* Conditional config space accessors. */ 290 + #define virtio_cread_feature(vdev, fbit, structname, member, ptr) \ 291 + ({ \ 292 + int _r = 0; \ 293 + if (!virtio_has_feature(vdev, fbit)) \ 294 + _r = -ENOENT; \ 295 + else \ 296 + virtio_cread((vdev), structname, member, ptr); \ 297 + _r; \ 298 + }) 138 299 139 300 #endif /* _LINUX_VIRTIO_CONFIG_H */
+1 -1
include/linux/virtio_ring.h
··· 71 71 struct virtio_device *vdev, 72 72 bool weak_barriers, 73 73 void *pages, 74 - void (*notify)(struct virtqueue *vq), 74 + bool (*notify)(struct virtqueue *vq), 75 75 void (*callback)(struct virtqueue *vq), 76 76 const char *name); 77 77 void vring_del_virtqueue(struct virtqueue *vq);
+4 -5
net/9p/trans_virtio.c
··· 544 544 545 545 chan->inuse = false; 546 546 if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) { 547 - vdev->config->get(vdev, 548 - offsetof(struct virtio_9p_config, tag_len), 549 - &tag_len, sizeof(tag_len)); 547 + virtio_cread(vdev, struct virtio_9p_config, tag_len, &tag_len); 550 548 } else { 551 549 err = -EINVAL; 552 550 goto out_free_vq; ··· 554 556 err = -ENOMEM; 555 557 goto out_free_vq; 556 558 } 557 - vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag), 558 - tag, tag_len); 559 + 560 + virtio_cread_bytes(vdev, offsetof(struct virtio_9p_config, tag), 561 + tag, tag_len); 559 562 chan->tag = tag; 560 563 chan->tag_len = tag_len; 561 564 err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+4 -2
tools/virtio/virtio_test.c
··· 41 41 struct vhost_memory *mem; 42 42 }; 43 43 44 - void vq_notify(struct virtqueue *vq) 44 + bool vq_notify(struct virtqueue *vq) 45 45 { 46 46 struct vq_info *info = vq->priv; 47 47 unsigned long long v = 1; 48 48 int r; 49 49 r = write(info->kick, &v, sizeof v); 50 50 assert(r == sizeof v); 51 + return true; 51 52 } 52 53 53 54 void vq_callback(struct virtqueue *vq) ··· 172 171 GFP_ATOMIC); 173 172 if (likely(r == 0)) { 174 173 ++started; 175 - virtqueue_kick(vq->vq); 174 + if (unlikely(!virtqueue_kick(vq->vq)) 175 + r = -1; 176 176 } 177 177 } else 178 178 r = -1;
+9 -4
tools/virtio/vringh_test.c
··· 22 22 #define RINGSIZE 256 23 23 #define ALIGN 4096 24 24 25 - static void never_notify_host(struct virtqueue *vq) 25 + static bool never_notify_host(struct virtqueue *vq) 26 26 { 27 27 abort(); 28 28 } ··· 65 65 unsigned long notifies; 66 66 }; 67 67 68 - static void parallel_notify_host(struct virtqueue *vq) 68 + static bool parallel_notify_host(struct virtqueue *vq) 69 69 { 70 + int rc; 70 71 struct guest_virtio_device *gvdev; 71 72 72 73 gvdev = container_of(vq->vdev, struct guest_virtio_device, vdev); 73 - write(gvdev->to_host_fd, "", 1); 74 + rc = write(gvdev->to_host_fd, "", 1); 75 + if (rc < 0) 76 + return false; 74 77 gvdev->notifies++; 78 + return true; 75 79 } 76 80 77 - static void no_notify_host(struct virtqueue *vq) 81 + static bool no_notify_host(struct virtqueue *vq) 78 82 { 83 + return true; 79 84 } 80 85 81 86 #define NUM_XFERS (10000000)