Commit 7c145640 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 virtio fixes from Michael Tsirkin:
 "A collection of small fixes that look like worth having in this
  release"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  virtio_pci: fix the common cfg map size
  virtio-crypto: handle config changed by work queue
  vhost: Allow null msg.size on VHOST_IOTLB_INVALIDATE
  vdpa/mlx5: Fix firmware error on creation of 1k VQs
  virtio_balloon: Fix endless deflation and inflation on arm64
  vdpa/mlx5: Fix double release of debugfs entry
  virtio-mmio: fix memory leak of vm_dev
  vdpa_sim_blk: Fix the potential leak of mgmt_dev
  tools/virtio: Add dma sync api for virtio test
parents 05d3ef8b 061b39fd
...@@ -35,6 +35,9 @@ struct virtio_crypto { ...@@ -35,6 +35,9 @@ struct virtio_crypto {
struct virtqueue *ctrl_vq; struct virtqueue *ctrl_vq;
struct data_queue *data_vq; struct data_queue *data_vq;
/* Work struct for config space updates */
struct work_struct config_work;
/* To protect the vq operations for the controlq */ /* To protect the vq operations for the controlq */
spinlock_t ctrl_lock; spinlock_t ctrl_lock;
......
...@@ -335,6 +335,14 @@ static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto) ...@@ -335,6 +335,14 @@ static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto)
virtcrypto_free_queues(vcrypto); virtcrypto_free_queues(vcrypto);
} }
static void vcrypto_config_changed_work(struct work_struct *work)
{
struct virtio_crypto *vcrypto =
container_of(work, struct virtio_crypto, config_work);
virtcrypto_update_status(vcrypto);
}
static int virtcrypto_probe(struct virtio_device *vdev) static int virtcrypto_probe(struct virtio_device *vdev)
{ {
int err = -EFAULT; int err = -EFAULT;
...@@ -454,6 +462,8 @@ static int virtcrypto_probe(struct virtio_device *vdev) ...@@ -454,6 +462,8 @@ static int virtcrypto_probe(struct virtio_device *vdev)
if (err) if (err)
goto free_engines; goto free_engines;
INIT_WORK(&vcrypto->config_work, vcrypto_config_changed_work);
return 0; return 0;
free_engines: free_engines:
...@@ -490,6 +500,7 @@ static void virtcrypto_remove(struct virtio_device *vdev) ...@@ -490,6 +500,7 @@ static void virtcrypto_remove(struct virtio_device *vdev)
dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); dev_info(&vdev->dev, "Start virtcrypto_remove.\n");
flush_work(&vcrypto->config_work);
if (virtcrypto_dev_started(vcrypto)) if (virtcrypto_dev_started(vcrypto))
virtcrypto_dev_stop(vcrypto); virtcrypto_dev_stop(vcrypto);
virtio_reset_device(vdev); virtio_reset_device(vdev);
...@@ -504,7 +515,7 @@ static void virtcrypto_config_changed(struct virtio_device *vdev) ...@@ -504,7 +515,7 @@ static void virtcrypto_config_changed(struct virtio_device *vdev)
{ {
struct virtio_crypto *vcrypto = vdev->priv; struct virtio_crypto *vcrypto = vdev->priv;
virtcrypto_update_status(vcrypto); schedule_work(&vcrypto->config_work);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -512,6 +523,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev) ...@@ -512,6 +523,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev)
{ {
struct virtio_crypto *vcrypto = vdev->priv; struct virtio_crypto *vcrypto = vdev->priv;
flush_work(&vcrypto->config_work);
virtio_reset_device(vdev); virtio_reset_device(vdev);
virtcrypto_free_unused_reqs(vcrypto); virtcrypto_free_unused_reqs(vcrypto);
if (virtcrypto_dev_started(vcrypto)) if (virtcrypto_dev_started(vcrypto))
......
...@@ -146,7 +146,8 @@ void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev) ...@@ -146,7 +146,8 @@ void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev)
ndev->rx_dent = debugfs_create_dir("rx", ndev->debugfs); ndev->rx_dent = debugfs_create_dir("rx", ndev->debugfs);
} }
void mlx5_vdpa_remove_debugfs(struct dentry *dbg) void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev)
{ {
debugfs_remove_recursive(dbg); debugfs_remove_recursive(ndev->debugfs);
ndev->debugfs = NULL;
} }
...@@ -625,30 +625,70 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx) ...@@ -625,30 +625,70 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx)
mlx5_db_free(ndev->mvdev.mdev, &vcq->db); mlx5_db_free(ndev->mvdev.mdev, &vcq->db);
} }
static int read_umem_params(struct mlx5_vdpa_net *ndev)
{
u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR & 0x01);
struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
int out_size;
void *caps;
void *out;
int err;
out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
out = kzalloc(out_size, GFP_KERNEL);
if (!out)
return -ENOMEM;
MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
if (err) {
mlx5_vdpa_warn(&ndev->mvdev,
"Failed reading vdpa umem capabilities with err %d\n", err);
goto out;
}
caps = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_a);
ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_b);
ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_a);
ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_b);
ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_a);
ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_b);
out:
kfree(out);
return 0;
}
static void set_umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num, static void set_umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num,
struct mlx5_vdpa_umem **umemp) struct mlx5_vdpa_umem **umemp)
{ {
struct mlx5_core_dev *mdev = ndev->mvdev.mdev; u32 p_a;
int p_a; u32 p_b;
int p_b;
switch (num) { switch (num) {
case 1: case 1:
p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a); p_a = ndev->umem_1_buffer_param_a;
p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b); p_b = ndev->umem_1_buffer_param_b;
*umemp = &mvq->umem1; *umemp = &mvq->umem1;
break; break;
case 2: case 2:
p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a); p_a = ndev->umem_2_buffer_param_a;
p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b); p_b = ndev->umem_2_buffer_param_b;
*umemp = &mvq->umem2; *umemp = &mvq->umem2;
break; break;
case 3: case 3:
p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a); p_a = ndev->umem_3_buffer_param_a;
p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b); p_b = ndev->umem_3_buffer_param_b;
*umemp = &mvq->umem3; *umemp = &mvq->umem3;
break; break;
} }
(*umemp)->size = p_a * mvq->num_ent + p_b; (*umemp)->size = p_a * mvq->num_ent + p_b;
} }
...@@ -2679,6 +2719,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev) ...@@ -2679,6 +2719,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
goto out; goto out;
} }
mlx5_vdpa_add_debugfs(ndev); mlx5_vdpa_add_debugfs(ndev);
err = read_umem_params(ndev);
if (err)
goto err_setup;
err = setup_virtqueues(mvdev); err = setup_virtqueues(mvdev);
if (err) { if (err) {
mlx5_vdpa_warn(mvdev, "setup_virtqueues\n"); mlx5_vdpa_warn(mvdev, "setup_virtqueues\n");
...@@ -2713,7 +2758,7 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev) ...@@ -2713,7 +2758,7 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
err_rqt: err_rqt:
teardown_virtqueues(ndev); teardown_virtqueues(ndev);
err_setup: err_setup:
mlx5_vdpa_remove_debugfs(ndev->debugfs); mlx5_vdpa_remove_debugfs(ndev);
out: out:
return err; return err;
} }
...@@ -2727,8 +2772,7 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev) ...@@ -2727,8 +2772,7 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev)
if (!ndev->setup) if (!ndev->setup)
return; return;
mlx5_vdpa_remove_debugfs(ndev->debugfs); mlx5_vdpa_remove_debugfs(ndev);
ndev->debugfs = NULL;
teardown_steering(ndev); teardown_steering(ndev);
destroy_tir(ndev); destroy_tir(ndev);
destroy_rqt(ndev); destroy_rqt(ndev);
...@@ -3489,8 +3533,6 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device * ...@@ -3489,8 +3533,6 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
struct workqueue_struct *wq; struct workqueue_struct *wq;
mlx5_vdpa_remove_debugfs(ndev->debugfs);
ndev->debugfs = NULL;
unregister_link_notifier(ndev); unregister_link_notifier(ndev);
_vdpa_unregister_device(dev); _vdpa_unregister_device(dev);
wq = mvdev->wq; wq = mvdev->wq;
......
...@@ -65,6 +65,15 @@ struct mlx5_vdpa_net { ...@@ -65,6 +65,15 @@ struct mlx5_vdpa_net {
struct hlist_head macvlan_hash[MLX5V_MACVLAN_SIZE]; struct hlist_head macvlan_hash[MLX5V_MACVLAN_SIZE];
struct mlx5_vdpa_irq_pool irqp; struct mlx5_vdpa_irq_pool irqp;
struct dentry *debugfs; struct dentry *debugfs;
u32 umem_1_buffer_param_a;
u32 umem_1_buffer_param_b;
u32 umem_2_buffer_param_a;
u32 umem_2_buffer_param_b;
u32 umem_3_buffer_param_a;
u32 umem_3_buffer_param_b;
}; };
struct mlx5_vdpa_counter { struct mlx5_vdpa_counter {
...@@ -88,7 +97,7 @@ struct macvlan_node { ...@@ -88,7 +97,7 @@ struct macvlan_node {
}; };
void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev); void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev);
void mlx5_vdpa_remove_debugfs(struct dentry *dbg); void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev);
void mlx5_vdpa_add_rx_flow_table(struct mlx5_vdpa_net *ndev); void mlx5_vdpa_add_rx_flow_table(struct mlx5_vdpa_net *ndev);
void mlx5_vdpa_remove_rx_flow_table(struct mlx5_vdpa_net *ndev); void mlx5_vdpa_remove_rx_flow_table(struct mlx5_vdpa_net *ndev);
void mlx5_vdpa_add_tirn(struct mlx5_vdpa_net *ndev); void mlx5_vdpa_add_tirn(struct mlx5_vdpa_net *ndev);
......
...@@ -499,12 +499,13 @@ static int __init vdpasim_blk_init(void) ...@@ -499,12 +499,13 @@ static int __init vdpasim_blk_init(void)
GFP_KERNEL); GFP_KERNEL);
if (!shared_buffer) { if (!shared_buffer) {
ret = -ENOMEM; ret = -ENOMEM;
goto parent_err; goto mgmt_dev_err;
} }
} }
return 0; return 0;
mgmt_dev_err:
vdpa_mgmtdev_unregister(&mgmt_dev);
parent_err: parent_err:
device_unregister(&vdpasim_blk_mgmtdev); device_unregister(&vdpasim_blk_mgmtdev);
return ret; return ret;
......
...@@ -1458,9 +1458,7 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev, ...@@ -1458,9 +1458,7 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
goto done; goto done;
} }
if ((msg.type == VHOST_IOTLB_UPDATE || if (msg.type == VHOST_IOTLB_UPDATE && msg.size == 0) {
msg.type == VHOST_IOTLB_INVALIDATE) &&
msg.size == 0) {
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
} }
......
...@@ -395,7 +395,11 @@ static inline s64 towards_target(struct virtio_balloon *vb) ...@@ -395,7 +395,11 @@ static inline s64 towards_target(struct virtio_balloon *vb)
virtio_cread_le(vb->vdev, struct virtio_balloon_config, num_pages, virtio_cread_le(vb->vdev, struct virtio_balloon_config, num_pages,
&num_pages); &num_pages);
target = num_pages; /*
* Aligned up to guest page size to avoid inflating and deflating
* balloon endlessly.
*/
target = ALIGN(num_pages, VIRTIO_BALLOON_PAGES_PER_PAGE);
return target - vb->num_pages; return target - vb->num_pages;
} }
......
...@@ -631,14 +631,17 @@ static int virtio_mmio_probe(struct platform_device *pdev) ...@@ -631,14 +631,17 @@ static int virtio_mmio_probe(struct platform_device *pdev)
spin_lock_init(&vm_dev->lock); spin_lock_init(&vm_dev->lock);
vm_dev->base = devm_platform_ioremap_resource(pdev, 0); vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vm_dev->base)) if (IS_ERR(vm_dev->base)) {
return PTR_ERR(vm_dev->base); rc = PTR_ERR(vm_dev->base);
goto free_vm_dev;
}
/* Check magic value */ /* Check magic value */
magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
return -ENODEV; rc = -ENODEV;
goto free_vm_dev;
} }
/* Check device version */ /* Check device version */
...@@ -646,7 +649,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) ...@@ -646,7 +649,8 @@ static int virtio_mmio_probe(struct platform_device *pdev)
if (vm_dev->version < 1 || vm_dev->version > 2) { if (vm_dev->version < 1 || vm_dev->version > 2) {
dev_err(&pdev->dev, "Version %ld not supported!\n", dev_err(&pdev->dev, "Version %ld not supported!\n",
vm_dev->version); vm_dev->version);
return -ENXIO; rc = -ENXIO;
goto free_vm_dev;
} }
vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
...@@ -655,7 +659,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) ...@@ -655,7 +659,8 @@ static int virtio_mmio_probe(struct platform_device *pdev)
* virtio-mmio device with an ID 0 is a (dummy) placeholder * virtio-mmio device with an ID 0 is a (dummy) placeholder
* with no function. End probing now with no error reported. * with no function. End probing now with no error reported.
*/ */
return -ENODEV; rc = -ENODEV;
goto free_vm_dev;
} }
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
...@@ -685,6 +690,10 @@ static int virtio_mmio_probe(struct platform_device *pdev) ...@@ -685,6 +690,10 @@ static int virtio_mmio_probe(struct platform_device *pdev)
put_device(&vm_dev->vdev.dev); put_device(&vm_dev->vdev.dev);
return rc; return rc;
free_vm_dev:
kfree(vm_dev);
return rc;
} }
static int virtio_mmio_remove(struct platform_device *pdev) static int virtio_mmio_remove(struct platform_device *pdev)
......
...@@ -291,7 +291,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) ...@@ -291,7 +291,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev)
err = -EINVAL; err = -EINVAL;
mdev->common = vp_modern_map_capability(mdev, common, mdev->common = vp_modern_map_capability(mdev, common,
sizeof(struct virtio_pci_common_cfg), 4, sizeof(struct virtio_pci_common_cfg), 4,
0, sizeof(struct virtio_pci_common_cfg), 0, sizeof(struct virtio_pci_modern_common_cfg),
NULL, NULL); NULL, NULL);
if (!mdev->common) if (!mdev->common)
goto err_map_common; goto err_map_common;
......
...@@ -24,11 +24,23 @@ enum dma_data_direction { ...@@ -24,11 +24,23 @@ enum dma_data_direction {
#define dma_map_page(d, p, o, s, dir) (page_to_phys(p) + (o)) #define dma_map_page(d, p, o, s, dir) (page_to_phys(p) + (o))
#define dma_map_single(d, p, s, dir) (virt_to_phys(p)) #define dma_map_single(d, p, s, dir) (virt_to_phys(p))
#define dma_map_single_attrs(d, p, s, dir, a) (virt_to_phys(p))
#define dma_mapping_error(...) (0) #define dma_mapping_error(...) (0)
#define dma_unmap_single(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0) #define dma_unmap_single(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0)
#define dma_unmap_page(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0) #define dma_unmap_page(d, a, s, r) do { (void)(d); (void)(a); (void)(s); (void)(r); } while (0)
#define sg_dma_address(sg) (0)
#define dma_need_sync(v, a) (0)
#define dma_unmap_single_attrs(d, a, s, r, t) do { \
(void)(d); (void)(a); (void)(s); (void)(r); (void)(t); \
} while (0)
#define dma_sync_single_range_for_cpu(d, a, o, s, r) do { \
(void)(d); (void)(a); (void)(o); (void)(s); (void)(r); \
} while (0)
#define dma_sync_single_range_for_device(d, a, o, s, r) do { \
(void)(d); (void)(a); (void)(o); (void)(s); (void)(r); \
} while (0)
#define dma_max_mapping_size(...) SIZE_MAX #define dma_max_mapping_size(...) SIZE_MAX
#endif #endif
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