Re: [PATCH] drm/xe: Declare __xe_lrc_*_ggtt_addr with __maybe__unused

2024-03-04 Thread Dawei Li
Hi,

On Sun, Feb 04, 2024 at 02:23:24PM +0800, Dawei Li wrote:
> Kernel test robot reports building error:
> 
> drivers/gpu/drm/xe/xe_lrc.c:544:1: error: unused function
> '__xe_lrc_regs_ggtt_addr' [-Werror,-Wunused-function]
> 544 | DECL_MAP_ADDR_HELPERS(regs)
> | ^~~
> 
> drivers/gpu/drm/xe/xe_lrc.c:536:19: note: expanded from macro
> 'DECL_MAP_ADDR_HELPERS'
> 536 | static inline u32 __xe_lrc_##elem##_ggtt_addr(struct xe_lrc *lrc) \
> |   ^~~
> 
> :54:1: note: expanded from here
> 54 | __xe_lrc_regs_ggtt_addr
>| ^~~
> 
> 1 error generated.
> 
> Declare __xe_lrc_*_ggtt_addr with __maybe_unused to address it.
> 
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202402010928.g3j2asbl-...@intel.com/
> Signed-off-by: Dawei Li 
> ---
>  drivers/gpu/drm/xe/xe_lrc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Just a gentle ping.

Thanks,

Dawei

> 
> diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
> index 0ec5ad2539f1..f70e60a2f8a3 100644
> --- a/drivers/gpu/drm/xe/xe_lrc.c
> +++ b/drivers/gpu/drm/xe/xe_lrc.c
> @@ -614,7 +614,7 @@ static inline struct iosys_map 
> __xe_lrc_##elem##_map(struct xe_lrc *lrc) \
>   iosys_map_incr(, __xe_lrc_##elem##_offset(lrc)); \
>   return map; \
>  } \
> -static inline u32 __xe_lrc_##elem##_ggtt_addr(struct xe_lrc *lrc) \
> +static inline u32 __maybe_unused __xe_lrc_##elem##_ggtt_addr(struct xe_lrc 
> *lrc) \
>  { \
>   return xe_bo_ggtt_addr(lrc->bo) + __xe_lrc_##elem##_offset(lrc); \
>  } \
> -- 
> 2.27.0
> 


[PATCH] drm/xe: Declare __xe_lrc_*_ggtt_addr with __maybe__unused

2024-02-05 Thread Dawei Li
Kernel test robot reports building error:

drivers/gpu/drm/xe/xe_lrc.c:544:1: error: unused function
'__xe_lrc_regs_ggtt_addr' [-Werror,-Wunused-function]
544 | DECL_MAP_ADDR_HELPERS(regs)
| ^~~

drivers/gpu/drm/xe/xe_lrc.c:536:19: note: expanded from macro
'DECL_MAP_ADDR_HELPERS'
536 | static inline u32 __xe_lrc_##elem##_ggtt_addr(struct xe_lrc *lrc) \
|   ^~~

:54:1: note: expanded from here
54 | __xe_lrc_regs_ggtt_addr
   | ^~~

1 error generated.

Declare __xe_lrc_*_ggtt_addr with __maybe_unused to address it.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202402010928.g3j2asbl-...@intel.com/
Signed-off-by: Dawei Li 
---
 drivers/gpu/drm/xe/xe_lrc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 0ec5ad2539f1..f70e60a2f8a3 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -614,7 +614,7 @@ static inline struct iosys_map __xe_lrc_##elem##_map(struct 
xe_lrc *lrc) \
iosys_map_incr(, __xe_lrc_##elem##_offset(lrc)); \
return map; \
 } \
-static inline u32 __xe_lrc_##elem##_ggtt_addr(struct xe_lrc *lrc) \
+static inline u32 __maybe_unused __xe_lrc_##elem##_ggtt_addr(struct xe_lrc 
*lrc) \
 { \
return xe_bo_ggtt_addr(lrc->bo) + __xe_lrc_##elem##_offset(lrc); \
 } \
-- 
2.27.0



Re: [PATCH v3] drm/vmwgfx: Fix race issue calling pin_user_pages

