From patchwork Tue Oct 4 11:47:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 77247 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp2169821qgf; Tue, 4 Oct 2016 04:47:49 -0700 (PDT) X-Received: by 10.66.166.238 with SMTP id zj14mr4329291pab.205.1475581668942; Tue, 04 Oct 2016 04:47:48 -0700 (PDT) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [2610:10:20:722:a800:ff:fe36:1795]) by mx.google.com with ESMTPS id t15si8548551pfj.65.2016.10.04.04.47.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Oct 2016 04:47:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) client-ip=2610:10:20:722:a800:ff:fe36:1795; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AC6256E624; Tue, 4 Oct 2016 11:47:46 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x22c.google.com (mail-wm0-x22c.google.com [IPv6:2a00:1450:400c:c09::22c]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2460D6E624 for ; Tue, 4 Oct 2016 11:47:45 +0000 (UTC) Received: by mail-wm0-x22c.google.com with SMTP id f193so162799253wmg.0 for ; Tue, 04 Oct 2016 04:47:45 -0700 (PDT) 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=k6rDVOh+epkEooASorCFMAORPkdN2Yr4sJOwVJg4bPA=; b=B4KtD1IWWODi67UypHrXE7B4onr2oj73TBz8rMj7xql2lHnkKmsoDRJxVGmMRk1oQu 4xCSmwqEri5g07zdr92dF0s39ryF8GF2EV6qtibWuaUHYAtEPOoAMVUFEKoMyoGHzvcz IHnO8FQcx3/icqEuOmiRJQgm2ag+J/f656lhc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=k6rDVOh+epkEooASorCFMAORPkdN2Yr4sJOwVJg4bPA=; b=dqelXaroeiYOS/5+/dtf08XyAaZbBC+cQuzhk1yBwRd8o/UBrux1YZ2WU9fH5atRHy 4JLQ8jtd58MKLv+iy9bnDApVowwAdvEoKo2XINoVG4qzWUFGW0WCUQ8YoELjm9L/SXTP bnPcnfVDr/+eHhC25hj8ofp8meHYQxfGLIOj1eVCh4qi4M+wK9WAcQvMkJ3Lwubzrl34 hjhsIzCE09Gp5C/9UkhL64odb1OyFi2g9p1xkSljyUqwv1vK8niNHY5M1D2xTIT9kWep mTkev18y2mCPKp11I1EnuWy8W+5OrPY+dIY5k2U2+aWclzy+f30vDIjtLQgTNgX7PLOC LbUg== X-Gm-Message-State: AA6/9Rnqn3OiyxCHvTcoFrVEWQqAW5Bz5hyop/haZl8HCz8nv8kI4FA4rlvAlYQs6VUCUkyr X-Received: by 10.28.38.69 with SMTP id m66mr13533085wmm.133.1475581662134; Tue, 04 Oct 2016 04:47:42 -0700 (PDT) Received: from lmenx321.st.com. ([80.215.15.251]) by smtp.gmail.com with ESMTPSA id lf3sm3146627wjc.15.2016.10.04.04.47.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 04 Oct 2016 04:47:41 -0700 (PDT) From: Benjamin Gaignard To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, cc.ma@mediatek.com, joakim.bech@linaro.org, burt.lien@linaro.org, linus.walleij@linaro.org Subject: [PATCH v10 2/3] SMAF: add CMA allocator Date: Tue, 4 Oct 2016 13:47:23 +0200 Message-Id: <1475581644-10600-3-git-send-email-benjamin.gaignard@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1475581644-10600-1-git-send-email-benjamin.gaignard@linaro.org> References: <1475581644-10600-1-git-send-email-benjamin.gaignard@linaro.org> Cc: linaro-mm-sig@lists.linaro.org, linaro-kernel@lists.linaro.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" SMAF CMA allocator implement helpers functions to allow SMAF to allocate contiguous memory. match() each if at least one of the attached devices have coherent_dma_mask set to DMA_BIT_MASK(32). For allocation it use dma_alloc_attrs() with DMA_ATTR_WRITE_COMBINE and not dma_alloc_writecombine to be compatible with ARM 64bits architecture Signed-off-by: Benjamin Gaignard --- drivers/smaf/Kconfig | 6 ++ drivers/smaf/Makefile | 1 + drivers/smaf/smaf-cma.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/smaf/smaf-cma.c diff --git a/drivers/smaf/Kconfig b/drivers/smaf/Kconfig index d36651a..cfdfffd 100644 --- a/drivers/smaf/Kconfig +++ b/drivers/smaf/Kconfig @@ -3,3 +3,9 @@ config SMAF depends on DMA_SHARED_BUFFER help Choose this option to enable Secure Memory Allocation Framework + +config SMAF_CMA + tristate "SMAF CMA allocator" + depends on SMAF + help + Choose this option to enable CMA allocation within SMAF diff --git a/drivers/smaf/Makefile b/drivers/smaf/Makefile index 40cd882..05bab01b 100644 --- a/drivers/smaf/Makefile +++ b/drivers/smaf/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_SMAF) += smaf-core.o +obj-$(CONFIG_SMAF_CMA) += smaf-cma.o diff --git a/drivers/smaf/smaf-cma.c b/drivers/smaf/smaf-cma.c new file mode 100644 index 0000000..6c9840b --- /dev/null +++ b/drivers/smaf/smaf-cma.c @@ -0,0 +1,186 @@ +/* + * smaf-cma.c + * + * Copyright (C) Linaro SA 2015 + * Author: Benjamin Gaignard for Linaro. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include + +struct smaf_cma_buffer_info { + struct device *dev; + size_t size; + void *vaddr; + dma_addr_t paddr; +}; + +/** + * find_matching_device - iterate over the attached devices to find one + * with coherent_dma_mask correctly set to DMA_BIT_MASK(32). + * Matching device (if any) will be used to aim CMA area. + */ +static struct device *find_matching_device(struct dma_buf *dmabuf) +{ + struct dma_buf_attachment *attach_obj; + + list_for_each_entry(attach_obj, &dmabuf->attachments, node) { + if (attach_obj->dev->coherent_dma_mask == DMA_BIT_MASK(32)) + return attach_obj->dev; + } + + return NULL; +} + +/** + * smaf_cma_match - return true if at least one device has been found + */ +static bool smaf_cma_match(struct dma_buf *dmabuf) +{ + return !!find_matching_device(dmabuf); +} + +static void smaf_cma_release(struct dma_buf *dmabuf) +{ + struct smaf_cma_buffer_info *info = dmabuf->priv; + + dma_free_attrs(info->dev, info->size, info->vaddr, + info->paddr, DMA_ATTR_WRITE_COMBINE); + + kfree(info); +} + +static struct sg_table *smaf_cma_map(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct smaf_cma_buffer_info *info = attachment->dmabuf->priv; + struct sg_table *sgt; + int ret; + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return NULL; + + ret = dma_get_sgtable(info->dev, sgt, info->vaddr, + info->paddr, info->size); + if (ret < 0) + goto out; + + sg_dma_address(sgt->sgl) = info->paddr; + return sgt; + +out: + kfree(sgt); + return NULL; +} + +static void smaf_cma_unmap(struct dma_buf_attachment *attachment, + struct sg_table *sgt, + enum dma_data_direction direction) +{ + /* do nothing */ +} + +static int smaf_cma_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct smaf_cma_buffer_info *info = dmabuf->priv; + + if (info->size < vma->vm_end - vma->vm_start) + return -EINVAL; + + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; + return dma_mmap_attrs(info->dev, vma, info->vaddr, info->paddr, + info->size, DMA_ATTR_WRITE_COMBINE); +} + +static void *smaf_cma_vmap(struct dma_buf *dmabuf) +{ + struct smaf_cma_buffer_info *info = dmabuf->priv; + + return info->vaddr; +} + +static void *smaf_kmap_atomic(struct dma_buf *dmabuf, unsigned long offset) +{ + struct smaf_cma_buffer_info *info = dmabuf->priv; + + return (void *)info->vaddr + offset; +} + +static const struct dma_buf_ops smaf_cma_ops = { + .map_dma_buf = smaf_cma_map, + .unmap_dma_buf = smaf_cma_unmap, + .mmap = smaf_cma_mmap, + .release = smaf_cma_release, + .kmap_atomic = smaf_kmap_atomic, + .kmap = smaf_kmap_atomic, + .vmap = smaf_cma_vmap, +}; + +static struct dma_buf *smaf_cma_allocate(struct dma_buf *dmabuf, size_t length) +{ + struct dma_buf_attachment *attach_obj; + struct smaf_cma_buffer_info *info; + struct dma_buf *cma_dmabuf; + + DEFINE_DMA_BUF_EXPORT_INFO(export); + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + + info->dev = find_matching_device(dmabuf); + info->size = length; + info->vaddr = dma_alloc_attrs(info->dev, info->size, &info->paddr, + GFP_KERNEL | __GFP_NOWARN, + DMA_ATTR_WRITE_COMBINE); + if (!info->vaddr) + goto alloc_error; + + export.ops = &smaf_cma_ops; + export.size = info->size; + export.priv = info; + + cma_dmabuf = dma_buf_export(&export); + if (IS_ERR(cma_dmabuf)) + goto export_error; + + list_for_each_entry(attach_obj, &dmabuf->attachments, node) { + dma_buf_attach(cma_dmabuf, attach_obj->dev); + } + + return cma_dmabuf; + +export_error: + dma_free_attrs(info->dev, info->size, &info->paddr, + GFP_KERNEL | __GFP_NOWARN, DMA_ATTR_WRITE_COMBINE); +alloc_error: + kfree(info); + return NULL; +} + +static struct smaf_allocator smaf_cma = { + .match = smaf_cma_match, + .allocate = smaf_cma_allocate, + .name = "smaf-cma", + .ranking = 0, +}; + +static int __init smaf_cma_init(void) +{ + return smaf_register_allocator(&smaf_cma); +} +module_init(smaf_cma_init); + +static void __exit smaf_cma_deinit(void) +{ + smaf_unregister_allocator(&smaf_cma); +} +module_exit(smaf_cma_deinit); + +MODULE_DESCRIPTION("SMAF CMA module"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Benjamin Gaignard ");