• Breno Leitao's avatar
    virtio_net: Do not send RSS key if it is not supported · 059a49aa
    Breno Leitao authored
    There is a bug when setting the RSS options in virtio_net that can break
    the whole machine, getting the kernel into an infinite loop.
    
    Running the following command in any QEMU virtual machine with virtionet
    will reproduce this problem:
    
        # ethtool -X eth0  hfunc toeplitz
    
    This is how the problem happens:
    
    1) ethtool_set_rxfh() calls virtnet_set_rxfh()
    
    2) virtnet_set_rxfh() calls virtnet_commit_rss_command()
    
    3) virtnet_commit_rss_command() populates 4 entries for the rss
    scatter-gather
    
    4) Since the command above does not have a key, then the last
    scatter-gatter entry will be zeroed, since rss_key_size == 0.
    sg_buf_size = vi->rss_key_size;
    
    5) This buffer is passed to qemu, but qemu is not happy with a buffer
    with zero length, and do the following in virtqueue_map_desc() (QEMU
    function):
    
      if (!sz) {
          virtio_error(vdev, "virtio: zero sized buffers are not allowed");
    
    6) virtio_error() (also QEMU function) set the device as broken
    
        vdev->broken = true;
    
    7) Qemu bails out, and do not repond this crazy kernel.
    
    8) The kernel is waiting for the response to come back (function
    virtnet_send_command())
    
    9) The kernel is waiting doing the following :
    
          while (!virtqueue_get_buf(vi->cvq, &tmp) &&
    	     !virtqueue_is_broken(vi->cvq))
    	      cpu_relax();
    
    10) None of the following functions above is true, thus, the kernel
    loops here forever. Keeping in mind that virtqueue_is_broken() does
    not look at the qemu `vdev->broken`, so, it never realizes that the
    vitio is broken at QEMU side.
    
    Fix it by not sending RSS commands if the feature is not available in
    the device.
    
    Fixes: c7114b12 ("drivers/net/virtio_net: Added basic RSS support.")
    Cc: stable@vger.kernel.org
    Cc: qemu-devel@nongnu.org
    Signed-off-by: default avatarBreno Leitao <leitao@debian.org>
    Reviewed-by: default avatarHeng Qi <hengqi@linux.alibaba.com>
    Reviewed-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    059a49aa
virtio_net.c 132 KB