2022-11-28 Thread Dawei Li
On Wed, Nov 09, 2022 at 11:37:34PM +0800, Dawei Li wrote:
> pin_user_pages() is unsafe without protection of mmap_lock,
> fix it by calling pin_user_pages_fast().
> 
> Fixes: 7a7a933edd6c ("drm/vmwgfx: Introduce VMware mks-guest-stats")
> Signed-off-by: Dawei Li 
> ---
> v1:
> https://lore.kernel.org/all/tycp286mb23235c9a9fcf85c045f95ea7ca...@tycp286mb2323.jpnp286.prod.outlook.com/
> 
> v1->v2:
> Rebased to latest vmwgfx/drm-misc-fixes.
> 
> v2->v3
> Replace pin_user_pages() with pin_user_pages_fast().

Gentle ping

> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
> index 089046fa21be..50fa3df0bc0c 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
> @@ -1085,21 +1085,21 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, 
> void *data,
>   reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
>  
>   /* Pin mksGuestStat user pages and store those in the instance 
> descriptor */
> - nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, 
> FOLL_LONGTERM, pages_stat, NULL);
> + nr_pinned_stat = pin_user_pages_fast(arg->stat, num_pages_stat, 
> FOLL_LONGTERM, pages_stat);
>   if (num_pages_stat != nr_pinned_stat)
>   goto err_pin_stat;
>  
>   for (i = 0; i < num_pages_stat; ++i)
>   pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
>  
> - nr_pinned_info = pin_user_pages(arg->info, num_pages_info, 
> FOLL_LONGTERM, pages_info, NULL);
> + nr_pinned_info = pin_user_pages_fast(arg->info, num_pages_info, 
> FOLL_LONGTERM, pages_info);
>   if (num_pages_info != nr_pinned_info)
>   goto err_pin_info;
>  
>   for (i = 0; i < num_pages_info; ++i)
>   pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
>  
> - nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, 
> FOLL_LONGTERM, pages_strs, NULL);
> + nr_pinned_strs = pin_user_pages_fast(arg->strs, num_pages_strs, 
> FOLL_LONGTERM, pages_strs);
>   if (num_pages_strs != nr_pinned_strs)
>   goto err_pin_strs;
>  
> -- 
> 2.25.1
> 


Re: [PATCH v4] dma-buf: fix racing conflict of dma_heap_add()

2022-11-21 Thread Dawei Li
On Sat, Nov 05, 2022 at 12:05:36AM +0800, Dawei Li wrote:

Hi Christian,
May I have your opinion on this change?

Thanks,
Dawei

> Racing conflict could be:
> task A task B
> list_for_each_entry
> strcmp(h->name))
>list_for_each_entry
>strcmp(h->name)
> kzallockzalloc
> .. .
> device_create  device_create
> list_add
>list_add
> 
> The root cause is that task B has no idea about the fact someone
> else(A) has inserted heap with same name when it calls list_add,
> so a potential collision occurs.
> 
> Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
> Signed-off-by: Dawei Li 
> ---
> v1: 
> https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/
> v1->v2: Narrow down locking scope, check the existence of heap before
> insertion, as suggested by Andrew Davis.
> v2->v3: Remove double checking.
> v3->v4: Minor coding style and patch formatting adjustment.
> ---
>  drivers/dma-buf/dma-heap.c | 28 +++-
>  1 file changed, 15 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
> index 8f5848aa144f..59d158873f4c 100644
> --- a/drivers/dma-buf/dma-heap.c
> +++ b/drivers/dma-buf/dma-heap.c
> @@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct 
> dma_heap_export_info *exp_info)
>   return ERR_PTR(-EINVAL);
>   }
>  
> - /* check the name is unique */
> - mutex_lock(_list_lock);
> - list_for_each_entry(h, _list, list) {
> - if (!strcmp(h->name, exp_info->name)) {
> - mutex_unlock(_list_lock);
> - pr_err("dma_heap: Already registered heap named %s\n",
> -exp_info->name);
> - return ERR_PTR(-EINVAL);
> - }
> - }
> - mutex_unlock(_list_lock);
> -
>   heap = kzalloc(sizeof(*heap), GFP_KERNEL);
>   if (!heap)
>   return ERR_PTR(-ENOMEM);
> @@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct 
> dma_heap_export_info *exp_info)
>   err_ret = ERR_CAST(dev_ret);
>   goto err2;
>   }
> - /* Add heap to the list */
> +
>   mutex_lock(_list_lock);
> + /* check the name is unique */
> + list_for_each_entry(h, _list, list) {
> + if (!strcmp(h->name, exp_info->name)) {
> + mutex_unlock(_list_lock);
> + pr_err("dma_heap: Already registered heap named %s\n",
> +exp_info->name);
> + err_ret = ERR_PTR(-EINVAL);
> + goto err3;
> + }
> + }
> +
> + /* Add heap to the list */
>   list_add(>list, _list);
>   mutex_unlock(_list_lock);
>  
>   return heap;
>  
> +err3:
> + device_destroy(dma_heap_class, heap->heap_devt);
>  err2:
>   cdev_del(>heap_cdev);
>  err1:
> -- 
> 2.25.1
> 


