lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1512060411-729-7-git-send-email-loic.pallardy@st.com>
Date:   Thu, 30 Nov 2017 17:46:41 +0100
From:   Loic Pallardy <loic.pallardy@...com>
To:     <bjorn.andersson@...aro.org>, <ohad@...ery.com>
CC:     <linux-remoteproc@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <arnaud.pouliquen@...com>, <benjamin.gaignard@...aro.org>,
        Loic Pallardy <loic.pallardy@...com>
Subject: [PATCH v2 06/16] remoteproc: modify vring allocation to support preallocated region

Current version of rproc_alloc_vring function supports only dynamic vring
allocation.
This patch extends rproc_alloc_vring to verify if requested vring DA is
already part or not of a registered carveout. If true, nothing to do, else
just allocate vring as before.

Signed-off-by: Loic Pallardy <loic.pallardy@...com>
---
 drivers/remoteproc/remoteproc_core.c | 53 +++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 515a17a..bdc99cd 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -263,21 +263,41 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	struct device *dev = &rproc->dev;
 	struct rproc_vring *rvring = &rvdev->vring[i];
 	struct fw_rsc_vdev *rsc;
-	dma_addr_t dma;
+	dma_addr_t dma = -1;
 	void *va;
 	int ret, size, notifyid;
 
 	/* actual size of vring (in bytes) */
 	size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 
-	/*
-	 * Allocate non-cacheable memory for the vring. In the future
-	 * this call will also configure the IOMMU for us
-	 */
-	va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
-	if (!va) {
-		dev_err(dev->parent, "dma_alloc_coherent failed\n");
-		return -EINVAL;
+	/* get vring resource table pointer */
+	rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
+
+	if (rsc->vring[i].da != FW_RSC_ADDR_ANY) {
+		va = rproc_find_carveout_by_da(rproc, rsc->vring[i].da, size);
+
+		if (!va) {
+			/* No region not found */
+			dev_err(dev->parent, "Pre-allocated vring not found\n");
+			return -ENOMEM;
+		}
+	} else {
+		/*
+		 * Allocate non-cacheable memory for the vring. In the future
+		 * this call will also configure the IOMMU for us
+		 */
+		va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
+		if (!va) {
+			dev_err(dev->parent, "dma_alloc_coherent failed\n");
+			return -EINVAL;
+		}
+		/*
+		 * Let the rproc know the da of this vring.
+		 * Not all platforms use dma_alloc_coherent to automatically
+		 * set up the iommu. In this case the device address (da) will
+		 * hold the physical address and not the device address.
+		 */
+		rsc->vring[i].da = dma;
 	}
 
 	/*
@@ -288,7 +308,8 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL);
 	if (ret < 0) {
 		dev_err(dev, "idr_alloc failed: %d\n", ret);
-		dma_free_coherent(dev->parent, size, va, dma);
+		if (dma != -1)
+			dma_free_coherent(dev->parent, size, va, dma);
 		return ret;
 	}
 	notifyid = ret;
@@ -304,14 +325,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	rvring->dma = dma;
 	rvring->notifyid = notifyid;
 
-	/*
-	 * Let the rproc know the notifyid and da of this vring.
-	 * Not all platforms use dma_alloc_coherent to automatically
-	 * set up the iommu. In this case the device address (da) will
-	 * hold the physical address and not the device address.
-	 */
-	rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
-	rsc->vring[i].da = dma;
+	/* Let the rproc know the notifyid of this vring. */
 	rsc->vring[i].notifyid = notifyid;
 	return 0;
 }
@@ -348,7 +362,8 @@ void rproc_free_vring(struct rproc_vring *rvring)
 	int idx = rvring->rvdev->vring - rvring;
 	struct fw_rsc_vdev *rsc;
 
-	dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
+	if (rvring->dma != -1)
+		dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
 	idr_remove(&rproc->notifyids, rvring->notifyid);
 
 	/* reset resource entry info */
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