Commit 892d6eb1245b771987afb8667a65344e568d3439
Committed by
David S. Miller
1 parent
7e09dccd07
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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, |