[PATCH] drm/radeon: fix potential racing issue due to mmap_lock

2022-11-13 Thread Dawei Li
Both find_vma() and get_user_pages() need explicit protection of
mmap lock, fix them by mmap_lock and get_user_pages_fast().

Fixes: ddd00e33e17a ("drm/radeon: add userptr flag to limit it to anonymous 
memory v2")
Fixes: f72a113a71ab ("drm/radeon: add userptr support v8")
Signed-off-by: Dawei Li 
---
 drivers/gpu/drm/radeon/radeon_ttm.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index d33fec488713..741ea64b9402 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -351,7 +351,10 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_device 
*bdev, struct ttm_tt *ttm
   to prevent problems with writeback */
unsigned long end = gtt->userptr + (u64)ttm->num_pages * 
PAGE_SIZE;
struct vm_area_struct *vma;
+
+   mmap_read_lock(gtt->usermm);
vma = find_vma(gtt->usermm, gtt->userptr);
+   mmap_read_unlock(gtt->usermm);
if (!vma || vma->vm_file || vma->vm_end < end)
return -EPERM;
}
@@ -361,8 +364,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_device 
*bdev, struct ttm_tt *ttm
uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE;
struct page **pages = ttm->pages + pinned;
 
-   r = get_user_pages(userptr, num_pages, write ? FOLL_WRITE : 0,
-  pages, NULL);
+   r = get_user_pages_fast(userptr, num_pages, write ? FOLL_WRITE 
: 0, pages);
if (r < 0)
goto release_pages;
 
-- 
2.25.1



[PATCH v3] drm/vmwgfx: Fix race issue calling pin_user_pages

2022-11-09 Thread Dawei Li
pin_user_pages() is unsafe without protection of mmap_lock,
fix it by calling pin_user_pages_fast().

Fixes: 7a7a933edd6c ("drm/vmwgfx: Introduce VMware mks-guest-stats")
Signed-off-by: Dawei Li 
---
v1:
https://lore.kernel.org/all/tycp286mb23235c9a9fcf85c045f95ea7ca...@tycp286mb2323.jpnp286.prod.outlook.com/

v1->v2:
Rebased to latest vmwgfx/drm-misc-fixes.

v2->v3
Replace pin_user_pages() with pin_user_pages_fast().
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 089046fa21be..50fa3df0bc0c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -1085,21 +1085,21 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
 
/* Pin mksGuestStat user pages and store those in the instance 
descriptor */
-   nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, 
FOLL_LONGTERM, pages_stat, NULL);
+   nr_pinned_stat = pin_user_pages_fast(arg->stat, num_pages_stat, 
FOLL_LONGTERM, pages_stat);
if (num_pages_stat != nr_pinned_stat)
goto err_pin_stat;
 
for (i = 0; i < num_pages_stat; ++i)
pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
 
-   nr_pinned_info = pin_user_pages(arg->info, num_pages_info, 
FOLL_LONGTERM, pages_info, NULL);
+   nr_pinned_info = pin_user_pages_fast(arg->info, num_pages_info, 
FOLL_LONGTERM, pages_info);
if (num_pages_info != nr_pinned_info)
goto err_pin_info;
 
for (i = 0; i < num_pages_info; ++i)
pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
 
-   nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, 
FOLL_LONGTERM, pages_strs, NULL);
+   nr_pinned_strs = pin_user_pages_fast(arg->strs, num_pages_strs, 
FOLL_LONGTERM, pages_strs);
if (num_pages_strs != nr_pinned_strs)
goto err_pin_strs;
 
-- 
2.25.1



[PATCH v2] drm/vmwgfx: Protect pin_user_pages with mmap_lock

2022-11-06 Thread Dawei Li
This patch includes changes below:
1) pin_user_pages() is unsafe without protection of mmap_lock,
   fix it by calling mmap_read_lock() & mmap_read_unlock().
2) fix & refactor the incorrect exception handling procedure in
   vmw_mksstat_add_ioctl().

Fixes: 7a7a933edd6c ("drm/vmwgfx: Introduce VMware mks-guest-stats")
Signed-off-by: Dawei Li 
---
v1:
https://lore.kernel.org/all/tycp286mb23235c9a9fcf85c045f95ea7ca...@tycp286mb2323.jpnp286.prod.outlook.com/

