Received: by 2002:ab2:3350:0:b0:1f4:6588:b3a7 with SMTP id o16csp2028615lqe; Tue, 9 Apr 2024 07:41:39 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVDKd8xVCMZ7QTaRNNdMNzgiplzClYY9Z2oBjzCgmqX0aN0TH0rvLZcw0gFw/CF8JRF/n6spOja1DQzZH6rJ8K6QP7KL2eoLBJSspb2Eg== X-Google-Smtp-Source: AGHT+IEKultL5gCPQ1NUPd0eZUooPcGOuvxFe6GZyWgnLvi80okrD4px26C8mh/PBKprz52Vipae X-Received: by 2002:a17:902:cecf:b0:1e0:cdcc:340b with SMTP id d15-20020a170902cecf00b001e0cdcc340bmr17000068plg.19.1712673699055; Tue, 09 Apr 2024 07:41:39 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712673699; cv=pass; d=google.com; s=arc-20160816; b=c4xhOJngF7N5ijt8FfAVpYzXt0ChzFVxlvIZ5kwsHu5TdyzKHJrhpTa3I0p1dR2s7s SkxElB+Sv8BNtjsXfQYz4yw7BM0MnnALvDlnVs+cVULBRuPi4eTt63ozeJjMNRJ58zDe CZK7MILrR/09RGEt3wCObCxEt+4IM6B4u7U7FaUieOEwN1eOs9KJYd8XvMBboi39DkEm IZ36uGFgQZEPyihMe9i2f7jJFf3v4Y8o3zyCFH78EyxEUMS61CETrMexWzQsOmqNDsfi LIqNKWqbSuLVn0slNUNTADbIet/e/j+nenQpFAWayamUaQhZNYx02FRMc47zWe2CUQgP bpZA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature; bh=haEpmy5VhtEasqeLLSLULQyED9X5Xlmx8DrgXvQysfQ=; fh=cRLaL4tK7LNA7g2s/tCfJQRCODJcs6xPtTvnRZG8rxc=; b=EgJ/BAuMJzZo9CYgFowDUmO8jzR9BLas40XoCQKJY+lnFdq4kVFeDFldyFnt4U5af6 RFq4waa2/1nWWdYD2v8+Yokv6TQfqGdHGwEsMuHLJK+33DsGBUTKE8rVGoTUn11lYVTB pse/5AwTHJGfX2fsbWn7IE1o1lVto7RbA051v/SOoPujNKiC/FxSyw43OUTGYXI0fpRq AOHNlmN3j0pGcvOsWve5IrBKDSUS7IQlDu6XSCIbPQspf0ordAg2NiT+aQ1rn2aydTyu GYz4igdu/AbcnPyHtRHaWcRtKcSJ96SvZfGx/9p8hKRfxtiFccmfgcC2gO3orPBk1mns BYgA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=h3GNJ4vb; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-137102-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-137102-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id k8-20020a170902c40800b001dee4bd73f3si8920329plk.599.2024.04.09.07.41.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Apr 2024 07:41:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-137102-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=h3GNJ4vb; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-137102-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-137102-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id DD78E286F3A for ; Tue, 9 Apr 2024 14:40:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 775221332BA; Tue, 9 Apr 2024 14:38:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="h3GNJ4vb" Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0063485652; Tue, 9 Apr 2024 14:38:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712673514; cv=none; b=h66pf4D6eFf4juPFNF03Q/xPmh6ZpoRB9LfMgRklS4zunTk8QDpNv5R9SG4yzNPmTRLpFjasZAWfSV3N4YJesQzU3/b5j/aXsUiKrzrsPvvSnU6dBT1ZRlzYsTBzZBf3szNYjsXpgB6tbr2VSYjamQnCi3IFFbWYo/+730rvK8g= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712673514; c=relaxed/simple; bh=ipY0k1EXJLopR2TB/j1i2URCq+Jnt9wZIjipMzoK3TY=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=ZS/6K44VTUXNVPbNNAMaNMl39tz9ODJ6aDWAIoe6ZDYaM4JWuAwUcsjZicn58RXrg2nu4oBGupGKMDA4mdbWtOaMHaCIjn1ZFaDR6E/hnVP5urAbNp6jlgkVNd7MS6jfF99aSLIToGzK3iwxZriyROUq5irrR+68KcbM6w4U8mw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=h3GNJ4vb; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 439EcAgL079405; Tue, 9 Apr 2024 09:38:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1712673490; bh=haEpmy5VhtEasqeLLSLULQyED9X5Xlmx8DrgXvQysfQ=; h=Date:Subject:To:CC:References:From:In-Reply-To; b=h3GNJ4vbNk4R79xkgSdUjOZcLEgCi/LUM3Ojj2nG7jw/60V4TcQIlc0rICQ4Cpxya JlZkXiSgVGX8KeXUMFzRUni9In8fY/gDNqbMDVCz8a0nG7AW0U7DldBXoxwBnFMgx8 hbo/kvwmzUthkHlvIRxE51R8XWvRb6nhmPACpuv8= Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 439EcAgF012015 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 9 Apr 2024 09:38:10 -0500 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Tue, 9 Apr 2024 09:38:09 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Tue, 9 Apr 2024 09:38:09 -0500 Received: from [10.249.42.149] ([10.249.42.149]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 439Ec9xP024183; Tue, 9 Apr 2024 09:38:09 -0500 Message-ID: <17f4e562-a218-466c-9ac7-171e8780af60@ti.com> Date: Tue, 9 Apr 2024 09:38:09 -0500 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 2/2] misc: sram: Add DMA-BUF Heap exporting of SRAM areas To: Pascal FONTAIN , , Derek Kiernan , Dragan Cvetic , Arnd Bergmann , Greg Kroah-Hartman , Sumit Semwal , =?UTF-8?Q?Christian_K=C3=B6nig?= , Robin Murphy CC: , , References: <20240409120605.4138472-1-Pascal.FONTAIN@bachmann.info> <20240409120605.4138472-3-Pascal.FONTAIN@bachmann.info> Content-Language: en-US From: Andrew Davis In-Reply-To: <20240409120605.4138472-3-Pascal.FONTAIN@bachmann.info> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 On 4/9/24 7:06 AM, Pascal FONTAIN wrote: > From: Andrew Davis > > This new export type exposes to userspace the SRAM area as a DMA-BUF > Heap, > this allows for allocations of DMA-BUFs that can be consumed by various > DMA-BUF supporting devices. > > Signed-off-by: Andrew Davis > Tested-by: Pascal Fontain > --- The last time I posted this I got this comment[0], for which I didn't really have a good response and so haven't reposted this since then. Bacically this driver is backed by something other than "normal" memory. So we really need to be careful here, the page pointer is really just a cookie to keep track for the real mappings. We might be able to use something similar to dma_get_sgtable() to hide that, but under the hood it would still a bit unsafe[1]. Andrew [0] https://patchwork.kernel.org/project/linux-media/patch/20230713191316.116019-1-afd@ti.com/#25475464 [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c#n388 > drivers/misc/Kconfig | 7 + > drivers/misc/Makefile | 1 + > drivers/misc/sram-dma-heap.c | 246 +++++++++++++++++++++++++++++++++++ > drivers/misc/sram.c | 6 + > drivers/misc/sram.h | 16 +++ > 5 files changed, 276 insertions(+) > create mode 100644 drivers/misc/sram-dma-heap.c > > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig > index 9e4ad4d61f06..e6674e913168 100644 > --- a/drivers/misc/Kconfig > +++ b/drivers/misc/Kconfig > @@ -448,6 +448,13 @@ config SRAM > config SRAM_EXEC > bool > > +config SRAM_DMA_HEAP > + bool "Export on-chip SRAM pools using DMA-Heaps" > + depends on DMABUF_HEAPS && SRAM > + help > + This driver allows the export of on-chip SRAM marked as both pool > + and exportable to userspace using the DMA-Heaps interface. > + > config DW_XDATA_PCIE > depends on PCI > tristate "Synopsys DesignWare xData PCIe driver" > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile > index cdc6405584e3..63effdde5163 100644 > --- a/drivers/misc/Makefile > +++ b/drivers/misc/Makefile > @@ -47,6 +47,7 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ > obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o > obj-$(CONFIG_SRAM) += sram.o > obj-$(CONFIG_SRAM_EXEC) += sram-exec.o > +obj-$(CONFIG_SRAM_DMA_HEAP) += sram-dma-heap.o > obj-$(CONFIG_GENWQE) += genwqe/ > obj-$(CONFIG_ECHO) += echo/ > obj-$(CONFIG_CXL_BASE) += cxl/ > diff --git a/drivers/misc/sram-dma-heap.c b/drivers/misc/sram-dma-heap.c > new file mode 100644 > index 000000000000..e5a0bafe8cb9 > --- /dev/null > +++ b/drivers/misc/sram-dma-heap.c > @@ -0,0 +1,246 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * SRAM DMA-Heap userspace exporter > + * > + * Copyright (C) 2019-2022 Texas Instruments Incorporated - https://www.ti.com/ > + * Andrew Davis > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "sram.h" > + > +struct sram_dma_heap { > + struct dma_heap *heap; > + struct gen_pool *pool; > +}; > + > +struct sram_dma_heap_buffer { > + struct gen_pool *pool; > + struct list_head attachments; > + struct mutex attachments_lock; > + unsigned long len; > + void *vaddr; > + phys_addr_t paddr; > +}; > + > +struct dma_heap_attachment { > + struct device *dev; > + struct sg_table *table; > + struct list_head list; > +}; > + > +static int dma_heap_attach(struct dma_buf *dmabuf, > + struct dma_buf_attachment *attachment) > +{ > + struct sram_dma_heap_buffer *buffer = dmabuf->priv; > + struct dma_heap_attachment *a; > + struct sg_table *table; > + > + a = kzalloc(sizeof(*a), GFP_KERNEL); > + if (!a) > + return -ENOMEM; > + > + table = kmalloc(sizeof(*table), GFP_KERNEL); > + if (!table) { > + kfree(a); > + return -ENOMEM; > + } > + if (sg_alloc_table(table, 1, GFP_KERNEL)) { > + kfree(table); > + kfree(a); > + return -ENOMEM; > + } > + sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->paddr)), buffer->len, 0); > + > + a->table = table; > + a->dev = attachment->dev; > + INIT_LIST_HEAD(&a->list); > + > + attachment->priv = a; > + > + mutex_lock(&buffer->attachments_lock); > + list_add(&a->list, &buffer->attachments); > + mutex_unlock(&buffer->attachments_lock); > + > + return 0; > +} > + > +static void dma_heap_detatch(struct dma_buf *dmabuf, > + struct dma_buf_attachment *attachment) > +{ > + struct sram_dma_heap_buffer *buffer = dmabuf->priv; > + struct dma_heap_attachment *a = attachment->priv; > + > + mutex_lock(&buffer->attachments_lock); > + list_del(&a->list); > + mutex_unlock(&buffer->attachments_lock); > + > + sg_free_table(a->table); > + kfree(a->table); > + kfree(a); > +} > + > +static struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment, > + enum dma_data_direction direction) > +{ > + struct dma_heap_attachment *a = attachment->priv; > + struct sg_table *table = a->table; > + > + /* > + * As this heap is backed by uncached SRAM memory we do not need to > + * perform any sync operations on the buffer before allowing device > + * domain access. For this reason we use SKIP_CPU_SYNC and also do > + * not use or provide begin/end_cpu_access() dma-buf functions. > + */ > + if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents, > + direction, DMA_ATTR_SKIP_CPU_SYNC)) > + return ERR_PTR(-ENOMEM); > + > + return table; > +} > + > +static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, > + struct sg_table *table, > + enum dma_data_direction direction) > +{ > + dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents, > + direction, DMA_ATTR_SKIP_CPU_SYNC); > +} > + > +static void dma_heap_dma_buf_release(struct dma_buf *dmabuf) > +{ > + struct sram_dma_heap_buffer *buffer = dmabuf->priv; > + > + gen_pool_free(buffer->pool, (unsigned long)buffer->vaddr, buffer->len); > + kfree(buffer); > +} > + > +static int dma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) > +{ > + struct sram_dma_heap_buffer *buffer = dmabuf->priv; > + int ret; > + > + /* SRAM mappings are not cached */ > + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); > + > + ret = vm_iomap_memory(vma, buffer->paddr, buffer->len); > + if (ret) > + pr_err("Could not map buffer to userspace\n"); > + > + return ret; > +} > + > +static int dma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map) > +{ > + struct sram_dma_heap_buffer *buffer = dmabuf->priv; > + > + iosys_map_set_vaddr(map, buffer->vaddr); > + > + return 0; > +} > + > +static const struct dma_buf_ops sram_dma_heap_buf_ops = { > + .attach = dma_heap_attach, > + .detach = dma_heap_detatch, > + .map_dma_buf = dma_heap_map_dma_buf, > + .unmap_dma_buf = dma_heap_unmap_dma_buf, > + .release = dma_heap_dma_buf_release, > + .mmap = dma_heap_mmap, > + .vmap = dma_heap_vmap, > +}; > + > +static struct dma_buf *sram_dma_heap_allocate(struct dma_heap *heap, > + unsigned long len, > + unsigned long fd_flags, > + unsigned long heap_flags) > +{ > + struct sram_dma_heap *sram_dma_heap = dma_heap_get_drvdata(heap); > + struct sram_dma_heap_buffer *buffer; > + > + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); > + struct dma_buf *dmabuf; > + int ret; > + > + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); > + if (!buffer) > + return ERR_PTR(-ENOMEM); > + buffer->pool = sram_dma_heap->pool; > + INIT_LIST_HEAD(&buffer->attachments); > + mutex_init(&buffer->attachments_lock); > + buffer->len = len; > + > + buffer->vaddr = (void *)gen_pool_alloc(buffer->pool, buffer->len); > + if (!buffer->vaddr) { > + ret = -ENOMEM; > + goto free_buffer; > + } > + > + buffer->paddr = gen_pool_virt_to_phys(buffer->pool, (unsigned long)buffer->vaddr); > + if (buffer->paddr == -1) { > + ret = -ENOMEM; > + goto free_pool; > + } > + > + /* create the dmabuf */ > + exp_info.exp_name = dma_heap_get_name(heap); > + exp_info.ops = &sram_dma_heap_buf_ops; > + exp_info.size = buffer->len; > + exp_info.flags = fd_flags; > + exp_info.priv = buffer; > + dmabuf = dma_buf_export(&exp_info); > + if (IS_ERR(dmabuf)) { > + ret = PTR_ERR(dmabuf); > + goto free_pool; > + } > + > + return dmabuf; > + > +free_pool: > + gen_pool_free(buffer->pool, (unsigned long)buffer->vaddr, buffer->len); > +free_buffer: > + kfree(buffer); > + > + return ERR_PTR(ret); > +} > + > +static struct dma_heap_ops sram_dma_heap_ops = { > + .allocate = sram_dma_heap_allocate, > +}; > + > +int sram_add_dma_heap(struct sram_dev *sram, > + struct sram_reserve *block, > + phys_addr_t start, > + struct sram_partition *part) > +{ > + struct sram_dma_heap *sram_dma_heap; > + struct dma_heap_export_info exp_info; > + > + dev_info(sram->dev, "Exporting SRAM Heap '%s'\n", block->label); > + > + sram_dma_heap = kzalloc(sizeof(*sram_dma_heap), GFP_KERNEL); > + if (!sram_dma_heap) > + return -ENOMEM; > + sram_dma_heap->pool = part->pool; > + > + exp_info.name = kasprintf(GFP_KERNEL, "sram_%s", block->label); > + exp_info.ops = &sram_dma_heap_ops; > + exp_info.priv = sram_dma_heap; > + sram_dma_heap->heap = dma_heap_add(&exp_info); > + if (IS_ERR(sram_dma_heap->heap)) { > + int ret = PTR_ERR(sram_dma_heap->heap); > + > + kfree(sram_dma_heap); > + return ret; > + } > + > + return 0; > +} > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c > index 632f90d9bcea..643c77598beb 100644 > --- a/drivers/misc/sram.c > +++ b/drivers/misc/sram.c > @@ -120,6 +120,12 @@ static int sram_add_partition(struct sram_dev *sram, struct sram_reserve *block, > ret = sram_add_pool(sram, block, start, part); > if (ret) > return ret; > + > + if (block->export) { > + ret = sram_add_dma_heap(sram, block, start, part); > + if (ret) > + return ret; > + } > } > if (block->export) { > ret = sram_add_export(sram, block, start, part); > diff --git a/drivers/misc/sram.h b/drivers/misc/sram.h > index 397205b8bf6f..062bdd25fa06 100644 > --- a/drivers/misc/sram.h > +++ b/drivers/misc/sram.h > @@ -60,4 +60,20 @@ static inline int sram_add_protect_exec(struct sram_partition *part) > return -ENODEV; > } > #endif /* CONFIG_SRAM_EXEC */ > + > +#ifdef CONFIG_SRAM_DMA_HEAP > +int sram_add_dma_heap(struct sram_dev *sram, > + struct sram_reserve *block, > + phys_addr_t start, > + struct sram_partition *part); > +#else > +static inline int sram_add_dma_heap(struct sram_dev *sram, > + struct sram_reserve *block, > + phys_addr_t start, > + struct sram_partition *part) > +{ > + return 0; > +} > +#endif /* CONFIG_SRAM_DMA_HEAP */ > + > #endif /* __SRAM_H */