diff mbox

[5/6] drm/radeon: add VRAM debugfs access

Message ID 1386837762-8375-6-git-send-email-deathsimple@vodafone.de (mailing list archive)
State New, archived
Headers show

Commit Message

Christian König Dec. 12, 2013, 8:42 a.m. UTC
From: Christian König <christian.koenig@amd.com>

Not very fast, but makes it possible to access even the
normally inaccessible parts of VRAM from userspace.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/radeon.h     |  4 +++
 drivers/gpu/drm/radeon/radeon_ttm.c | 72 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 1 deletion(-)

Comments

Alex Deucher Dec. 12, 2013, 1:31 p.m. UTC | #1
On Thu, Dec 12, 2013 at 3:42 AM, Christian König
<deathsimple@vodafone.de> wrote:
> From: Christian König <christian.koenig@amd.com>
>
> Not very fast, but makes it possible to access even the
> normally inaccessible parts of VRAM from userspace.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/radeon/radeon.h     |  4 +++
>  drivers/gpu/drm/radeon/radeon_ttm.c | 72 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 75 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index b1f990d..49f210c1 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -413,6 +413,10 @@ struct radeon_mman {
>         struct ttm_bo_device            bdev;
>         bool                            mem_global_referenced;
>         bool                            initialized;
> +
> +#if defined(CONFIG_DEBUG_FS)
> +       struct dentry                   *vram;
> +#endif
>  };
>
>  /* bo virtual address in a specific vm */
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index a2d6c4f..f5e8eed 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -39,12 +39,14 @@
>  #include <linux/seq_file.h>
>  #include <linux/slab.h>
>  #include <linux/swiotlb.h>
> +#include <linux/debugfs.h>
>  #include "radeon_reg.h"
>  #include "radeon.h"
>
>  #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
>
>  static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
>
>  static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
>  {
> @@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
>
>         if (!rdev->mman.initialized)
>                 return;
> +       radeon_ttm_debugfs_fini(rdev);
>         if (rdev->stollen_vga_memory) {
>                 r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
>                 if (r == 0) {
> @@ -862,12 +865,70 @@ static struct drm_info_list radeon_ttm_debugfs_list[] = {
>  #endif
>  };
>
> +static int radeon_ttm_mem_open(struct inode *inode, struct file *filep)
> +{
> +       filep->private_data = inode->i_private;
> +       return 0;
> +}
> +
> +static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
> +                                   size_t size, loff_t *pos)
> +{
> +       struct radeon_device *rdev = f->private_data;
> +       ssize_t result = 0;
> +       int r;
> +
> +       if (size & 0x3 || *pos & 0x3)
> +               return -EINVAL;
> +
> +       while (size) {
> +               unsigned long flags;
> +               uint32_t value;
> +
> +               if (*pos >= rdev->mc.mc_vram_size || *pos >= 0x7FFFFFFF)
> +                       return result;
> +
> +               spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
> +               WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);

Starting with evergreen dGPUs, there is also an MM_INDEX_HI register
at 0x18 for accessing addresses over 30 bits.

Alex


> +               value = RREG32(RADEON_MM_DATA);
> +               spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
> +
> +               r = put_user(value, (uint32_t *)buf);
> +               if (r)
> +                       return r;
> +
> +               result += 4;
> +               buf += 4;
> +               *pos += 4;
> +               size -= 4;
> +       }
> +
> +       return result;
> +}
> +
> +static const struct file_operations radeon_ttm_vram_fops = {
> +       .owner = THIS_MODULE,
> +       .open = radeon_ttm_mem_open,
> +       .read = radeon_ttm_vram_read,
> +};
> +
>  #endif
>
>  static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
>  {
>  #if defined(CONFIG_DEBUG_FS)
> -       unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list);
> +       unsigned count;
> +
> +       struct drm_minor *minor = rdev->ddev->primary;
> +       struct dentry *ent, *root = minor->debugfs_root;
> +
> +       ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
> +                                 rdev, &radeon_ttm_vram_fops);
> +       if (IS_ERR(ent))
> +               return PTR_ERR(ent);
> +       rdev->mman.vram = ent;
> +
> +       count = ARRAY_SIZE(radeon_ttm_debugfs_list);
>
>  #ifdef CONFIG_SWIOTLB
>         if (!swiotlb_nr_tbl())
> @@ -880,3 +941,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
>         return 0;
>  #endif
>  }
> +
> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
> +{
> +#if defined(CONFIG_DEBUG_FS)
> +
> +       debugfs_remove(rdev->mman.vram);
> +       rdev->mman.vram = NULL;
> +#endif
> +}
> --
> 1.8.1.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Christian König Dec. 12, 2013, 1:35 p.m. UTC | #2
Am 12.12.2013 14:31, schrieb Alex Deucher:
> On Thu, Dec 12, 2013 at 3:42 AM, Christian König
> <deathsimple@vodafone.de> wrote:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Not very fast, but makes it possible to access even the
>> normally inaccessible parts of VRAM from userspace.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/radeon/radeon.h     |  4 +++
>>   drivers/gpu/drm/radeon/radeon_ttm.c | 72 ++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 75 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
>> index b1f990d..49f210c1 100644
>> --- a/drivers/gpu/drm/radeon/radeon.h
>> +++ b/drivers/gpu/drm/radeon/radeon.h
>> @@ -413,6 +413,10 @@ struct radeon_mman {
>>          struct ttm_bo_device            bdev;
>>          bool                            mem_global_referenced;
>>          bool                            initialized;
>> +
>> +#if defined(CONFIG_DEBUG_FS)
>> +       struct dentry                   *vram;
>> +#endif
>>   };
>>
>>   /* bo virtual address in a specific vm */
>> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
>> index a2d6c4f..f5e8eed 100644
>> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
>> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
>> @@ -39,12 +39,14 @@
>>   #include <linux/seq_file.h>
>>   #include <linux/slab.h>
>>   #include <linux/swiotlb.h>
>> +#include <linux/debugfs.h>
>>   #include "radeon_reg.h"
>>   #include "radeon.h"
>>
>>   #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
>>
>>   static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
>> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
>>
>>   static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
>>   {
>> @@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
>>
>>          if (!rdev->mman.initialized)
>>                  return;
>> +       radeon_ttm_debugfs_fini(rdev);
>>          if (rdev->stollen_vga_memory) {
>>                  r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
>>                  if (r == 0) {
>> @@ -862,12 +865,70 @@ static struct drm_info_list radeon_ttm_debugfs_list[] = {
>>   #endif
>>   };
>>
>> +static int radeon_ttm_mem_open(struct inode *inode, struct file *filep)
>> +{
>> +       filep->private_data = inode->i_private;
>> +       return 0;
>> +}
>> +
>> +static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
>> +                                   size_t size, loff_t *pos)
>> +{
>> +       struct radeon_device *rdev = f->private_data;
>> +       ssize_t result = 0;
>> +       int r;
>> +
>> +       if (size & 0x3 || *pos & 0x3)
>> +               return -EINVAL;
>> +
>> +       while (size) {
>> +               unsigned long flags;
>> +               uint32_t value;
>> +
>> +               if (*pos >= rdev->mc.mc_vram_size || *pos >= 0x7FFFFFFF)
>> +                       return result;
>> +
>> +               spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
>> +               WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
> Starting with evergreen dGPUs, there is also an MM_INDEX_HI register
> at 0x18 for accessing addresses over 30 bits.

I know, but I wanted to keep that as simple and stupid as possible. I 
mean this code should work from r100 till CIK and except for HAINAN do 
we really have cards with more than 2GB or ram?

And I'm not even sure if radeon_ttm is the right place for this.

Christian.

>
> Alex
>
>
>> +               value = RREG32(RADEON_MM_DATA);
>> +               spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
>> +
>> +               r = put_user(value, (uint32_t *)buf);
>> +               if (r)
>> +                       return r;
>> +
>> +               result += 4;
>> +               buf += 4;
>> +               *pos += 4;
>> +               size -= 4;
>> +       }
>> +
>> +       return result;
>> +}
>> +
>> +static const struct file_operations radeon_ttm_vram_fops = {
>> +       .owner = THIS_MODULE,
>> +       .open = radeon_ttm_mem_open,
>> +       .read = radeon_ttm_vram_read,
>> +};
>> +
>>   #endif
>>
>>   static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
>>   {
>>   #if defined(CONFIG_DEBUG_FS)
>> -       unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list);
>> +       unsigned count;
>> +
>> +       struct drm_minor *minor = rdev->ddev->primary;
>> +       struct dentry *ent, *root = minor->debugfs_root;
>> +
>> +       ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
>> +                                 rdev, &radeon_ttm_vram_fops);
>> +       if (IS_ERR(ent))
>> +               return PTR_ERR(ent);
>> +       rdev->mman.vram = ent;
>> +
>> +       count = ARRAY_SIZE(radeon_ttm_debugfs_list);
>>
>>   #ifdef CONFIG_SWIOTLB
>>          if (!swiotlb_nr_tbl())
>> @@ -880,3 +941,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
>>          return 0;
>>   #endif
>>   }
>> +
>> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
>> +{
>> +#if defined(CONFIG_DEBUG_FS)
>> +
>> +       debugfs_remove(rdev->mman.vram);
>> +       rdev->mman.vram = NULL;
>> +#endif
>> +}
>> --
>> 1.8.1.2
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Alex Deucher Dec. 12, 2013, 1:44 p.m. UTC | #3
On Thu, Dec 12, 2013 at 8:35 AM, Christian König
<deathsimple@vodafone.de> wrote:
> Am 12.12.2013 14:31, schrieb Alex Deucher:
>
>> On Thu, Dec 12, 2013 at 3:42 AM, Christian König
>> <deathsimple@vodafone.de> wrote:
>>>
>>> From: Christian König <christian.koenig@amd.com>
>>>
>>> Not very fast, but makes it possible to access even the
>>> normally inaccessible parts of VRAM from userspace.
>>>
>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>> ---
>>>   drivers/gpu/drm/radeon/radeon.h     |  4 +++
>>>   drivers/gpu/drm/radeon/radeon_ttm.c | 72
>>> ++++++++++++++++++++++++++++++++++++-
>>>   2 files changed, 75 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/radeon/radeon.h
>>> b/drivers/gpu/drm/radeon/radeon.h
>>> index b1f990d..49f210c1 100644
>>> --- a/drivers/gpu/drm/radeon/radeon.h
>>> +++ b/drivers/gpu/drm/radeon/radeon.h
>>> @@ -413,6 +413,10 @@ struct radeon_mman {
>>>          struct ttm_bo_device            bdev;
>>>          bool                            mem_global_referenced;
>>>          bool                            initialized;
>>> +
>>> +#if defined(CONFIG_DEBUG_FS)
>>> +       struct dentry                   *vram;
>>> +#endif
>>>   };
>>>
>>>   /* bo virtual address in a specific vm */
>>> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c
>>> b/drivers/gpu/drm/radeon/radeon_ttm.c
>>> index a2d6c4f..f5e8eed 100644
>>> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
>>> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
>>> @@ -39,12 +39,14 @@
>>>   #include <linux/seq_file.h>
>>>   #include <linux/slab.h>
>>>   #include <linux/swiotlb.h>
>>> +#include <linux/debugfs.h>
>>>   #include "radeon_reg.h"
>>>   #include "radeon.h"
>>>
>>>   #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
>>>
>>>   static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
>>> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
>>>
>>>   static struct radeon_device *radeon_get_rdev(struct ttm_bo_device
>>> *bdev)
>>>   {
>>> @@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
>>>
>>>          if (!rdev->mman.initialized)
>>>                  return;
>>> +       radeon_ttm_debugfs_fini(rdev);
>>>          if (rdev->stollen_vga_memory) {
>>>                  r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
>>>                  if (r == 0) {
>>> @@ -862,12 +865,70 @@ static struct drm_info_list
>>> radeon_ttm_debugfs_list[] = {
>>>   #endif
>>>   };
>>>
>>> +static int radeon_ttm_mem_open(struct inode *inode, struct file *filep)
>>> +{
>>> +       filep->private_data = inode->i_private;
>>> +       return 0;
>>> +}
>>> +
>>> +static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
>>> +                                   size_t size, loff_t *pos)
>>> +{
>>> +       struct radeon_device *rdev = f->private_data;
>>> +       ssize_t result = 0;
>>> +       int r;
>>> +
>>> +       if (size & 0x3 || *pos & 0x3)
>>> +               return -EINVAL;
>>> +
>>> +       while (size) {
>>> +               unsigned long flags;
>>> +               uint32_t value;
>>> +
>>> +               if (*pos >= rdev->mc.mc_vram_size || *pos >= 0x7FFFFFFF)
>>> +                       return result;
>>> +
>>> +               spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
>>> +               WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
>>
>> Starting with evergreen dGPUs, there is also an MM_INDEX_HI register
>> at 0x18 for accessing addresses over 30 bits.
>
>
> I know, but I wanted to keep that as simple and stupid as possible. I mean
> this code should work from r100 till CIK and except for HAINAN do we really
> have cards with more than 2GB or ram?

Most Hawaii boards are shipping with 4GB and a number of workstation
cards have large amounts of memory.

Alex

>
> And I'm not even sure if radeon_ttm is the right place for this.
>
> Christian.
>
>
>>
>> Alex
>>
>>
>>> +               value = RREG32(RADEON_MM_DATA);
>>> +               spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
>>> +
>>> +               r = put_user(value, (uint32_t *)buf);
>>> +               if (r)
>>> +                       return r;
>>> +
>>> +               result += 4;
>>> +               buf += 4;
>>> +               *pos += 4;
>>> +               size -= 4;
>>> +       }
>>> +
>>> +       return result;
>>> +}
>>> +
>>> +static const struct file_operations radeon_ttm_vram_fops = {
>>> +       .owner = THIS_MODULE,
>>> +       .open = radeon_ttm_mem_open,
>>> +       .read = radeon_ttm_vram_read,
>>> +};
>>> +
>>>   #endif
>>>
>>>   static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
>>>   {
>>>   #if defined(CONFIG_DEBUG_FS)
>>> -       unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list);
>>> +       unsigned count;
>>> +
>>> +       struct drm_minor *minor = rdev->ddev->primary;
>>> +       struct dentry *ent, *root = minor->debugfs_root;
>>> +
>>> +       ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
>>> +                                 rdev, &radeon_ttm_vram_fops);
>>> +       if (IS_ERR(ent))
>>> +               return PTR_ERR(ent);
>>> +       rdev->mman.vram = ent;
>>> +
>>> +       count = ARRAY_SIZE(radeon_ttm_debugfs_list);
>>>
>>>   #ifdef CONFIG_SWIOTLB
>>>          if (!swiotlb_nr_tbl())
>>> @@ -880,3 +941,12 @@ static int radeon_ttm_debugfs_init(struct
>>> radeon_device *rdev)
>>>          return 0;
>>>   #endif
>>>   }
>>> +
>>> +static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
>>> +{
>>> +#if defined(CONFIG_DEBUG_FS)
>>> +
>>> +       debugfs_remove(rdev->mman.vram);
>>> +       rdev->mman.vram = NULL;
>>> +#endif
>>> +}
>>> --
>>> 1.8.1.2
>>>
>>> _______________________________________________
>>> dri-devel mailing list
>>> dri-devel@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b1f990d..49f210c1 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -413,6 +413,10 @@  struct radeon_mman {
 	struct ttm_bo_device		bdev;
 	bool				mem_global_referenced;
 	bool				initialized;
+
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry			*vram;
+#endif
 };
 
 /* bo virtual address in a specific vm */
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index a2d6c4f..f5e8eed 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -39,12 +39,14 @@ 
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/swiotlb.h>
+#include <linux/debugfs.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 
 static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
 
 static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 {
@@ -753,6 +755,7 @@  void radeon_ttm_fini(struct radeon_device *rdev)
 
 	if (!rdev->mman.initialized)
 		return;
+	radeon_ttm_debugfs_fini(rdev);
 	if (rdev->stollen_vga_memory) {
 		r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
 		if (r == 0) {
@@ -862,12 +865,70 @@  static struct drm_info_list radeon_ttm_debugfs_list[] = {
 #endif
 };
 
+static int radeon_ttm_mem_open(struct inode *inode, struct file *filep)
+{
+	filep->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
+				    size_t size, loff_t *pos)
+{
+	struct radeon_device *rdev = f->private_data;
+	ssize_t result = 0;
+	int r;
+
+	if (size & 0x3 || *pos & 0x3)
+		return -EINVAL;
+
+	while (size) {
+		unsigned long flags;
+		uint32_t value;
+
+		if (*pos >= rdev->mc.mc_vram_size || *pos >= 0x7FFFFFFF)
+			return result;
+
+		spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
+		WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
+		value = RREG32(RADEON_MM_DATA);
+		spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
+
+		r = put_user(value, (uint32_t *)buf);
+		if (r)
+			return r;
+
+		result += 4;
+		buf += 4;
+		*pos += 4;
+		size -= 4;
+	}
+
+	return result;
+}
+
+static const struct file_operations radeon_ttm_vram_fops = {
+	.owner = THIS_MODULE,
+	.open = radeon_ttm_mem_open,
+	.read = radeon_ttm_vram_read,
+};
+
 #endif
 
 static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list);
+	unsigned count;
+
+	struct drm_minor *minor = rdev->ddev->primary;
+	struct dentry *ent, *root = minor->debugfs_root;
+
+	ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
+				  rdev, &radeon_ttm_vram_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+	rdev->mman.vram = ent;
+
+	count = ARRAY_SIZE(radeon_ttm_debugfs_list);
 
 #ifdef CONFIG_SWIOTLB
 	if (!swiotlb_nr_tbl())
@@ -880,3 +941,12 @@  static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
 	return 0;
 #endif
 }
+
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+
+	debugfs_remove(rdev->mman.vram);
+	rdev->mman.vram = NULL;
+#endif
+}