From patchwork Fri Mar 29 00:16:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 161379 Delivered-To: patches@linaro.org Received: by 2002:a02:c6d8:0:0:0:0:0 with SMTP id r24csp1367935jan; Thu, 28 Mar 2019 17:16:17 -0700 (PDT) X-Received: by 2002:aa7:9095:: with SMTP id i21mr21568172pfa.134.1553818577459; Thu, 28 Mar 2019 17:16:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553818577; cv=none; d=google.com; s=arc-20160816; b=pw14pkE6+jHsxGDQPCcDchVzjqt3CCECgyyGUx8Kj10rArJR95s9C81JK2YCzSCBW0 +kB+lefj637Xv6RoJqA9gzTETfsrOXIXi+r0FxHyf9kmQYCTcEqOFrx/g6er1eujwgRF 8Be1fXtaF0iiZfe4/e9WsIbU42rwVVCGFecuqLvvqu/3Dwr1YziiUero8tuEIzzv0AnR Qfq09QtmgjKHK4sXDYEzYaQM7eAv2KeBECwVRnnXueSOPI2h5VdPbjZpTJd2zTTGmJ/m uzN1qTUZw9l68KprIxamRLIV9Pbw5MEv1Hroj0Vb8l+qGjL+3EFUlgNubslrQWgvZnBM O3fA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=viFUhe6LpFGg7/lEQ9FuuvEf+iPLtzynE94Ig2iXdP4=; b=Bq4LkC3Qszcb9Mdh6Q9STcKhf0qz8SqLDF87iI/GXcgIdeWinGxRyFJ9PVRr/7K5xJ XVAJkTJL2rxfTgDqb4pQZI7PrU/8O1zHIictjAyiPSlPUL9PxhDrisC7fHfdy8g66LKS BTsVhgaZt6nEMRh7D9Jxei8feJZHQ8bpmg9WJT3yA8Yqiw6U5ojpgV80QgyjH3yFx6Fc eNek3L9IOgoOaUq/DwZ+IspG5vrHrFGmid68NvM8uksSLJfmhXXmzpnGfwbZT6+Csg9j Pn9gAT12XTA9HYMLPfJ/TaTmKkhr4WPfeXsoKddmq/nXDdQOUBU9qHtPrHYwlj0mmQe3 5k4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jbrWas5H; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id e63sor504102pgc.0.2019.03.28.17.16.17 for (Google Transport Security); Thu, 28 Mar 2019 17:16:17 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jbrWas5H; spf=pass (google.com: domain of john.stultz@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=viFUhe6LpFGg7/lEQ9FuuvEf+iPLtzynE94Ig2iXdP4=; b=jbrWas5HNRqZs34e4EA4kuqSyKUHSirDi13Gj9om1pVr9LulhBpFlTHm3m2vAPuaB9 BqGevEw5yA9mFF8DlnQJzWRQTEfjqTuycA6SHY5tXL0yZOF30uVjMdp9NfCqwiyGXFn3 44XAlFk4ggSs966npkH+B60bxf5itRnAkEkxt3iEe88x8GPILSEwlUvSX4dDcY/u+WsB J7fELthyiePGdt9nH2Xo2SVGnoFPXLP6rDNA1Hvn26TguqrAr5vpCjFVQqynsTjOU9GW ljUOxAmLDWm9NyAyIMti1s0YlLTY4ChDqkrwCNm2Cc3h+1LYyOGGa7D7t9fef7QElkgb I1Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=viFUhe6LpFGg7/lEQ9FuuvEf+iPLtzynE94Ig2iXdP4=; b=ZM8mMFc5fUaOFMuVNXXUdSaoQHnDMsX62JmaV5HFY7HFQpjnU6JuBDxbzLlSvHWuZm KBIku06Pn92S8Md5EC/W6OxZTTPph1phw/Yx29oNaA7jKhre2/mkEMiRDSFlnAp052pc GSMpqP4HYs9Wdyv7HKWqg/CQAJ9T3VxgMGQuA4oB31zCyoFBhTsA3St0ZiTEsUgE5p2e 71cJu0qkgjt+5HvAzR/A0CRmHt7eSzhOXBqtmA57m3+fn2rrh+x6W8xmkP1kGILNIG/J 7NeXTNm7KAmjr/meacOLViPCI2aPWGtD3M9FnbvIUeu89vPkUmFNq+K1rNuSwj62pQl1 KQjQ== X-Gm-Message-State: APjAAAVS3cNK0dg1tBZ99yQwBmwcBe3FDz+7n/qsc9Fj/NztY4PoDKVO zc5g9vq3jH6YuaMwsIRpYowU/+LZ X-Google-Smtp-Source: APXvYqz1p/ncf6/URKK0zdV7oDLW/ybTFu36vwYa7Q7TOAlb+vOUiPR//K6om5XDLdeNDejUBIk74g== X-Received: by 2002:a65:5c4b:: with SMTP id v11mr42054499pgr.411.1553818576987; Thu, 28 Mar 2019 17:16:16 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id g5sm430137pfo.53.2019.03.28.17.16.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Mar 2019 17:16:16 -0700 (PDT) From: John Stultz To: lkml Cc: "Andrew F. Davis" , Benjamin Gaignard , Sumit Semwal , Liam Mark , Pratik Patel , Brian Starkey , Vincent Donnefort , Sudipto Paul , Xu YiPing , "Chenfeng (puck)" , butao , "Xiaqing (A)" , Yudongbin , Christoph Hellwig , Chenbo Feng , Alistair Strachan , dri-devel@lists.freedesktop.org, John Stultz Subject: [RFC][PATCH 5/6 v3] dma-buf: Add Dummy Importer Test Device Date: Thu, 28 Mar 2019 17:16:01 -0700 Message-Id: <1553818562-2516-6-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1553818562-2516-1-git-send-email-john.stultz@linaro.org> References: <1553818562-2516-1-git-send-email-john.stultz@linaro.org> From: "Andrew F. Davis" This dummy test driver lets us do some very basic testing of importing dma-bufs. It is based originally on TI's out of tree "DMA-BUF physical address user-space exporter" originally by Andrew F. Davis Cc: Benjamin Gaignard Cc: Sumit Semwal Cc: Liam Mark Cc: Pratik Patel Cc: Brian Starkey Cc: Vincent Donnefort Cc: Sudipto Paul Cc: Andrew F. Davis Cc: Xu YiPing Cc: "Chenfeng (puck)" Cc: butao Cc: "Xiaqing (A)" Cc: Yudongbin Cc: Christoph Hellwig Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: Andrew F. Davis [Renamed and refactored dma_buf_phys driver, rewote commitlog] Signed-off-by: John Stultz --- drivers/dma-buf/Kconfig | 6 + drivers/dma-buf/Makefile | 1 + drivers/dma-buf/dma-buf-testdev.c | 239 +++++++++++++++++++++++++++++++++++ include/uapi/linux/dma-buf-testdev.h | 37 ++++++ 4 files changed, 283 insertions(+) create mode 100644 drivers/dma-buf/dma-buf-testdev.c create mode 100644 include/uapi/linux/dma-buf-testdev.h -- 2.7.4 diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index 63c139d..3cbcbe0 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -49,4 +49,10 @@ menuconfig DMABUF_HEAPS source "drivers/dma-buf/heaps/Kconfig" +config DMABUF_TESTDEV + bool "DMA-BUF Dummy Test Device" + depends on DMA_SHARED_BUFFER + help + This provides a dummy test device that can be used to test + importing dma-bufs. endmenu diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 09c2f2d..69bf45d 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_SYNC_FILE) += sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o obj-$(CONFIG_UDMABUF) += udmabuf.o +obj-$(CONFIG_DMABUF_TESTDEV) += dma-buf-testdev.o diff --git a/drivers/dma-buf/dma-buf-testdev.c b/drivers/dma-buf/dma-buf-testdev.c new file mode 100644 index 0000000..dc3ed93 --- /dev/null +++ b/drivers/dma-buf/dma-buf-testdev.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMA-BUF Dummy Importer Test Device + * + * Originally from TI DMA BUF contiguous buffer physical address + * user-space exporter + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DEVICE_NAME "dma-buf-testdev" + +struct dma_buf_testdev_priv { + struct miscdevice miscdev; +}; + +struct dma_buf_testdev_file { + struct device *dev; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attachment; + struct sg_table *sgt; +}; + +static int dma_buf_testdev_open(struct inode *inode, struct file *file) +{ + struct miscdevice *miscdev = file->private_data; + struct device *dev = miscdev->this_device; + struct dma_buf_testdev_file *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->dev = dev; + file->private_data = (void *)priv; + + return 0; +} + +static int dma_buf_testdev_release(struct inode *inode, struct file *file) +{ + struct dma_buf_testdev_file *priv = file->private_data; + + if (priv->attachment && priv->sgt) + dma_buf_unmap_attachment(priv->attachment, priv->sgt, + DMA_BIDIRECTIONAL); + if (priv->dma_buf && priv->attachment) + dma_buf_detach(priv->dma_buf, priv->attachment); + if (priv->dma_buf) + dma_buf_put(priv->dma_buf); + + kfree(priv); + + return 0; +} + +static int dma_buf_testdev_convert(struct dma_buf_testdev_file *priv, int fd, + phys_addr_t *phys) +{ + struct device *dev = priv->dev; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attachment; + struct sg_table *sgt; + dma_addr_t dma_addr; + int ret; + + dma_buf = dma_buf_get(fd); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + + /* Attach as the parent device as it will have the correct DMA ops */ + attachment = dma_buf_attach(dma_buf, dev->parent); + if (IS_ERR(attachment)) { + ret = PTR_ERR(attachment); + goto fail_put; + } + + sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + goto fail_detach; + } + + /* Without PAT only physically contiguous buffers can be supported */ + if (sgt->orig_nents != 1) { + dev_err(dev, "DMA-BUF not contiguous\n"); + ret = -EINVAL; + goto fail_unmap; + } + + dma_addr = sg_dma_address(sgt->sgl); + + *phys = dma_addr; + + priv->dma_buf = dma_buf; + priv->attachment = attachment; + priv->sgt = sgt; + + return 0; + +fail_unmap: + dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL); +fail_detach: + dma_buf_detach(dma_buf, attachment); +fail_put: + dma_buf_put(dma_buf); + + return ret; +} + +static long dma_buf_testdev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct dma_buf_testdev_file *priv = file->private_data; + + switch (cmd) { + case DMA_BUF_TESTDEV_IOC_CONVERT: + { + struct dma_buf_testdev_data data; + int ret; + + /* + * TODO: this should likely be properly serialized, but I + * see no reason this file would ever need to be shared. + */ + /* one attachment per file */ + if (priv->dma_buf) + return -EFAULT; + + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + ret = dma_buf_testdev_convert(priv, data.fd, &data.phys); + if (ret) + return ret; + + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) + return -EFAULT; + + break; + } + default: + return -ENOTTY; + } + + return 0; +} + +static const struct file_operations dma_buf_testdev_fops = { + .owner = THIS_MODULE, + .open = dma_buf_testdev_open, + .release = dma_buf_testdev_release, + .unlocked_ioctl = dma_buf_testdev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = dma_buf_testdev_ioctl, +#endif +}; + +static int dma_buf_testdev_probe(struct platform_device *pdev) +{ + struct dma_buf_testdev_priv *priv; + struct device *dev = &pdev->dev; + int err; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + dev_set_drvdata(dev, priv); + + dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + + if (!dev->dma_parms) { + dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), + GFP_KERNEL); + if (!dev->dma_parms) + return -ENOMEM; + } + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); + + priv->miscdev.minor = MISC_DYNAMIC_MINOR; + priv->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", + DEVICE_NAME); + priv->miscdev.fops = &dma_buf_testdev_fops; + priv->miscdev.parent = dev; + err = misc_register(&priv->miscdev); + if (err) { + dev_err(dev, + "unable to register DMA-BUF to Phys misc device\n"); + return err; + } + + return 0; +} + +static int dma_buf_testdev_remove(struct platform_device *pdev) +{ + struct dma_buf_testdev_priv *priv = dev_get_drvdata(&pdev->dev); + + misc_deregister(&priv->miscdev); + + return 0; +} + +static struct platform_driver dma_buf_testdev_driver = { + .probe = dma_buf_testdev_probe, + .remove = dma_buf_testdev_remove, + .driver = { + .name = "dma_buf_testdev", + } +}; +module_platform_driver(dma_buf_testdev_driver); + +static int __init dma_buf_testdev_init(void) +{ + struct platform_device *pdev; + + pdev = platform_device_register_simple("dma_buf_testdev", -1, NULL, 0); + + return PTR_ERR_OR_ZERO(pdev); +} + +postcore_initcall(dma_buf_testdev_init); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("DMA-BUF Dummy Importer Test Device"); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/linux/dma-buf-testdev.h b/include/uapi/linux/dma-buf-testdev.h new file mode 100644 index 0000000..b9706b8 --- /dev/null +++ b/include/uapi/linux/dma-buf-testdev.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * DMA-BUF Dummy Importer Test Device + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + */ + +#ifndef DMA_BUF_TESTDEV_H +#define DMA_BUF_TESTDEV_H + +#include +#include + +/** + * struct dma_buf_testdev_data - metadata passed from userspace for conversion + * @fd: DMA-BUF fd for conversion + * @phys: populated with CPU physical address of DMA-BUF + */ +struct dma_buf_testdev_data { + __u32 fd; + __u64 phys; +}; + +#define DMA_BUF_TESTDEV_IOC_MAGIC 'D' + +/** + * DOC: DMA_BUF_TESTDEV_IOC_CONVERT - Convert DMA-BUF to physical address + * + * Takes a dma_buf_testdev_data struct containing a fd for a + * physicaly contigous buffer. Pins this buffer and populates + * phys field with the CPU physical address. + */ +#define DMA_BUF_TESTDEV_IOC_CONVERT _IOWR(DMA_BUF_TESTDEV_IOC_MAGIC, 0, \ + struct dma_buf_testdev_data) + +#endif /* DMA_BUF_PHYS_H */