Commit d8673afb authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'virtio_net-vdpa-update-mac-address-when-it-is-generated-by-virtio-net'

Laurent Vivier says:

====================
virtio_net: vdpa: update MAC address when it is generated by virtio-net

When the MAC address is not provided by the vdpa device virtio_net
driver assigns a random one without notifying the device.
The consequence, in the case of mlx5_vdpa, is the internal routing
tables of the device are not updated and this can block the
communication between two namespaces.

To fix this problem, use virtnet_send_command(VIRTIO_NET_CTRL_MAC)
to set the address from virtnet_probe() when the MAC address is
not provided by the device.
====================

Link: https://lore.kernel.org/r/20230127204500.51930-1-lvivier@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents ca3daf43 9f62d221
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -3813,6 +3813,12 @@ static int virtnet_validate(struct virtio_device *vdev)
			__virtio_clear_bit(vdev, VIRTIO_NET_F_MTU);
	}

	if (virtio_has_feature(vdev, VIRTIO_NET_F_STANDBY) &&
	    !virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
		dev_warn(&vdev->dev, "device advertises feature VIRTIO_NET_F_STANDBY but not VIRTIO_NET_F_MAC, disabling standby");
		__virtio_clear_bit(vdev, VIRTIO_NET_F_STANDBY);
	}

	return 0;
}

@@ -3925,6 +3931,8 @@ static int virtnet_probe(struct virtio_device *vdev)
		eth_hw_addr_set(dev, addr);
	} else {
		eth_hw_addr_random(dev);
		dev_info(&vdev->dev, "Assigned random MAC address %pM\n",
			 dev->dev_addr);
	}

	/* Set up our device-specific information */
@@ -4052,6 +4060,24 @@ static int virtnet_probe(struct virtio_device *vdev)

	virtio_device_ready(vdev);

	/* a random MAC address has been assigned, notify the device.
	 * We don't fail probe if VIRTIO_NET_F_CTRL_MAC_ADDR is not there
	 * because many devices work fine without getting MAC explicitly
	 */
	if (!virtio_has_feature(vdev, VIRTIO_NET_F_MAC) &&
	    virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
		struct scatterlist sg;

		sg_init_one(&sg, dev->dev_addr, dev->addr_len);
		if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
					  VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) {
			pr_debug("virtio_net: setting MAC address failed\n");
			rtnl_unlock();
			err = -EINVAL;
			goto free_unregister_netdev;
		}
	}

	rtnl_unlock();

	err = virtnet_cpu_notif_add(vi);