v1->v2:
Rebased to latest vmwgfx/drm-misc-fixes
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 089046fa21be..ec40a3364e0a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -1020,9 +1020,9 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
const size_t num_pages_info = PFN_UP(arg->info_len);
const size_t num_pages_strs = PFN_UP(arg->strs_len);
long desc_len;
-   long nr_pinned_stat;
-   long nr_pinned_info;
-   long nr_pinned_strs;
+   long nr_pinned_stat = 0;
+   long nr_pinned_info = 0;
+   long nr_pinned_strs = 0;
struct page *pages_stat[ARRAY_SIZE(pdesc->statPPNs)];
struct page *pages_info[ARRAY_SIZE(pdesc->infoPPNs)];
struct page *pages_strs[ARRAY_SIZE(pdesc->strsPPNs)];
@@ -1084,28 +1084,33 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
reset_ppn_array(pdesc->infoPPNs, ARRAY_SIZE(pdesc->infoPPNs));
reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
 
+   /* pin_user_pages() needs protection of mmap_lock */
+   mmap_read_lock(current->mm);
+
/* Pin mksGuestStat user pages and store those in the instance 
descriptor */
nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, 
FOLL_LONGTERM, pages_stat, NULL);
if (num_pages_stat != nr_pinned_stat)
-   goto err_pin_stat;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_stat; ++i)
pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
 
nr_pinned_info = pin_user_pages(arg->info, num_pages_info, 
FOLL_LONGTERM, pages_info, NULL);
if (num_pages_info != nr_pinned_info)
-   goto err_pin_info;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_info; ++i)
pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
 
nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, 
FOLL_LONGTERM, pages_strs, NULL);
if (num_pages_strs != nr_pinned_strs)
-   goto err_pin_strs;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_strs; ++i)
pdesc->strsPPNs[i] = page_to_pfn(pages_strs[i]);
 
+   mmap_read_unlock(current->mm);
+
/* Send the descriptor to the host via a hypervisor call. The 
mksGuestStat
   pages will remain in use until the user requests a matching remove 
stats
   or a stats reset occurs. */
@@ -1120,15 +1125,15 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
 
return 0;
 
-err_pin_strs:
+__err_pin_pages:
+   mmap_read_unlock(current->mm);
+
if (nr_pinned_strs > 0)
unpin_user_pages(pages_strs, nr_pinned_strs);
 
-err_pin_info:
if (nr_pinned_info > 0)
unpin_user_pages(pages_info, nr_pinned_info);
 
-err_pin_stat:
if (nr_pinned_stat > 0)
unpin_user_pages(pages_stat, nr_pinned_stat);
 
-- 
2.25.1



[PATCH v4] dma-buf: fix racing conflict of dma_heap_add()

2022-11-04 Thread Dawei Li
Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
   list_for_each_entry
   strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
   list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
Signed-off-by: Dawei Li 
---
v1: 
https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/
v1->v2: Narrow down locking scope, check the existence of heap before
insertion, as suggested by Andrew Davis.
v2->v3: Remove double checking.
v3->v4: Minor coding style and patch formatting adjustment.
---
 drivers/dma-buf/dma-heap.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..59d158873f4c 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
 
