Commit 189fefc7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull vdpa/mlx5 fixes from Michael Tsirkin:
 "Last minute fixes.

  These all look like something we are better off having
  than not ..."

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  vdpa/mlx5: Fix suspend/resume index restoration
  vdpa/mlx5: Fix wrong use of bit numbers
  vdpa/mlx5: Retrieve BAR address suitable any function
  vdpa/mlx5: Use the correct dma device when registering memory
  vdpa/mlx5: should exclude header length and fcs from mtu
parents 3766fcf5 bc04d93e
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
#ifndef __MLX5_VDPA_H__ #ifndef __MLX5_VDPA_H__
#define __MLX5_VDPA_H__ #define __MLX5_VDPA_H__
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/vdpa.h> #include <linux/vdpa.h>
#include <linux/mlx5/driver.h> #include <linux/mlx5/driver.h>
#define MLX5V_ETH_HARD_MTU (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
struct mlx5_vdpa_direct_mr { struct mlx5_vdpa_direct_mr {
u64 start; u64 start;
u64 end; u64 end;
......
...@@ -219,6 +219,11 @@ static void destroy_indirect_key(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_m ...@@ -219,6 +219,11 @@ static void destroy_indirect_key(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_m
mlx5_vdpa_destroy_mkey(mvdev, &mkey->mkey); mlx5_vdpa_destroy_mkey(mvdev, &mkey->mkey);
} }
static struct device *get_dma_device(struct mlx5_vdpa_dev *mvdev)
{
return &mvdev->mdev->pdev->dev;
}
static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr, static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr,
struct vhost_iotlb *iotlb) struct vhost_iotlb *iotlb)
{ {
...@@ -234,7 +239,7 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr ...@@ -234,7 +239,7 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
u64 pa; u64 pa;
u64 paend; u64 paend;
struct scatterlist *sg; struct scatterlist *sg;
struct device *dma = mvdev->mdev->device; struct device *dma = get_dma_device(mvdev);
for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1); for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1);
map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) { map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) {
...@@ -291,7 +296,7 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr ...@@ -291,7 +296,7 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr) static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr)
{ {
struct device *dma = mvdev->mdev->device; struct device *dma = get_dma_device(mvdev);
destroy_direct_mr(mvdev, mr); destroy_direct_mr(mvdev, mr);
dma_unmap_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0); dma_unmap_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
......
...@@ -246,7 +246,8 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev) ...@@ -246,7 +246,8 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
if (err) if (err)
goto err_key; goto err_key;
kick_addr = pci_resource_start(mdev->pdev, 0) + offset; kick_addr = mdev->bar_addr + offset;
res->kick_addr = ioremap(kick_addr, PAGE_SIZE); res->kick_addr = ioremap(kick_addr, PAGE_SIZE);
if (!res->kick_addr) { if (!res->kick_addr) {
err = -ENOMEM; err = -ENOMEM;
......
...@@ -820,7 +820,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque ...@@ -820,7 +820,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->fwqp.mqp.qpn); MLX5_SET(virtio_q, vq_ctx, event_qpn_or_msix, mvq->fwqp.mqp.qpn);
MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent); MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent);
MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0,
!!(ndev->mvdev.actual_features & VIRTIO_F_VERSION_1)); !!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_F_VERSION_1)));
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
...@@ -1169,6 +1169,7 @@ static void suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *m ...@@ -1169,6 +1169,7 @@ static void suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *m
return; return;
} }
mvq->avail_idx = attr.available_index; mvq->avail_idx = attr.available_index;
mvq->used_idx = attr.used_index;
} }
static void suspend_vqs(struct mlx5_vdpa_net *ndev) static void suspend_vqs(struct mlx5_vdpa_net *ndev)
...@@ -1426,6 +1427,7 @@ static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx, ...@@ -1426,6 +1427,7 @@ static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
return -EINVAL; return -EINVAL;
} }
mvq->used_idx = state->avail_index;
mvq->avail_idx = state->avail_index; mvq->avail_idx = state->avail_index;
return 0; return 0;
} }
...@@ -1443,7 +1445,11 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa ...@@ -1443,7 +1445,11 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa
* that cares about emulating the index after vq is stopped. * that cares about emulating the index after vq is stopped.
*/ */
if (!mvq->initialized) { if (!mvq->initialized) {
state->avail_index = mvq->avail_idx; /* Firmware returns a wrong value for the available index.
* Since both values should be identical, we take the value of
* used_idx which is reported correctly.
*/
state->avail_index = mvq->used_idx;
return 0; return 0;
} }
...@@ -1452,7 +1458,7 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa ...@@ -1452,7 +1458,7 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa
mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n"); mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
return err; return err;
} }
state->avail_index = attr.available_index; state->avail_index = attr.used_index;
return 0; return 0;
} }
...@@ -1540,21 +1546,11 @@ static void teardown_virtqueues(struct mlx5_vdpa_net *ndev) ...@@ -1540,21 +1546,11 @@ static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
} }
} }
static void clear_virtqueues(struct mlx5_vdpa_net *ndev)
{
int i;
for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
ndev->vqs[i].avail_idx = 0;
ndev->vqs[i].used_idx = 0;
}
}
/* TODO: cross-endian support */ /* TODO: cross-endian support */
static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev) static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
{ {
return virtio_legacy_is_little_endian() || return virtio_legacy_is_little_endian() ||
(mvdev->actual_features & (1ULL << VIRTIO_F_VERSION_1)); (mvdev->actual_features & BIT_ULL(VIRTIO_F_VERSION_1));
} }
static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val) static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
...@@ -1785,7 +1781,6 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) ...@@ -1785,7 +1781,6 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
if (!status) { if (!status) {
mlx5_vdpa_info(mvdev, "performing device reset\n"); mlx5_vdpa_info(mvdev, "performing device reset\n");
teardown_driver(ndev); teardown_driver(ndev);
clear_virtqueues(ndev);
mlx5_vdpa_destroy_mr(&ndev->mvdev); mlx5_vdpa_destroy_mr(&ndev->mvdev);
ndev->mvdev.status = 0; ndev->mvdev.status = 0;
ndev->mvdev.mlx_features = 0; ndev->mvdev.mlx_features = 0;
...@@ -1907,6 +1902,19 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = { ...@@ -1907,6 +1902,19 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
.free = mlx5_vdpa_free, .free = mlx5_vdpa_free,
}; };
static int query_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
{
u16 hw_mtu;
int err;
err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu);
if (err)
return err;
*mtu = hw_mtu - MLX5V_ETH_HARD_MTU;
return 0;
}
static int alloc_resources(struct mlx5_vdpa_net *ndev) static int alloc_resources(struct mlx5_vdpa_net *ndev)
{ {
struct mlx5_vdpa_net_resources *res = &ndev->res; struct mlx5_vdpa_net_resources *res = &ndev->res;
...@@ -1992,7 +2000,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, ...@@ -1992,7 +2000,7 @@ static int mlx5v_probe(struct auxiliary_device *adev,
init_mvqs(ndev); init_mvqs(ndev);
mutex_init(&ndev->reslock); mutex_init(&ndev->reslock);
config = &ndev->config; config = &ndev->config;
err = mlx5_query_nic_vport_mtu(mdev, &ndev->mtu); err = query_mtu(mdev, &ndev->mtu);
if (err) if (err)
goto err_mtu; goto err_mtu;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment