aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
diff options
context:
space:
mode:
authorTom St Denis <tom.stdenis@amd.com>2018-02-23 09:46:23 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-03-07 16:11:54 -0500
commitebb043f267511a6e6ba2ee92e0146552432e8db2 (patch)
treeebc6fce5998699ce67ded595ce58c298ef7658aa /drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
parent65e4b49019029e7effcfc7855af822cd75f28c47 (diff)
drm/amdgpu: replace iova debugfs file with iomem (v3)
This allows access to pages allocated through the driver with optional IOMMU mapping. v2: Fix number of bytes copied and add write method v3: drop check for kmap return Original-by: Christian König <christian.koenig@amd.com> Signed-off-by: Tom St Denis <tom.stdenis@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index b19a4f7a845e..28c33d711bab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1957,38 +1957,98 @@ static const struct file_operations amdgpu_ttm_gtt_fops = {
1957 1957
1958#endif 1958#endif
1959 1959
1960static ssize_t amdgpu_iova_to_phys_read(struct file *f, char __user *buf, 1960static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
1961 size_t size, loff_t *pos) 1961 size_t size, loff_t *pos)
1962{ 1962{
1963 struct amdgpu_device *adev = file_inode(f)->i_private; 1963 struct amdgpu_device *adev = file_inode(f)->i_private;
1964 int r;
1965 uint64_t phys;
1966 struct iommu_domain *dom; 1964 struct iommu_domain *dom;
1965 ssize_t result = 0;
1966 int r;
1967 1967
1968 // always return 8 bytes 1968 dom = iommu_get_domain_for_dev(adev->dev);
1969 if (size != 8)
1970 return -EINVAL;
1971 1969
1972 // only accept page addresses 1970 while (size) {
1973 if (*pos & 0xFFF) 1971 phys_addr_t addr = *pos & PAGE_MASK;
1974 return -EINVAL; 1972 loff_t off = *pos & ~PAGE_MASK;
1973 size_t bytes = PAGE_SIZE - off;
1974 unsigned long pfn;
1975 struct page *p;
1976 void *ptr;
1977
1978 bytes = bytes < size ? bytes : size;
1979
1980 addr = dom ? iommu_iova_to_phys(dom, addr) : addr;
1981
1982 pfn = addr >> PAGE_SHIFT;
1983 if (!pfn_valid(pfn))
1984 return -EPERM;
1985
1986 p = pfn_to_page(pfn);
1987 if (p->mapping != adev->mman.bdev.dev_mapping)
1988 return -EPERM;
1989
1990 ptr = kmap(p);
1991 r = copy_to_user(buf, ptr, bytes);
1992 kunmap(p);
1993 if (r)
1994 return -EFAULT;
1995
1996 size -= bytes;
1997 *pos += bytes;
1998 result += bytes;
1999 }
2000
2001 return result;
2002}
2003
2004static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf,
2005 size_t size, loff_t *pos)
2006{
2007 struct amdgpu_device *adev = file_inode(f)->i_private;
2008 struct iommu_domain *dom;
2009 ssize_t result = 0;
2010 int r;
1975 2011
1976 dom = iommu_get_domain_for_dev(adev->dev); 2012 dom = iommu_get_domain_for_dev(adev->dev);
1977 if (dom)
1978 phys = iommu_iova_to_phys(dom, *pos);
1979 else
1980 phys = *pos;
1981 2013
1982 r = copy_to_user(buf, &phys, 8); 2014 while (size) {
1983 if (r) 2015 phys_addr_t addr = *pos & PAGE_MASK;
1984 return -EFAULT; 2016 loff_t off = *pos & ~PAGE_MASK;
2017 size_t bytes = PAGE_SIZE - off;
2018 unsigned long pfn;
2019 struct page *p;
2020 void *ptr;
2021
2022 bytes = bytes < size ? bytes : size;
1985 2023
1986 return 8; 2024 addr = dom ? iommu_iova_to_phys(dom, addr) : addr;
2025
2026 pfn = addr >> PAGE_SHIFT;
2027 if (!pfn_valid(pfn))
2028 return -EPERM;
2029
2030 p = pfn_to_page(pfn);
2031 if (p->mapping != adev->mman.bdev.dev_mapping)
2032 return -EPERM;
2033
2034 ptr = kmap(p);
2035 r = copy_from_user(ptr, buf, bytes);
2036 kunmap(p);
2037 if (r)
2038 return -EFAULT;
2039
2040 size -= bytes;
2041 *pos += bytes;
2042 result += bytes;
2043 }
2044
2045 return result;
1987} 2046}
1988 2047
1989static const struct file_operations amdgpu_ttm_iova_fops = { 2048static const struct file_operations amdgpu_ttm_iomem_fops = {
1990 .owner = THIS_MODULE, 2049 .owner = THIS_MODULE,
1991 .read = amdgpu_iova_to_phys_read, 2050 .read = amdgpu_iomem_read,
2051 .write = amdgpu_iomem_write,
1992 .llseek = default_llseek 2052 .llseek = default_llseek
1993}; 2053};
1994 2054
@@ -2001,7 +2061,7 @@ static const struct {
2001#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS 2061#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
2002 { "amdgpu_gtt", &amdgpu_ttm_gtt_fops, TTM_PL_TT }, 2062 { "amdgpu_gtt", &amdgpu_ttm_gtt_fops, TTM_PL_TT },
2003#endif 2063#endif
2004 { "amdgpu_iova", &amdgpu_ttm_iova_fops, TTM_PL_SYSTEM }, 2064 { "amdgpu_iomem", &amdgpu_ttm_iomem_fops, TTM_PL_SYSTEM },
2005}; 2065};
2006 2066
2007#endif 2067#endif