-   /* check the name is unique */
-   mutex_lock(_list_lock);
-   list_for_each_entry(h, _list, list) {
-   if (!strcmp(h->name, exp_info->name)) {
-   mutex_unlock(_list_lock);
-   pr_err("dma_heap: Already registered heap named %s\n",
-  exp_info->name);
-   return ERR_PTR(-EINVAL);
-   }
-   }
-   mutex_unlock(_list_lock);
-
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret);
goto err2;
}
-   /* Add heap to the list */
+
mutex_lock(_list_lock);
+   /* check the name is unique */
+   list_for_each_entry(h, _list, list) {
+   if (!strcmp(h->name, exp_info->name)) {
+   mutex_unlock(_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   err_ret = ERR_PTR(-EINVAL);
+   goto err3;
+   }
+   }
+
+   /* Add heap to the list */
list_add(>list, _list);
mutex_unlock(_list_lock);
 
return heap;
 
+err3:
+   device_destroy(dma_heap_class, heap->heap_devt);
 err2:
cdev_del(>heap_cdev);
 err1:
-- 
2.25.1



[PATCH v3] dma-buf: fix racing conflict of dma_heap_add()

2022-11-02 Thread Dawei Li
Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
   list_for_each_entry
   strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
   list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

v1: 
https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/

v1->v2: Narrow down locking scope, check the existence of heap before
insertion, as suggested by Andrew Davis.

v2->v3: Remove double checking.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")

base-commit: 447fb14bf07905b880c9ed1ea92c53d6dd0649d7

Signed-off-by: Dawei Li 
---
 drivers/dma-buf/dma-heap.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..7a25e98259ea 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
 
-   /* check the name is unique */
-   mutex_lock(_list_lock);
-   list_for_each_entry(h, _list, list) {
-   if (!strcmp(h->name, exp_info->name)) {
-   mutex_unlock(_list_lock);
-   pr_err("dma_heap: Already registered heap named %s\n",
-  exp_info->name);
-   return ERR_PTR(-EINVAL);
-   }
-   }
-   mutex_unlock(_list_lock);
-
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
@@ -283,13 +271,26 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret);
goto err2;
}
-   /* Add heap to the list */
+
mutex_lock(_list_lock);
+   /* check the name is unique */
+   list_for_each_entry(h, _list, list) {
+   if (!strcmp(h->name, exp_info->name)) {
+   mutex_unlock(_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   err_ret = ERR_PTR(-EINVAL);
+   goto err3;
+   }
+   }
+
+   /* Add heap to the list */
list_add(>list, _list);
mutex_unlock(_list_lock);
 
return heap;
-
+err3:
+   device_destroy(dma_heap_class, heap->heap_devt);
 err2:
cdev_del(>heap_cdev);
 err1:
-- 
2.25.1



[PATCH v2] dma-buf: fix racing conflict of dma_heap_add()

2022-10-31 Thread Dawei Li
Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
   list_for_each_entry
   strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
   list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

v1: 
https://lore.kernel.org/all/tycp286mb2323950197f60fc3473123b7ca...@tycp286mb2323.jpnp286.prod.outlook.com/

v1->v2: Narrow down locking scope, check the existence of heap before
insertion, as suggested by Andrew Davis.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")

base-commit: 447fb14bf07905b880c9ed1ea92c53d6dd0649d7

Signed-off-by: Dawei Li 
---
 drivers/dma-buf/dma-heap.c | 37 -
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..1c787a147e3a 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -216,9 +216,21 @@ const char *dma_heap_get_name(struct dma_heap *heap)
return heap->name;
 }
 
+static inline bool dma_heap_exist(const char *name)
+{
+   struct dma_heap *h;
+
+   list_for_each_entry(h, _list, list) {
+   if (!strcmp(h->name, name))
+   return true;
+   }
+
+   return false;
+}
+
 struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
 {
-   struct dma_heap *heap, *h, *err_ret;
+   struct dma_heap *heap, *err_ret;
struct device *dev_ret;
unsigned int minor;
int ret;
@@ -235,13 +247,11 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
 
/* check the name is unique */
mutex_lock(_list_lock);
-   list_for_each_entry(h, _list, list) {
-   if (!strcmp(h->name, exp_info->name)) {
-   mutex_unlock(_list_lock);
-   pr_err("dma_heap: Already registered heap named %s\n",
-  exp_info->name);
-   return ERR_PTR(-EINVAL);
-   }
+   if (dma_heap_exist(exp_info->name)) {
+   mutex_unlock(_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   return ERR_PTR(-EINVAL);
}
mutex_unlock(_list_lock);
 
@@ -283,13 +293,22 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
err_ret = ERR_CAST(dev_ret);
goto err2;
}
+
/* Add heap to the list */
mutex_lock(_list_lock);
+   if (unlikely(dma_heap_exist(exp_info->name))) {
+   mutex_unlock(_list_lock);
+   pr_err("dma_heap: Already registered heap named %s\n",
+  exp_info->name);
+   err_ret = ERR_PTR(-EINVAL);
+   goto err3;
+   }
list_add(>list, _list);
mutex_unlock(_list_lock);
 
return heap;
-
+err3:
+   device_destroy(dma_heap_class, heap->heap_devt);
 err2:
cdev_del(>heap_cdev);
 err1:
-- 
2.25.1



[PATCH] dma-buf: fix racing conflict of dma_heap_add()

2022-10-30 Thread Dawei Li
Racing conflict could be:
task A task B
list_for_each_entry
strcmp(h->name))
   list_for_each_entry
   strcmp(h->name)
kzallockzalloc
.. .
device_create  device_create
list_add
   list_add

The root cause is that task B has no idea about the fact someone
else(A) has inserted heap with same name when it calls list_add,
so a potential collision occurs.

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")

base-commit: 447fb14bf07905b880c9ed1ea92c53d6dd0649d7

Signed-off-by: Dawei Li 
---
 drivers/dma-buf/dma-heap.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 8f5848aa144f..ff44c2777b04 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -243,11 +243,12 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
}
-   mutex_unlock(_list_lock);
 
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
-   if (!heap)
+   if (!heap) {
+   mutex_unlock(_list_lock);
return ERR_PTR(-ENOMEM);
+   }
 
heap->name = exp_info->name;
heap->ops = exp_info->ops;
@@ -284,7 +285,6 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
goto err2;
}
/* Add heap to the list */
-   mutex_lock(_list_lock);
list_add(>list, _list);
mutex_unlock(_list_lock);
 
@@ -296,6 +296,7 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
xa_erase(_heap_minors, minor);
 err0:
kfree(heap);
+   mutex_unlock(_list_lock);
return err_ret;
 }
 
-- 
2.25.1



[PATCH] drm/vmwgfx: Protect pin_user_pages with mmap_lock

2022-09-21 Thread Dawei Li
This patch includes changes below:
1) pin_user_pages() is unsafe without protection of mmap_lock,
   fix it by calling mmap_read_lock() & mmap_read_unlock().
2) fix & refactor the incorrect exception handling procedure in
   vmw_mksstat_add_ioctl().

based-on branch: vmwgfx/drm-misc-fixes
based commit: d8a79c03054911c375a2252627a429c9bc4615b6

Signed-off-by: Dawei Li 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 2aceac7856e2..ec40a3364e0a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -1020,9 +1020,9 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
const size_t num_pages_info = PFN_UP(arg->info_len);
const size_t num_pages_strs = PFN_UP(arg->strs_len);
long desc_len;
-   long nr_pinned_stat;
-   long nr_pinned_info;
-   long nr_pinned_strs;
+   long nr_pinned_stat = 0;
+   long nr_pinned_info = 0;
+   long nr_pinned_strs = 0;
struct page *pages_stat[ARRAY_SIZE(pdesc->statPPNs)];
struct page *pages_info[ARRAY_SIZE(pdesc->infoPPNs)];
struct page *pages_strs[ARRAY_SIZE(pdesc->strsPPNs)];
@@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
 
if (desc_len < 0) {
atomic_set(_priv->mksstat_user_pids[slot], 0);
+   __free_page(page);
return -EFAULT;
}
 
@@ -1083,28 +1084,33 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
reset_ppn_array(pdesc->infoPPNs, ARRAY_SIZE(pdesc->infoPPNs));
reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
 
+   /* pin_user_pages() needs protection of mmap_lock */
+   mmap_read_lock(current->mm);
+
/* Pin mksGuestStat user pages and store those in the instance 
descriptor */
nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, 
FOLL_LONGTERM, pages_stat, NULL);
if (num_pages_stat != nr_pinned_stat)
-   goto err_pin_stat;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_stat; ++i)
pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
 
nr_pinned_info = pin_user_pages(arg->info, num_pages_info, 
FOLL_LONGTERM, pages_info, NULL);
if (num_pages_info != nr_pinned_info)
-   goto err_pin_info;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_info; ++i)
pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
 
nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, 
FOLL_LONGTERM, pages_strs, NULL);
if (num_pages_strs != nr_pinned_strs)
-   goto err_pin_strs;
+   goto __err_pin_pages;
 
for (i = 0; i < num_pages_strs; ++i)
pdesc->strsPPNs[i] = page_to_pfn(pages_strs[i]);
 
+   mmap_read_unlock(current->mm);
+
/* Send the descriptor to the host via a hypervisor call. The 
mksGuestStat
   pages will remain in use until the user requests a matching remove 
stats
   or a stats reset occurs. */
@@ -1119,15 +1125,15 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void 
*data,
 
return 0;
 
-err_pin_strs:
+__err_pin_pages:
+   mmap_read_unlock(current->mm);
+
if (nr_pinned_strs > 0)
unpin_user_pages(pages_strs, nr_pinned_strs);
 
-err_pin_info:
if (nr_pinned_info > 0)
unpin_user_pages(pages_info, nr_pinned_info);
 
-err_pin_stat:
if (nr_pinned_stat > 0)
unpin_user_pages(pages_stat, nr_pinned_stat);
 
-- 
2.25.1