Message ID | 20170918123528.26629-3-tom.stdenis@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Am 18.09.2017 um 14:35 schrieb Tom St Denis: > Signed-off-by: Tom St Denis <tom.stdenis@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 32 ++++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index 7848ffa99eb4..b4c298925e2a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -43,6 +43,7 @@ > #include <linux/swap.h> > #include <linux/pagemap.h> > #include <linux/debugfs.h> > +#include <linux/iommu.h> > #include "amdgpu.h" > #include "amdgpu_trace.h" > #include "bif/bif_4_1_d.h" > @@ -1810,6 +1811,36 @@ static const struct file_operations amdgpu_ttm_gtt_fops = { > #endif > > > +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; > + int r; > + uint64_t phys; > + > + // always return 8 bytes > + if (size != 8) > + return -EINVAL; > + > + // only accept page addresses > + if (*pos & 0xFFF) > + return -EINVAL; > + > + > + phys = iommu_iova_to_phys(iommu_get_domain_for_dev(adev->dev), *pos); Well how about adding directly read/write support for the page behind the address? This way we won't need to fiddle with /dev/mem any more either. Christian. > + > + r = copy_to_user(buf, &phys, 8); > + if (r) > + return -EFAULT; > + > + return 8; > +} > + > +static const struct file_operations amdgpu_ttm_iova_fops = { > + .owner = THIS_MODULE, > + .read = amdgpu_iova_to_phys_read, > + .llseek = default_llseek > +}; > > static const struct { > char *name; > @@ -1819,6 +1850,7 @@ static const struct { > #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS > { "amdgpu_gtt", &amdgpu_ttm_gtt_fops }, > #endif > + { "amdgpu_iova", &amdgpu_ttm_iova_fops }, > }; > > #endif
On 18/09/17 08:52 AM, Christian König wrote: > Am 18.09.2017 um 14:35 schrieb Tom St Denis: >> Signed-off-by: Tom St Denis <tom.stdenis@amd.com> >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 32 >> ++++++++++++++++++++++++++++++++ >> 1 file changed, 32 insertions(+) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> index 7848ffa99eb4..b4c298925e2a 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> @@ -43,6 +43,7 @@ >> #include <linux/swap.h> >> #include <linux/pagemap.h> >> #include <linux/debugfs.h> >> +#include <linux/iommu.h> >> #include "amdgpu.h" >> #include "amdgpu_trace.h" >> #include "bif/bif_4_1_d.h" >> @@ -1810,6 +1811,36 @@ static const struct file_operations >> amdgpu_ttm_gtt_fops = { >> #endif >> +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; >> + int r; >> + uint64_t phys; >> + >> + // always return 8 bytes >> + if (size != 8) >> + return -EINVAL; >> + >> + // only accept page addresses >> + if (*pos & 0xFFF) >> + return -EINVAL; >> + >> + >> + phys = iommu_iova_to_phys(iommu_get_domain_for_dev(adev->dev), >> *pos); > > Well how about adding directly read/write support for the page behind > the address? > > This way we won't need to fiddle with /dev/mem any more either. Given the flak we got from requesting this from the iommu team I'm worried that might not be appreciated by the community (even though we maintain this part of the tree) and hurt our abilities to upstream. I agree that adding a read/write method would be better though since we don't need config changes of /dev/fmem anymore. Tom
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 7848ffa99eb4..b4c298925e2a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -43,6 +43,7 @@ #include <linux/swap.h> #include <linux/pagemap.h> #include <linux/debugfs.h> +#include <linux/iommu.h> #include "amdgpu.h" #include "amdgpu_trace.h" #include "bif/bif_4_1_d.h" @@ -1810,6 +1811,36 @@ static const struct file_operations amdgpu_ttm_gtt_fops = { #endif +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; + int r; + uint64_t phys; + + // always return 8 bytes + if (size != 8) + return -EINVAL; + + // only accept page addresses + if (*pos & 0xFFF) + return -EINVAL; + + + phys = iommu_iova_to_phys(iommu_get_domain_for_dev(adev->dev), *pos); + + r = copy_to_user(buf, &phys, 8); + if (r) + return -EFAULT; + + return 8; +} + +static const struct file_operations amdgpu_ttm_iova_fops = { + .owner = THIS_MODULE, + .read = amdgpu_iova_to_phys_read, + .llseek = default_llseek +}; static const struct { char *name; @@ -1819,6 +1850,7 @@ static const struct { #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS { "amdgpu_gtt", &amdgpu_ttm_gtt_fops }, #endif + { "amdgpu_iova", &amdgpu_ttm_iova_fops }, }; #endif
Signed-off-by: Tom St Denis <tom.stdenis@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)