@@ -198,6 +198,7 @@ amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo)
198198 */
199199void * amdxdna_gem_vmap (struct amdxdna_gem_obj * abo )
200200{
201+ struct amdxdna_dev * xdna = to_xdna_dev (to_gobj (abo )-> dev );
201202 struct iosys_map map = IOSYS_MAP_INIT_VADDR (NULL );
202203 int ret ;
203204
@@ -210,7 +211,7 @@ void *amdxdna_gem_vmap(struct amdxdna_gem_obj *abo)
210211 if (!abo -> mem .kva ) {
211212 ret = drm_gem_vmap (to_gobj (abo ), & map );
212213 if (ret )
213- XDNA_ERR (abo -> client -> xdna , "Vmap bo failed, ret %d" , ret );
214+ XDNA_ERR (xdna , "Vmap bo failed, ret %d" , ret );
214215 else
215216 abo -> mem .kva = map .vaddr ;
216217 }
@@ -254,7 +255,7 @@ static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni,
254255
255256 xdna = to_xdna_dev (to_gobj (abo )-> dev );
256257 XDNA_DBG (xdna , "Invalidating range 0x%lx, 0x%lx, type %d" ,
257- mapp -> vma -> vm_start , mapp -> vma -> vm_end , abo -> type );
258+ mapp -> range . start , mapp -> range . end , abo -> type );
258259
259260 if (!mmu_notifier_range_blockable (range ))
260261 return false;
@@ -284,15 +285,23 @@ static const struct mmu_interval_notifier_ops amdxdna_hmm_ops = {
284285 .invalidate = amdxdna_hmm_invalidate ,
285286};
286287
288+ static inline bool compare_range (struct amdxdna_umap * mapp ,
289+ struct mm_struct * mm ,
290+ unsigned long start , unsigned long end )
291+ {
292+ return (!mapp -> unmapped && mapp -> notifier .mm == mm &&
293+ mapp -> range .start == start && mapp -> range .end == end );
294+ }
295+
287296static void amdxdna_hmm_unregister (struct amdxdna_gem_obj * abo ,
288297 struct vm_area_struct * vma )
289298{
290299 struct amdxdna_dev * xdna = to_xdna_dev (to_gobj (abo )-> dev );
291300 struct amdxdna_umap * mapp ;
292301
293- down_read (& xdna -> notifier_lock );
302+ down_write (& xdna -> notifier_lock );
294303 list_for_each_entry (mapp , & abo -> mem .umap_list , node ) {
295- if (!vma || mapp -> vma == vma ) {
304+ if (!vma || compare_range ( mapp , vma -> vm_mm , vma -> vm_start , vma -> vm_end ) ) {
296305 if (!mapp -> unmapped ) {
297306 queue_work (xdna -> notifier_wq , & mapp -> hmm_unreg_work );
298307 mapp -> unmapped = true;
@@ -301,19 +310,16 @@ static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo,
301310 break ;
302311 }
303312 }
304- up_read (& xdna -> notifier_lock );
313+ up_write (& xdna -> notifier_lock );
305314}
306315
307316static void amdxdna_umap_release (struct kref * ref )
308317{
309318 struct amdxdna_umap * mapp = container_of (ref , struct amdxdna_umap , refcnt );
310319 struct amdxdna_gem_obj * abo = mapp -> abo ;
311- struct vm_area_struct * vma = mapp -> vma ;
312320 struct amdxdna_dev * xdna ;
313321
314322 mmu_interval_notifier_remove (& mapp -> notifier );
315- if (is_import_bo (abo ) && vma -> vm_file && vma -> vm_file -> f_mapping )
316- mapping_clear_unevictable (vma -> vm_file -> f_mapping );
317323
318324 xdna = to_xdna_dev (to_gobj (mapp -> abo )-> dev );
319325 down_write (& xdna -> notifier_lock );
@@ -346,15 +352,30 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
346352 unsigned long len = vma -> vm_end - vma -> vm_start ;
347353 unsigned long addr = vma -> vm_start ;
348354 struct amdxdna_umap * mapp ;
349- u32 nr_pages ;
355+ unsigned long nr_pages ;
350356 int ret ;
351357
352- if (!amdxdna_pasid_on (abo -> client )) {
358+ /*
359+ * When PASID is off, amdxdna_gem_obj_open() called amdxdna_dma_map_bo()
360+ * and mem.dma_addr is valid; use the DMA address directly and skip HMM.
361+ * Avoid dereferencing abo->client which may be NULL (cleared in close())
362+ * while internal kernel references are still held.
363+ */
364+ if (abo -> mem .dma_addr != AMDXDNA_INVALID_ADDR ) {
353365 /* Need to set uva for heap uva validation */
354366 abo -> mem .uva = addr ;
355367 return 0 ;
356368 }
357369
370+ down_read (& xdna -> notifier_lock );
371+ list_for_each_entry (mapp , & abo -> mem .umap_list , node ) {
372+ if (compare_range (mapp , current -> mm , addr , addr + len )) {
373+ up_read (& xdna -> notifier_lock );
374+ return 0 ;
375+ }
376+ }
377+ up_read (& xdna -> notifier_lock );
378+
358379 mapp = kzalloc_obj (* mapp );
359380 if (!mapp )
360381 return - ENOMEM ;
@@ -380,13 +401,10 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
380401 mapp -> range .start = vma -> vm_start ;
381402 mapp -> range .end = vma -> vm_end ;
382403 mapp -> range .default_flags = HMM_PFN_REQ_FAULT ;
383- mapp -> vma = vma ;
384404 mapp -> abo = abo ;
385405 kref_init (& mapp -> refcnt );
386406
387407 INIT_WORK (& mapp -> hmm_unreg_work , amdxdna_hmm_unreg_work );
388- if (is_import_bo (abo ) && vma -> vm_file && vma -> vm_file -> f_mapping )
389- mapping_set_unevictable (vma -> vm_file -> f_mapping );
390408
391409 down_write (& xdna -> notifier_lock );
392410 if (list_empty (& abo -> mem .umap_list ))
@@ -527,6 +545,7 @@ static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struc
527545
528546close_vma :
529547 vma -> vm_ops -> close (vma );
548+ return ret ;
530549put_obj :
531550 drm_gem_object_put (gobj );
532551 return ret ;
@@ -652,8 +671,11 @@ static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fi
652671 /* No need to set up dma addr mapping in PASID mode. */
653672 if (!amdxdna_pasid_on (abo -> client )) {
654673 ret = amdxdna_dma_map_bo (xdna , abo );
655- if (ret )
674+ if (ret ) {
675+ abo -> open_ref -- ;
676+ abo -> client = NULL ;
656677 return ret ;
678+ }
657679 }
658680
659681 amdxdna_gem_add_bo_usage (abo );
0 commit comments