Commit 892d6eb1245b771987afb8667a65344e568d3439

Authored by Jason Wang
Committed by David S. Miller
1 parent 7e09dccd07

virtio-net: validate features during probe

We currently trigger BUG when VIRTIO_NET_F_CTRL_VQ
is not set but one of features depending on it is.
That's not a friendly way to report errors to
hypervisors.
Let's check, and fail probe instead.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 37 additions and 0 deletions Side-by-side Diff

drivers/net/virtio_net.c
... ... @@ -1673,12 +1673,49 @@
1673 1673 };
1674 1674 #endif
1675 1675  
  1676 +static bool virtnet_fail_on_feature(struct virtio_device *vdev,
  1677 + unsigned int fbit,
  1678 + const char *fname, const char *dname)
  1679 +{
  1680 + if (!virtio_has_feature(vdev, fbit))
  1681 + return false;
  1682 +
  1683 + dev_err(&vdev->dev, "device advertises feature %s but not %s",
  1684 + fname, dname);
  1685 +
  1686 + return true;
  1687 +}
  1688 +
  1689 +#define VIRTNET_FAIL_ON(vdev, fbit, dbit) \
  1690 + virtnet_fail_on_feature(vdev, fbit, #fbit, dbit)
  1691 +
  1692 +static bool virtnet_validate_features(struct virtio_device *vdev)
  1693 +{
  1694 + if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) &&
  1695 + (VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_RX,
  1696 + "VIRTIO_NET_F_CTRL_VQ") ||
  1697 + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_VLAN,
  1698 + "VIRTIO_NET_F_CTRL_VQ") ||
  1699 + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE,
  1700 + "VIRTIO_NET_F_CTRL_VQ") ||
  1701 + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_MQ, "VIRTIO_NET_F_CTRL_VQ") ||
  1702 + VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR,
  1703 + "VIRTIO_NET_F_CTRL_VQ"))) {
  1704 + return false;
  1705 + }
  1706 +
  1707 + return true;
  1708 +}
  1709 +
1676 1710 static int virtnet_probe(struct virtio_device *vdev)
1677 1711 {
1678 1712 int i, err;
1679 1713 struct net_device *dev;
1680 1714 struct virtnet_info *vi;
1681 1715 u16 max_queue_pairs;
  1716 +
  1717 + if (!virtnet_validate_features(vdev))
  1718 + return -EINVAL;
1682 1719  
1683 1720 /* Find if host supports multiqueue virtio_net device */
1684 1721 err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ,