Am 20.09.2017 um 13:42 schrieb Tom St Denis: > 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 at amd.com> Reviewed-by: Christan König <christian.koenig at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 90 +++++---------------------------- > 1 file changed, 13 insertions(+), 77 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index 0e5f78f3a97e..ce435dbbb398 100644 > --- 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(struct file *f, 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; > > - 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; > -} > + // always return 8 bytes > + if (size != 8) > + return -EINVAL; > > -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; > + // 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 > }; >