[PATCH] drm/i915/gvt: Convert from atomic_t to refcount_t on intel_vgpu_ppgtt_spt->refcount

2021-07-17 Thread Xiyu Yang
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/i915/gvt/gtt.c | 11 ++-
 drivers/gpu/drm/i915/gvt/gtt.h |  3 ++-
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index cc2c05e18206..62f3daff5a36 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -841,7 +841,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
}
 
spt->vgpu = vgpu;
-   atomic_set(&spt->refcount, 1);
+   refcount_set(&spt->refcount, 1);
INIT_LIST_HEAD(&spt->post_shadow_list);
 
/*
@@ -927,18 +927,19 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt_gfn(
 
 static inline void ppgtt_get_spt(struct intel_vgpu_ppgtt_spt *spt)
 {
-   int v = atomic_read(&spt->refcount);
+   int v = refcount_read(&spt->refcount);
 
trace_spt_refcount(spt->vgpu->id, "inc", spt, v, (v + 1));
-   atomic_inc(&spt->refcount);
+   refcount_inc(&spt->refcount);
 }
 
 static inline int ppgtt_put_spt(struct intel_vgpu_ppgtt_spt *spt)
 {
-   int v = atomic_read(&spt->refcount);
+   int v = refcount_read(&spt->refcount);
 
trace_spt_refcount(spt->vgpu->id, "dec", spt, v, (v - 1));
-   return atomic_dec_return(&spt->refcount);
+   refcount_dec(&spt->refcount);
+   return refcount_read(&spt->refcount);
 }
 
 static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt);
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index 3bf45672ef98..944c2d0739df 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "gt/intel_gtt.h"
 
@@ -243,7 +244,7 @@ struct intel_vgpu_oos_page {
 
 /* Represent a vgpu shadow page table. */
 struct intel_vgpu_ppgtt_spt {
-   atomic_t refcount;
+   refcount_t refcount;
struct intel_vgpu *vgpu;
 
struct {
-- 
2.7.4



[PATCH] fbmem: Convert from atomic_t to refcount_t on fb_info->count

2021-07-19 Thread Xiyu Yang
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/video/fbdev/core/fbmem.c | 6 +++---
 include/linux/fb.h   | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 98f193078c05..b7d26b928e1d 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -67,7 +67,7 @@ static struct fb_info *get_fb_info(unsigned int idx)
mutex_lock(®istration_lock);
fb_info = registered_fb[idx];
if (fb_info)
-   atomic_inc(&fb_info->count);
+   refcount_inc(&fb_info->count);
mutex_unlock(®istration_lock);
 
return fb_info;
@@ -75,7 +75,7 @@ static struct fb_info *get_fb_info(unsigned int idx)
 
 static void put_fb_info(struct fb_info *fb_info)
 {
-   if (!atomic_dec_and_test(&fb_info->count))
+   if (!refcount_dec_and_test(&fb_info->count))
return;
if (fb_info->fbops->fb_destroy)
fb_info->fbops->fb_destroy(fb_info);
@@ -1594,7 +1594,7 @@ static int do_register_framebuffer(struct fb_info 
*fb_info)
if (!registered_fb[i])
break;
fb_info->node = i;
-   atomic_set(&fb_info->count, 1);
+   refcount_set(&fb_info->count, 1);
mutex_init(&fb_info->lock);
mutex_init(&fb_info->mm_lock);
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index ecfbcc0553a5..5950f8f5dc74 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_FB_H
 #define _LINUX_FB_H
 
+#include 
 #include 
 #include 
 
@@ -435,7 +436,7 @@ struct fb_tile_ops {
 
 
 struct fb_info {
-   atomic_t count;
+   refcount_t count;
int node;
int flags;
/*
-- 
2.7.4



[PATCH] drm/exynos: Convert from atomic_t to refcount_t on g2d_cmdlist_userptr->refcount

2021-07-19 Thread Xiyu Yang
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index cab4d2c370a7..4921e84c374d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -4,6 +4,7 @@
  * Authors: Joonyoung Shim 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -208,7 +209,7 @@ struct g2d_cmdlist_userptr {
struct page **pages;
unsigned intnpages;
struct sg_table *sgt;
-   atomic_trefcount;
+   refcount_t  refcount;
boolin_pool;
boolout_of_list;
 };
@@ -386,9 +387,9 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
if (force)
goto out;
 
-   atomic_dec(&g2d_userptr->refcount);
+   refcount_dec(&g2d_userptr->refcount);
 
-   if (atomic_read(&g2d_userptr->refcount) > 0)
+   if (refcount_read(&g2d_userptr->refcount) > 0)
return;
 
if (g2d_userptr->in_pool)
@@ -436,7 +437,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data 
*g2d,
 * and different size.
 */
if (g2d_userptr->size == size) {
-   atomic_inc(&g2d_userptr->refcount);
+   refcount_inc(&g2d_userptr->refcount);
*obj = g2d_userptr;
 
return &g2d_userptr->dma_addr;
@@ -461,7 +462,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data 
*g2d,
if (!g2d_userptr)
return ERR_PTR(-ENOMEM);
 
-   atomic_set(&g2d_userptr->refcount, 1);
+   refcount_set(&g2d_userptr->refcount, 1);
g2d_userptr->size = size;
 
start = userptr & PAGE_MASK;
-- 
2.7.4



[PATCH] drm/amd/amdkfd: fix possible memory leak in svm_range_restore_pages

2021-09-09 Thread Xiyu Yang
The memory leak issue may take place in an error handling path. When
p->xnack_enabled is NULL, the function simply returns with -EFAULT and
forgets to decrement the reference count of a kfd_process object bumped
by kfd_lookup_process_by_pasid, which may incur memory leaks.

Fix it by jumping to label "out", in which kfd_unref_process() decreases
the refcount.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Xiong 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index e883731c3f8f..0f7f1e5621ea 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -2426,7 +2426,8 @@ svm_range_restore_pages(struct amdgpu_device *adev, 
unsigned int pasid,
}
if (!p->xnack_enabled) {
pr_debug("XNACK not enabled for pasid 0x%x\n", pasid);
-   return -EFAULT;
+   r = -EFAULT;
+   goto out;
}
svms = &p->svms;
 
-- 
2.7.4



[PATCH] drm/amdgpu/display: Fix dc_sink refcnt leak when detecting link

2020-04-23 Thread Xiyu Yang
emulated_link_detect() invokes dc_sink_retain(), which increases the
refcount of the "prev_sink".

When emulated_link_detect() returns, local variable "prev_sink" becomes
invalid, so the refcount should be decreased to keep refcount balanced.

The reference counting issue happens in all paths of
emulated_link_detect(), which forgets to decrease the refcnt increased
by dc_sink_retain(), causing a refcnt leak.

Fix this issue by adding a "err_sink_put" label and calling
dc_sink_release() before emulated_link_detect() returns.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e997251a8b57..1b0c4f11b9b1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1633,7 +1633,7 @@ static void emulated_link_detect(struct dc_link *link)
default:
DC_ERROR("Invalid connector type! signal:%d\n",
link->connector_signal);
-   return;
+   goto err_sink_put;
}
 
sink_init_data.link = link;
@@ -1642,7 +1642,7 @@ static void emulated_link_detect(struct dc_link *link)
sink = dc_sink_create(&sink_init_data);
if (!sink) {
DC_ERROR("Failed to create sink!\n");
-   return;
+   goto err_sink_put;
}
 
/* dc_sink_create returns a new reference */
@@ -1655,6 +1655,9 @@ static void emulated_link_detect(struct dc_link *link)
 
if (edid_status != EDID_OK)
DC_ERROR("Failed to read EDID");
+err_sink_put:
+   if (prev_sink != NULL)
+   dc_sink_release(prev_sink);
 
 }
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/amdgpu/display: Fix dc_sink refcnt leak in dc_link_detect_helper

2020-04-23 Thread Xiyu Yang
dc_link_detect_helper() invokes dc_sink_retain(), which increases the
refcount of the "prev_sink".

When dc_link_detect_helper() returns, local variable "prev_sink" becomes
invalid, so the refcount should be decreased to keep refcount balanced.

The reference counting issue happens in one exception handling path of
dc_link_detect_helper(). When alt mode times out, the function forgets
to decrease the refcnt increased by dc_sink_retain(), causing a refcnt
leak.

Fix this issue by calling dc_sink_release() when alt mode times out.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index a09119c10d7c..91550d9a1abb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -832,6 +832,8 @@ static bool dc_link_detect_helper(struct dc_link *link,
 
/* if alt mode times out, return false */
if (wait_for_alt_mode(link) == false) {
+   if (prev_sink != NULL)
+   dc_sink_release(prev_sink);
return false;
}
}
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/ttm: Fix dma_fence refcnt leak when adding move fence

2020-06-15 Thread Xiyu Yang
ttm_bo_add_move_fence() invokes dma_fence_get(), which returns a
reference of the specified dma_fence object to "fence" with increased
refcnt.

When ttm_bo_add_move_fence() returns, local variable "fence" becomes
invalid, so the refcount should be decreased to keep refcount balanced.

The reference counting issue happens in one exception handling path of
ttm_bo_add_move_fence(). When no_wait_gpu flag is equals to true, the
function forgets to decrease the refcnt increased by dma_fence_get(),
causing a refcnt leak.

Fix this issue by calling dma_fence_put() when no_wait_gpu flag is
equals to true.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index f73b81c2576e..0f20e14a4cfd 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -883,8 +883,10 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object 
*bo,
if (!fence)
return 0;
 
-   if (no_wait_gpu)
+   if (no_wait_gpu) {
+   dma_fence_put(fence);
return -EBUSY;
+   }
 
dma_resv_add_shared_fence(bo->base.resv, fence);
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/ttm: Fix dma_fence refcnt leak in ttm_bo_vm_fault_reserved

2020-06-15 Thread Xiyu Yang
ttm_bo_vm_fault_reserved() invokes dma_fence_get(), which returns a
reference of the specified dma_fence object to "moving" with increased
refcnt.

When ttm_bo_vm_fault_reserved() returns, local variable "moving" becomes
invalid, so the refcount should be decreased to keep refcount balanced.

The reference counting issue happens in several exception handling paths
of ttm_bo_vm_fault_reserved(). When those error scenarios occur such as
"err" equals to -EBUSY, the function forgets to decrease the refcnt
increased by dma_fence_get(), causing a refcnt leak.

Fix this issue by calling dma_fence_put() when no_wait_gpu flag is
equals to true.

Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index a43aa7275f12..fa03fab02076 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -300,8 +300,10 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
break;
case -EBUSY:
case -ERESTARTSYS:
+   dma_fence_put(moving);
return VM_FAULT_NOPAGE;
default:
+   dma_fence_put(moving);
return VM_FAULT_SIGBUS;
}
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/i915/selftests: Fix i915_address_space refcnt leak

2020-04-20 Thread Xiyu Yang
igt_ppgtt_pin_update() invokes i915_gem_context_get_vm_rcu(), which
returns a reference of the i915_address_space object to "vm" with
increased refcount.

When igt_ppgtt_pin_update() returns, "vm" becomes invalid, so the
refcount should be decreased to keep refcount balanced.

The reference counting issue happens in two exception handling paths of
igt_ppgtt_pin_update(). When i915_gem_object_create_internal() returns
IS_ERR, the refcnt increased by i915_gem_context_get_vm_rcu() is not
decreased, causing a refcnt leak.

Fix this issue by jumping to "out_vm" label when
i915_gem_object_create_internal() returns IS_ERR.

Fixes: 4049866f0913 ("drm/i915/selftests: huge page tests")
Signed-off-by: Xiyu Yang 
Signed-off-by: Xin Tan 
---
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 9311250d7d6f..7a7763be6b2e 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -1578,8 +1578,10 @@ static int igt_ppgtt_pin_update(void *arg)
unsigned int page_size = BIT(first);
 
obj = i915_gem_object_create_internal(dev_priv, page_size);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out_vm;
+   }
 
vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {
@@ -1632,8 +1634,10 @@ static int igt_ppgtt_pin_update(void *arg)
}
 
obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out_vm;
+   }
 
vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel