Blob Blame History Raw
From: Tom St Denis <tom.stdenis@amd.com>
Date: Tue, 19 Sep 2017 11:29:04 -0400
Subject: drm/amd/amdgpu: Partial revert of iova debugfs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 10cfafd62af4295abc73cbf4531654d4f335ff15
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

We discovered that on some devices even with iommu enabled
you can access all of system memory through the iommu translation.

Therefore, we revert the read method to the translation only service
and drop the write method completely.

Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
Reviewed-by: Christan König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |   92 ++++----------------------------
 1 file changed, 14 insertions(+), 78 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1784,98 +1784,34 @@ static ssize_t amdgpu_iova_to_phys_read(
 				   size_t size, loff_t *pos)
 {
 	struct amdgpu_device *adev = file_inode(f)->i_private;
-	ssize_t result, n;
 	int r;
 	uint64_t phys;
-	void *ptr;
 	struct iommu_domain *dom;
 
-	dom = iommu_get_domain_for_dev(adev->dev);
-	if (!dom)
-		return -EFAULT;
-
-	result = 0;
-	while (size) {
-		// get physical address and map
-		phys = iommu_iova_to_phys(dom, *pos);
-
-		// copy upto one page
-		if (size > PAGE_SIZE)
-			n = PAGE_SIZE;
-		else
-			n = size;
-
-		// to end of the page
-		if (((*pos & (PAGE_SIZE - 1)) + n) >= PAGE_SIZE)
-			n = PAGE_SIZE - (*pos & (PAGE_SIZE - 1));
-
-		ptr = kmap(pfn_to_page(PFN_DOWN(phys)));
-		if (!ptr)
-			return -EFAULT;
-
-		r = copy_to_user(buf, ptr, n);
-		kunmap(pfn_to_page(PFN_DOWN(phys)));
-		if (r)
-			return -EFAULT;
-
-		*pos += n;
-		size -= n;
-		result += n;
-	}
-
-	return result;
-}
-
-static ssize_t amdgpu_iova_to_phys_write(struct file *f, const char __user *buf,
-				   size_t size, loff_t *pos)
-{
-	struct amdgpu_device *adev = file_inode(f)->i_private;
-	ssize_t result, n;
-	int r;
-	uint64_t phys;
-	void *ptr;
-	struct iommu_domain *dom;
+	// always return 8 bytes
+	if (size != 8)
+		return -EINVAL;
+
+	// only accept page addresses
+	if (*pos & 0xFFF)
+		return -EINVAL;
 
 	dom = iommu_get_domain_for_dev(adev->dev);
-	if (!dom)
-		return -EFAULT;
-
-	result = 0;
-	while (size) {
-		// get physical address and map
+	if (dom)
 		phys = iommu_iova_to_phys(dom, *pos);
+	else
+		phys = *pos;
 
-		// copy upto one page
-		if (size > PAGE_SIZE)
-			n = PAGE_SIZE;
-		else
-			n = size;
-
-		// to end of the page
-		if (((*pos & (PAGE_SIZE - 1)) + n) >= PAGE_SIZE)
-			n = PAGE_SIZE - (*pos & (PAGE_SIZE - 1));
-
-		ptr = kmap(pfn_to_page(PFN_DOWN(phys)));
-		if (!ptr)
-			return -EFAULT;
-
-		r = copy_from_user(ptr, buf, n);
-		kunmap(pfn_to_page(PFN_DOWN(phys)));
-		if (r)
-			return -EFAULT;
-
-		*pos += n;
-		size -= n;
-		result += n;
-	}
+	r = copy_to_user(buf, &phys, 8);
+	if (r)
+		return -EFAULT;
 
-	return result;
+	return 8;
 }
 
 static const struct file_operations amdgpu_ttm_iova_fops = {
 	.owner = THIS_MODULE,
 	.read = amdgpu_iova_to_phys_read,
-	.write = amdgpu_iova_to_phys_write,
 	.llseek = default_llseek
 };