On Wed, Feb 10, 2021 at 01:47:59PM -0800, Si-Wei Liu wrote: > The mlx_features denotes the capability for which > set of virtio features is supported by device. In > principle, this field needs not be cleared during > virtio device reset, as this capability is static > and does not change across reset. > > In fact, the current code may have the assumption > that mlx_features can be reloaded from firmware > via the .get_features ops after device is reset > (via the .set_status ops), which is unfortunately > not true. The userspace VMM might save a copy > of backend capable features and won't call into > kernel again to get it on reset. This causes all > virtio features getting disabled on newly created > virtqs after device reset, while guest would hold > mismatched view of available features. For e.g., > the guest may still assume tx checksum offload > is available after reset and feature negotiation, > causing frames with bogus (incomplete) checksum > transmitted on the wire. > > Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices") > Signed-off-by: Si-Wei Liu <si-wei....@oracle.com>
Acked-by: Eli Cohen <e...@nvidia.com> > --- > drivers/vdpa/mlx5/net/mlx5_vnet.c | 25 +++++++++++++++---------- > 1 file changed, 15 insertions(+), 10 deletions(-) > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c > b/drivers/vdpa/mlx5/net/mlx5_vnet.c > index b8416c4..7c1f789 100644 > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c > @@ -1486,16 +1486,8 @@ static u64 mlx_to_vritio_features(u16 dev_features) > static u64 mlx5_vdpa_get_features(struct vdpa_device *vdev) > { > struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); > - struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); > - u16 dev_features; > > - dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, > device_features_bits_mask); > - ndev->mvdev.mlx_features = mlx_to_vritio_features(dev_features); > - if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0)) > - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1); > - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM); > - print_features(mvdev, ndev->mvdev.mlx_features, false); > - return ndev->mvdev.mlx_features; > + return mvdev->mlx_features; > } > > static int verify_min_features(struct mlx5_vdpa_dev *mvdev, u64 features) > @@ -1788,7 +1780,6 @@ static void mlx5_vdpa_set_status(struct vdpa_device > *vdev, u8 status) > clear_virtqueues(ndev); > mlx5_vdpa_destroy_mr(&ndev->mvdev); > ndev->mvdev.status = 0; > - ndev->mvdev.mlx_features = 0; > ++mvdev->generation; > return; > } > @@ -1907,6 +1898,19 @@ static int mlx5_get_vq_irq(struct vdpa_device *vdv, > u16 idx) > .free = mlx5_vdpa_free, > }; > > +static void query_virtio_features(struct mlx5_vdpa_net *ndev) > +{ > + struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; > + u16 dev_features; > + > + dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, > device_features_bits_mask); > + mvdev->mlx_features = mlx_to_vritio_features(dev_features); > + if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0)) > + mvdev->mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1); > + mvdev->mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM); > + print_features(mvdev, mvdev->mlx_features, false); > +} > + > static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu) > { > u16 hw_mtu; > @@ -2005,6 +2009,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, > init_mvqs(ndev); > mutex_init(&ndev->reslock); > config = &ndev->config; > + query_virtio_features(ndev); > err = query_mtu(mdev, &ndev->mtu); > if (err) > goto err_mtu; > -- > 1.8.3.1 >