Commit 0676181a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dmaengine fixes from Vinod Koul:

 - Intel idxd fixes for idxd_free() handling, refcount underflow on
   module unload, double free in idxd_setup_wqs()

 - Qualcomm bam dma missing properties and handing for channels with ees

 - dw device reference leak in rzn1_dmamux_route_allocate()

* tag 'dmaengine-fix-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dmaengine: dw: dmamux: Fix device reference leak in rzn1_dmamux_route_allocate
  dmaengine: ti: edma: Fix memory allocation size for queue_priority_map
  dmaengine: idxd: Fix double free in idxd_setup_wqs()
  dmaengine: idxd: Fix refcount underflow on module unload
  dmaengine: idxd: Remove improper idxd_free
  dmaengine: qcom: bam_dma: Fix DT error handling for num-channels/ees
  dt-bindings: dma: qcom: bam-dma: Add missing required properties
parents 1519fc7c aa2e1e45
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -92,8 +92,12 @@ required:
anyOf:
  - required:
      - qcom,powered-remotely
      - num-channels
      - qcom,num-ees
  - required:
      - qcom,controlled-remotely
      - num-channels
      - qcom,num-ees
  - required:
      - clocks
      - clock-names
+11 −4
Original line number Diff line number Diff line
@@ -48,12 +48,16 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec,
	u32 mask;
	int ret;

	if (dma_spec->args_count != RNZ1_DMAMUX_NCELLS)
		return ERR_PTR(-EINVAL);
	if (dma_spec->args_count != RNZ1_DMAMUX_NCELLS) {
		ret = -EINVAL;
		goto put_device;
	}

	map = kzalloc(sizeof(*map), GFP_KERNEL);
	if (!map)
		return ERR_PTR(-ENOMEM);
	if (!map) {
		ret = -ENOMEM;
		goto put_device;
	}

	chan = dma_spec->args[0];
	map->req_idx = dma_spec->args[4];
@@ -94,12 +98,15 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec,
	if (ret)
		goto clear_bitmap;

	put_device(&pdev->dev);
	return map;

clear_bitmap:
	clear_bit(map->req_idx, dmamux->used_chans);
free_map:
	kfree(map);
put_device:
	put_device(&pdev->dev);

	return ERR_PTR(ret);
}
+21 −18
Original line number Diff line number Diff line
@@ -189,27 +189,30 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
	idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev));
	if (!idxd->wq_enable_map) {
		rc = -ENOMEM;
		goto err_bitmap;
		goto err_free_wqs;
	}

	for (i = 0; i < idxd->max_wqs; i++) {
		wq = kzalloc_node(sizeof(*wq), GFP_KERNEL, dev_to_node(dev));
		if (!wq) {
			rc = -ENOMEM;
			goto err;
			goto err_unwind;
		}

		idxd_dev_set_type(&wq->idxd_dev, IDXD_DEV_WQ);
		conf_dev = wq_confdev(wq);
		wq->id = i;
		wq->idxd = idxd;
		device_initialize(wq_confdev(wq));
		device_initialize(conf_dev);
		conf_dev->parent = idxd_confdev(idxd);
		conf_dev->bus = &dsa_bus_type;
		conf_dev->type = &idxd_wq_device_type;
		rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id);
		if (rc < 0)
			goto err;
		if (rc < 0) {
			put_device(conf_dev);
			kfree(wq);
			goto err_unwind;
		}

		mutex_init(&wq->wq_lock);
		init_waitqueue_head(&wq->err_queue);
@@ -220,15 +223,20 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
		wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
		wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
		if (!wq->wqcfg) {
			put_device(conf_dev);
			kfree(wq);
			rc = -ENOMEM;
			goto err;
			goto err_unwind;
		}

		if (idxd->hw.wq_cap.op_config) {
			wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
			if (!wq->opcap_bmap) {
				kfree(wq->wqcfg);
				put_device(conf_dev);
				kfree(wq);
				rc = -ENOMEM;
				goto err_opcap_bmap;
				goto err_unwind;
			}
			bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS);
		}
@@ -239,13 +247,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)

	return 0;

err_opcap_bmap:
	kfree(wq->wqcfg);

err:
	put_device(conf_dev);
	kfree(wq);

err_unwind:
	while (--i >= 0) {
		wq = idxd->wqs[i];
		if (idxd->hw.wq_cap.op_config)
@@ -254,11 +256,10 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
		conf_dev = wq_confdev(wq);
		put_device(conf_dev);
		kfree(wq);

	}
	bitmap_free(idxd->wq_enable_map);

err_bitmap:
err_free_wqs:
	kfree(idxd->wqs);

	return rc;
@@ -1291,10 +1292,12 @@ static void idxd_remove(struct pci_dev *pdev)
	device_unregister(idxd_confdev(idxd));
	idxd_shutdown(pdev);
	idxd_device_remove_debugfs(idxd);
	idxd_cleanup(idxd);
	perfmon_pmu_remove(idxd);
	idxd_cleanup_interrupts(idxd);
	if (device_pasid_enabled(idxd))
		idxd_disable_system_pasid(idxd);
	pci_iounmap(pdev, idxd->reg_base);
	put_device(idxd_confdev(idxd));
	idxd_free(idxd);
	pci_disable_device(pdev);
}

+6 −2
Original line number Diff line number Diff line
@@ -1283,13 +1283,17 @@ static int bam_dma_probe(struct platform_device *pdev)
	if (!bdev->bamclk) {
		ret = of_property_read_u32(pdev->dev.of_node, "num-channels",
					   &bdev->num_channels);
		if (ret)
		if (ret) {
			dev_err(bdev->dev, "num-channels unspecified in dt\n");
			return ret;
		}

		ret = of_property_read_u32(pdev->dev.of_node, "qcom,num-ees",
					   &bdev->num_ees);
		if (ret)
		if (ret) {
			dev_err(bdev->dev, "num-ees unspecified in dt\n");
			return ret;
		}
	}

	ret = clk_prepare_enable(bdev->bamclk);
+2 −2
Original line number Diff line number Diff line
@@ -2064,8 +2064,8 @@ static int edma_setup_from_hw(struct device *dev, struct edma_soc_info *pdata,
	 * priority. So Q0 is the highest priority queue and the last queue has
	 * the lowest priority.
	 */
	queue_priority_map = devm_kcalloc(dev, ecc->num_tc + 1, sizeof(s8),
					  GFP_KERNEL);
	queue_priority_map = devm_kcalloc(dev, ecc->num_tc + 1,
					  sizeof(*queue_priority_map), GFP_KERNEL);
	if (!queue_priority_map)
		return -ENOMEM;