Merge tag 'amd-drm-next-6.6-2023-07-28' of https://gitlab.freedesktop.org/agd5f/linux...
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 4 Aug 2023 09:10:18 +0000 (11:10 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 4 Aug 2023 09:10:18 +0000 (11:10 +0200)
amd-drm-next-6.6-2023-07-28:

amdgpu:
- Lots of checkpatch cleanups
- GFX 9.4.3 updates
- Add USB PD and IFWI flashing documentation
- GPUVM updates
- RAS fixes
- DRR fixes
- FAMS fixes
- Virtual display fixes
- Soft IH fixes
- SMU13 fixes
- Rework PSP firmware loading for other IPs
- Kernel doc fixes
- DCN 3.0.1 fixes
- LTTPR fixes
- DP MST fixes
- DCN 3.1.6 fixes
- SubVP fixes
- Display bandwidth calculation fixes
- VCN4 secure submission fixes
- Allow building DC on RISC-V
- Add visible FB info to bo_print_info
- HBR3 fixes
- Add PSP 14.0 support
- GFX9 MCBP fix
- GMC10 vmhub index fix
- GMC11 vmhub index fix
- Create a new doorbell manager
- SR-IOV fixes

amdkfd:
- Cleanup CRIU dma-buf handling
- Use KIQ to unmap HIQ
- GFX 9.4.3 debugger updates
- GFX 9.4.2 debugger fixes
- Enable cooperative groups fof gfx11
- SVM fixes

radeon:
- Lots of checkpatch cleanups

Merge conflicts:
- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
The switch to drm eu helpers in 8a206685d36f ("drm/amdgpu: use
drm_exec for GEM and CSA handling v2") clashed with the
cosmetic cleanups from 30953c4d000b ("drm/amdgpu: Fix style
issues in amdgpu_gem.c"). I
kept the former since the cleanup up code is gone.
- drivers/gpu/drm/amd/amdgpu/atom.c.
adf64e214280 ("drm/amd: Avoid reading the VBIOS part number
twice") removed code that 992b8fe106ab ("drm/radeon: Replace
all non-returning strlcpy with strscpy") polished.

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230728214228.8102-1-alexander.deucher@amd.com
[sima: some merge conflict wrangling as noted]
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
1  2 
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/radeon/radeon_drv.c

index 8f2255b3a38a437c133e2fd6d2bb4c4d9d8552c8,8eda1a8d79abbf5d344901372fc66683e60415e6..035437d7d73af991b8375ddbb3aa4610cb3294f8
@@@ -53,6 -53,7 +53,6 @@@
  
  #include <drm/ttm/ttm_bo.h>
  #include <drm/ttm/ttm_placement.h>
 -#include <drm/ttm/ttm_execbuf_util.h>
  
  #include <drm/amdgpu_drm.h>
  #include <drm/drm_gem.h>
@@@ -1033,7 -1034,6 +1033,6 @@@ struct amdgpu_device 
        bool                            has_pr3;
  
        bool                            ucode_sysfs_en;
-       bool                            psp_sysfs_en;
  
        /* Chip product information */
        char                            product_number[20];
@@@ -1128,7 -1128,7 +1127,7 @@@ void amdgpu_device_wreg(struct amdgpu_d
  void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
                                     u64 reg_addr, u32 reg_data);
  void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
-                            uint32_t reg, uint32_t v);
+                            uint32_t reg, uint32_t v, uint32_t xcc_id);
  void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
  uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
  
@@@ -1506,4 -1506,8 +1505,8 @@@ static inline bool amdgpu_is_tmz(struc
  
  int amdgpu_in_reset(struct amdgpu_device *adev);
  
+ extern const struct attribute_group amdgpu_vram_mgr_attr_group;
+ extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
+ extern const struct attribute_group amdgpu_flash_attr_group;
  #endif
index 1e4cc1fe88fc731f48a49c1ba90cececb7c900ea,b34418e3e006ed08ed3c5c385435940daf99ca32..082c9f4cfd34416dcc7eb952bfa7abc06ce76a2d
@@@ -25,7 -25,6 +25,7 @@@
  #ifndef AMDGPU_AMDKFD_H_INCLUDED
  #define AMDGPU_AMDKFD_H_INCLUDED
  
 +#include <linux/list.h>
  #include <linux/types.h>
  #include <linux/mm.h>
  #include <linux/kthread.h>
@@@ -33,6 -32,7 +33,6 @@@
  #include <linux/mmu_notifier.h>
  #include <linux/memremap.h>
  #include <kgd_kfd_interface.h>
 -#include <drm/ttm/ttm_execbuf_util.h>
  #include "amdgpu_sync.h"
  #include "amdgpu_vm.h"
  #include "amdgpu_xcp.h"
@@@ -71,7 -71,8 +71,7 @@@ struct kgd_mem 
        struct hmm_range *range;
        struct list_head attachments;
        /* protected by amdkfd_process_info.lock */
 -      struct ttm_validate_buffer validate_list;
 -      struct ttm_validate_buffer resv_list;
 +      struct list_head validate_list;
        uint32_t domain;
        unsigned int mapped_to_gpu_memory;
        uint64_t va;
@@@ -251,6 -252,8 +251,8 @@@ int amdgpu_amdkfd_get_xgmi_bandwidth_mb
  int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min);
  int amdgpu_amdkfd_send_close_event_drain_irq(struct amdgpu_device *adev,
                                        uint32_t *payload);
+ int amdgpu_amdkfd_unmap_hiq(struct amdgpu_device *adev, u32 doorbell_off,
+                               u32 inst);
  
  /* Read user wptr from a specified user address space with page fault
   * disabled. The memory must be pinned and mapped to the hardware when
index edb35a88cb788412b15b1d50ab151e42215e3eba,d34c3ef8f3edb1b3bccf183a27cd989b64251eb2..a136fba9f29ba454a10794076fa92bd64eafad63
@@@ -27,8 -27,6 +27,8 @@@
  #include <linux/sched/task.h>
  #include <drm/ttm/ttm_tt.h>
  
 +#include <drm/drm_exec.h>
 +
  #include "amdgpu_object.h"
  #include "amdgpu_gem.h"
  #include "amdgpu_vm.h"
@@@ -966,20 -964,28 +966,20 @@@ static void add_kgd_mem_to_kfd_bo_list(
                                struct amdkfd_process_info *process_info,
                                bool userptr)
  {
 -      struct ttm_validate_buffer *entry = &mem->validate_list;
 -      struct amdgpu_bo *bo = mem->bo;
 -
 -      INIT_LIST_HEAD(&entry->head);
 -      entry->num_shared = 1;
 -      entry->bo = &bo->tbo;
        mutex_lock(&process_info->lock);
        if (userptr)
 -              list_add_tail(&entry->head, &process_info->userptr_valid_list);
 +              list_add_tail(&mem->validate_list,
 +                            &process_info->userptr_valid_list);
        else
 -              list_add_tail(&entry->head, &process_info->kfd_bo_list);
 +              list_add_tail(&mem->validate_list, &process_info->kfd_bo_list);
        mutex_unlock(&process_info->lock);
  }
  
  static void remove_kgd_mem_from_kfd_bo_list(struct kgd_mem *mem,
                struct amdkfd_process_info *process_info)
  {
 -      struct ttm_validate_buffer *bo_list_entry;
 -
 -      bo_list_entry = &mem->validate_list;
        mutex_lock(&process_info->lock);
 -      list_del(&bo_list_entry->head);
 +      list_del(&mem->validate_list);
        mutex_unlock(&process_info->lock);
  }
  
   * object can track VM updates.
   */
  struct bo_vm_reservation_context {
 -      struct amdgpu_bo_list_entry kfd_bo; /* BO list entry for the KFD BO */
 -      unsigned int n_vms;                 /* Number of VMs reserved       */
 -      struct amdgpu_bo_list_entry *vm_pd; /* Array of VM BO list entries  */
 -      struct ww_acquire_ctx ticket;       /* Reservation ticket           */
 -      struct list_head list, duplicates;  /* BO lists                     */
 -      struct amdgpu_sync *sync;           /* Pointer to sync object       */
 -      bool reserved;                      /* Whether BOs are reserved     */
 +      /* DRM execution context for the reservation */
 +      struct drm_exec exec;
 +      /* Number of VMs reserved */
 +      unsigned int n_vms;
 +      /* Pointer to sync object */
 +      struct amdgpu_sync *sync;
  };
  
  enum bo_vm_match {
@@@ -1095,26 -1102,35 +1095,26 @@@ static int reserve_bo_and_vm(struct kgd
  
        WARN_ON(!vm);
  
 -      ctx->reserved = false;
        ctx->n_vms = 1;
        ctx->sync = &mem->sync;
 -
 -      INIT_LIST_HEAD(&ctx->list);
 -      INIT_LIST_HEAD(&ctx->duplicates);
 -
 -      ctx->vm_pd = kcalloc(ctx->n_vms, sizeof(*ctx->vm_pd), GFP_KERNEL);
 -      if (!ctx->vm_pd)
 -              return -ENOMEM;
 -
 -      ctx->kfd_bo.priority = 0;
 -      ctx->kfd_bo.tv.bo = &bo->tbo;
 -      ctx->kfd_bo.tv.num_shared = 1;
 -      list_add(&ctx->kfd_bo.tv.head, &ctx->list);
 -
 -      amdgpu_vm_get_pd_bo(vm, &ctx->list, &ctx->vm_pd[0]);
 -
 -      ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
 -                                   false, &ctx->duplicates);
 -      if (ret) {
 -              pr_err("Failed to reserve buffers in ttm.\n");
 -              kfree(ctx->vm_pd);
 -              ctx->vm_pd = NULL;
 -              return ret;
 +      drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
 +      drm_exec_until_all_locked(&ctx->exec) {
 +              ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
 +              drm_exec_retry_on_contention(&ctx->exec);
 +              if (unlikely(ret))
 +                      goto error;
 +
 +              ret = drm_exec_lock_obj(&ctx->exec, &bo->tbo.base);
 +              drm_exec_retry_on_contention(&ctx->exec);
 +              if (unlikely(ret))
 +                      goto error;
        }
 -
 -      ctx->reserved = true;
        return 0;
 +
 +error:
 +      pr_err("Failed to reserve buffers in ttm.\n");
 +      drm_exec_fini(&ctx->exec);
 +      return ret;
  }
  
  /**
@@@ -1131,39 -1147,63 +1131,39 @@@ static int reserve_bo_and_cond_vms(stru
                                struct amdgpu_vm *vm, enum bo_vm_match map_type,
                                struct bo_vm_reservation_context *ctx)
  {
 -      struct amdgpu_bo *bo = mem->bo;
        struct kfd_mem_attachment *entry;
 -      unsigned int i;
 +      struct amdgpu_bo *bo = mem->bo;
        int ret;
  
 -      ctx->reserved = false;
 -      ctx->n_vms = 0;
 -      ctx->vm_pd = NULL;
        ctx->sync = &mem->sync;
 +      drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
 +      drm_exec_until_all_locked(&ctx->exec) {
 +              ctx->n_vms = 0;
 +              list_for_each_entry(entry, &mem->attachments, list) {
 +                      if ((vm && vm != entry->bo_va->base.vm) ||
 +                              (entry->is_mapped != map_type
 +                              && map_type != BO_VM_ALL))
 +                              continue;
  
 -      INIT_LIST_HEAD(&ctx->list);
 -      INIT_LIST_HEAD(&ctx->duplicates);
 -
 -      list_for_each_entry(entry, &mem->attachments, list) {
 -              if ((vm && vm != entry->bo_va->base.vm) ||
 -                      (entry->is_mapped != map_type
 -                      && map_type != BO_VM_ALL))
 -                      continue;
 -
 -              ctx->n_vms++;
 -      }
 -
 -      if (ctx->n_vms != 0) {
 -              ctx->vm_pd = kcalloc(ctx->n_vms, sizeof(*ctx->vm_pd),
 -                                   GFP_KERNEL);
 -              if (!ctx->vm_pd)
 -                      return -ENOMEM;
 -      }
 -
 -      ctx->kfd_bo.priority = 0;
 -      ctx->kfd_bo.tv.bo = &bo->tbo;
 -      ctx->kfd_bo.tv.num_shared = 1;
 -      list_add(&ctx->kfd_bo.tv.head, &ctx->list);
 -
 -      i = 0;
 -      list_for_each_entry(entry, &mem->attachments, list) {
 -              if ((vm && vm != entry->bo_va->base.vm) ||
 -                      (entry->is_mapped != map_type
 -                      && map_type != BO_VM_ALL))
 -                      continue;
 -
 -              amdgpu_vm_get_pd_bo(entry->bo_va->base.vm, &ctx->list,
 -                              &ctx->vm_pd[i]);
 -              i++;
 -      }
 +                      ret = amdgpu_vm_lock_pd(entry->bo_va->base.vm,
 +                                              &ctx->exec, 2);
 +                      drm_exec_retry_on_contention(&ctx->exec);
 +                      if (unlikely(ret))
 +                              goto error;
 +                      ++ctx->n_vms;
 +              }
  
 -      ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
 -                                   false, &ctx->duplicates);
 -      if (ret) {
 -              pr_err("Failed to reserve buffers in ttm.\n");
 -              kfree(ctx->vm_pd);
 -              ctx->vm_pd = NULL;
 -              return ret;
 +              ret = drm_exec_prepare_obj(&ctx->exec, &bo->tbo.base, 1);
 +              drm_exec_retry_on_contention(&ctx->exec);
 +              if (unlikely(ret))
 +                      goto error;
        }
 -
 -      ctx->reserved = true;
        return 0;
 +
 +error:
 +      pr_err("Failed to reserve buffers in ttm.\n");
 +      drm_exec_fini(&ctx->exec);
 +      return ret;
  }
  
  /**
@@@ -1184,8 -1224,15 +1184,8 @@@ static int unreserve_bo_and_vms(struct 
        if (wait)
                ret = amdgpu_sync_wait(ctx->sync, intr);
  
 -      if (ctx->reserved)
 -              ttm_eu_backoff_reservation(&ctx->ticket, &ctx->list);
 -      kfree(ctx->vm_pd);
 -
 +      drm_exec_fini(&ctx->exec);
        ctx->sync = NULL;
 -
 -      ctx->reserved = false;
 -      ctx->vm_pd = NULL;
 -
        return ret;
  }
  
@@@ -1662,7 -1709,8 +1662,8 @@@ int amdgpu_amdkfd_gpuvm_alloc_memory_of
                        alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ?
                        AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0;
                }
-               xcp_id = fpriv->xcp_id == ~0 ? 0 : fpriv->xcp_id;
+               xcp_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ?
+                                       0 : fpriv->xcp_id;
        } else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
                domain = alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
                alloc_flags = 0;
@@@ -1807,6 -1855,7 +1808,6 @@@ int amdgpu_amdkfd_gpuvm_free_memory_of_
        bool use_release_notifier = (mem->bo->kfd_bo == mem);
        struct kfd_mem_attachment *entry, *tmp;
        struct bo_vm_reservation_context ctx;
 -      struct ttm_validate_buffer *bo_list_entry;
        unsigned int mapped_to_gpu_memory;
        int ret;
        bool is_imported = false;
        }
  
        /* Make sure restore workers don't access the BO any more */
 -      bo_list_entry = &mem->validate_list;
        mutex_lock(&process_info->lock);
 -      list_del(&bo_list_entry->head);
 +      list_del(&mem->validate_list);
        mutex_unlock(&process_info->lock);
  
        /* Cleanup user pages and MMU notifiers */
@@@ -2402,14 -2452,14 +2403,14 @@@ static int update_invalid_user_pages(st
        /* Move all invalidated BOs to the userptr_inval_list */
        list_for_each_entry_safe(mem, tmp_mem,
                                 &process_info->userptr_valid_list,
 -                               validate_list.head)
 +                               validate_list)
                if (mem->invalid)
 -                      list_move_tail(&mem->validate_list.head,
 +                      list_move_tail(&mem->validate_list,
                                       &process_info->userptr_inval_list);
  
        /* Go through userptr_inval_list and update any invalid user_pages */
        list_for_each_entry(mem, &process_info->userptr_inval_list,
 -                          validate_list.head) {
 +                          validate_list) {
                invalid = mem->invalid;
                if (!invalid)
                        /* BO hasn't been invalidated since the last
@@@ -2489,41 -2539,50 +2490,41 @@@ unlock_out
   */
  static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
  {
 -      struct amdgpu_bo_list_entry *pd_bo_list_entries;
 -      struct list_head resv_list, duplicates;
 -      struct ww_acquire_ctx ticket;
 +      struct ttm_operation_ctx ctx = { false, false };
        struct amdgpu_sync sync;
 +      struct drm_exec exec;
  
        struct amdgpu_vm *peer_vm;
        struct kgd_mem *mem, *tmp_mem;
        struct amdgpu_bo *bo;
 -      struct ttm_operation_ctx ctx = { false, false };
 -      int i, ret;
 -
 -      pd_bo_list_entries = kcalloc(process_info->n_vms,
 -                                   sizeof(struct amdgpu_bo_list_entry),
 -                                   GFP_KERNEL);
 -      if (!pd_bo_list_entries) {
 -              pr_err("%s: Failed to allocate PD BO list entries\n", __func__);
 -              ret = -ENOMEM;
 -              goto out_no_mem;
 -      }
 -
 -      INIT_LIST_HEAD(&resv_list);
 -      INIT_LIST_HEAD(&duplicates);
 +      int ret;
  
 -      /* Get all the page directory BOs that need to be reserved */
 -      i = 0;
 -      list_for_each_entry(peer_vm, &process_info->vm_list_head,
 -                          vm_list_node)
 -              amdgpu_vm_get_pd_bo(peer_vm, &resv_list,
 -                                  &pd_bo_list_entries[i++]);
 -      /* Add the userptr_inval_list entries to resv_list */
 -      list_for_each_entry(mem, &process_info->userptr_inval_list,
 -                          validate_list.head) {
 -              list_add_tail(&mem->resv_list.head, &resv_list);
 -              mem->resv_list.bo = mem->validate_list.bo;
 -              mem->resv_list.num_shared = mem->validate_list.num_shared;
 -      }
 +      amdgpu_sync_create(&sync);
  
 +      drm_exec_init(&exec, 0);
        /* Reserve all BOs and page tables for validation */
 -      ret = ttm_eu_reserve_buffers(&ticket, &resv_list, false, &duplicates);
 -      WARN(!list_empty(&duplicates), "Duplicates should be empty");
 -      if (ret)
 -              goto out_free;
 +      drm_exec_until_all_locked(&exec) {
 +              /* Reserve all the page directories */
 +              list_for_each_entry(peer_vm, &process_info->vm_list_head,
 +                                  vm_list_node) {
 +                      ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
 +                      drm_exec_retry_on_contention(&exec);
 +                      if (unlikely(ret))
 +                              goto unreserve_out;
 +              }
  
 -      amdgpu_sync_create(&sync);
 +              /* Reserve the userptr_inval_list entries to resv_list */
 +              list_for_each_entry(mem, &process_info->userptr_inval_list,
 +                                  validate_list) {
 +                      struct drm_gem_object *gobj;
 +
 +                      gobj = &mem->bo->tbo.base;
 +                      ret = drm_exec_prepare_obj(&exec, gobj, 1);
 +                      drm_exec_retry_on_contention(&exec);
 +                      if (unlikely(ret))
 +                              goto unreserve_out;
 +              }
 +      }
  
        ret = process_validate_vms(process_info);
        if (ret)
        /* Validate BOs and update GPUVM page tables */
        list_for_each_entry_safe(mem, tmp_mem,
                                 &process_info->userptr_inval_list,
 -                               validate_list.head) {
 +                               validate_list) {
                struct kfd_mem_attachment *attachment;
  
                bo = mem->bo;
        ret = process_update_pds(process_info, &sync);
  
  unreserve_out:
 -      ttm_eu_backoff_reservation(&ticket, &resv_list);
 +      drm_exec_fini(&exec);
        amdgpu_sync_wait(&sync, false);
        amdgpu_sync_free(&sync);
 -out_free:
 -      kfree(pd_bo_list_entries);
 -out_no_mem:
  
        return ret;
  }
@@@ -2592,7 -2654,7 +2593,7 @@@ static int confirm_valid_user_pages_loc
  
        list_for_each_entry_safe(mem, tmp_mem,
                                 &process_info->userptr_inval_list,
 -                               validate_list.head) {
 +                               validate_list) {
                bool valid;
  
                /* keep mem without hmm range at userptr_inval_list */
                        continue;
                }
  
 -              list_move_tail(&mem->validate_list.head,
 +              list_move_tail(&mem->validate_list,
                               &process_info->userptr_valid_list);
        }
  
@@@ -2726,44 -2788,50 +2727,44 @@@ unlock_out
   */
  int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
  {
 -      struct amdgpu_bo_list_entry *pd_bo_list;
        struct amdkfd_process_info *process_info = info;
        struct amdgpu_vm *peer_vm;
        struct kgd_mem *mem;
 -      struct bo_vm_reservation_context ctx;
        struct amdgpu_amdkfd_fence *new_fence;
 -      int ret = 0, i;
        struct list_head duplicate_save;
        struct amdgpu_sync sync_obj;
        unsigned long failed_size = 0;
        unsigned long total_size = 0;
 +      struct drm_exec exec;
 +      int ret;
  
        INIT_LIST_HEAD(&duplicate_save);
 -      INIT_LIST_HEAD(&ctx.list);
 -      INIT_LIST_HEAD(&ctx.duplicates);
 -
 -      pd_bo_list = kcalloc(process_info->n_vms,
 -                           sizeof(struct amdgpu_bo_list_entry),
 -                           GFP_KERNEL);
 -      if (!pd_bo_list)
 -              return -ENOMEM;
  
 -      i = 0;
        mutex_lock(&process_info->lock);
 -      list_for_each_entry(peer_vm, &process_info->vm_list_head,
 -                      vm_list_node)
 -              amdgpu_vm_get_pd_bo(peer_vm, &ctx.list, &pd_bo_list[i++]);
  
 -      /* Reserve all BOs and page tables/directory. Add all BOs from
 -       * kfd_bo_list to ctx.list
 -       */
 -      list_for_each_entry(mem, &process_info->kfd_bo_list,
 -                          validate_list.head) {
 -
 -              list_add_tail(&mem->resv_list.head, &ctx.list);
 -              mem->resv_list.bo = mem->validate_list.bo;
 -              mem->resv_list.num_shared = mem->validate_list.num_shared;
 -      }
 +      drm_exec_init(&exec, 0);
 +      drm_exec_until_all_locked(&exec) {
 +              list_for_each_entry(peer_vm, &process_info->vm_list_head,
 +                                  vm_list_node) {
 +                      ret = amdgpu_vm_lock_pd(peer_vm, &exec, 2);
 +                      drm_exec_retry_on_contention(&exec);
 +                      if (unlikely(ret))
 +                              goto ttm_reserve_fail;
 +              }
  
 -      ret = ttm_eu_reserve_buffers(&ctx.ticket, &ctx.list,
 -                                   false, &duplicate_save);
 -      if (ret) {
 -              pr_debug("Memory eviction: TTM Reserve Failed. Try again\n");
 -              goto ttm_reserve_fail;
 +              /* Reserve all BOs and page tables/directory. Add all BOs from
 +               * kfd_bo_list to ctx.list
 +               */
 +              list_for_each_entry(mem, &process_info->kfd_bo_list,
 +                                  validate_list) {
 +                      struct drm_gem_object *gobj;
 +
 +                      gobj = &mem->bo->tbo.base;
 +                      ret = drm_exec_prepare_obj(&exec, gobj, 1);
 +                      drm_exec_retry_on_contention(&exec);
 +                      if (unlikely(ret))
 +                              goto ttm_reserve_fail;
 +              }
        }
  
        amdgpu_sync_create(&sync_obj);
  
        /* Validate BOs and map them to GPUVM (update VM page tables). */
        list_for_each_entry(mem, &process_info->kfd_bo_list,
 -                          validate_list.head) {
 +                          validate_list) {
  
                struct amdgpu_bo *bo = mem->bo;
                uint32_t domain = mem->domain;
        *ef = dma_fence_get(&new_fence->base);
  
        /* Attach new eviction fence to all BOs except pinned ones */
 -      list_for_each_entry(mem, &process_info->kfd_bo_list,
 -              validate_list.head) {
 +      list_for_each_entry(mem, &process_info->kfd_bo_list, validate_list) {
                if (mem->bo->tbo.pin_count)
                        continue;
  
        }
  
  validate_map_fail:
 -      ttm_eu_backoff_reservation(&ctx.ticket, &ctx.list);
        amdgpu_sync_free(&sync_obj);
  ttm_reserve_fail:
 +      drm_exec_fini(&exec);
        mutex_unlock(&process_info->lock);
 -      kfree(pd_bo_list);
        return ret;
  }
  
index e90f730eb715d9fadd26e4c670ac5278e12883b8,144fcb32666895ee715bf53dc3396fa6c6b6ed6c..d6439d56dcd59d551aa7758b1db358ccfa412d5a
@@@ -313,9 -313,7 +313,7 @@@ module_param_named(msi, amdgpu_msi, int
   * jobs is 10000. The timeout for compute is 60000.
   */
  MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: for bare metal 10000 for non-compute jobs and 60000 for compute jobs; "
-               "for passthrough or sriov, 10000 for all jobs."
-               " 0: keep default value. negative: infinity timeout), "
-               "format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; "
+               "for passthrough or sriov, 10000 for all jobs. 0: keep default value. negative: infinity timeout), format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; "
                "for passthrough or sriov [all jobs] or [GFX,Compute,SDMA,Video].");
  module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_timeout), 0444);
  
@@@ -584,7 -582,7 +582,7 @@@ module_param_named(timeout_period, amdg
   */
  #ifdef CONFIG_DRM_AMDGPU_SI
  
- #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
+ #if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
  int amdgpu_si_support = 0;
  MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
  #else
@@@ -603,7 -601,7 +601,7 @@@ module_param_named(si_support, amdgpu_s
   */
  #ifdef CONFIG_DRM_AMDGPU_CIK
  
- #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
+ #if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE)
  int amdgpu_cik_support = 0;
  MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
  #else
@@@ -620,8 -618,7 +618,7 @@@ module_param_named(cik_support, amdgpu_
   * E.g. 0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte. The default is 0 (disabled).
   */
  MODULE_PARM_DESC(smu_memory_pool_size,
-       "reserve gtt for smu debug usage, 0 = disable,"
-               "0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte");
+       "reserve gtt for smu debug usage, 0 = disable,0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte");
  module_param_named(smu_memory_pool_size, amdgpu_smu_memory_pool_size, uint, 0444);
  
  /**
@@@ -791,9 -788,9 +788,9 @@@ module_param(hws_gws_support, bool, 044
  MODULE_PARM_DESC(hws_gws_support, "Assume MEC2 FW supports GWS barriers (false = rely on FW version check (Default), true = force supported)");
  
  /**
-   * DOC: queue_preemption_timeout_ms (int)
-   * queue preemption timeout in ms (1 = Minimum, 9000 = default)
-   */
+  * DOC: queue_preemption_timeout_ms (int)
+  * queue preemption timeout in ms (1 = Minimum, 9000 = default)
+  */
  int queue_preemption_timeout_ms = 9000;
  module_param(queue_preemption_timeout_ms, int, 0644);
  MODULE_PARM_DESC(queue_preemption_timeout_ms, "queue preemption timeout in ms (1 = Minimum, 9000 = default)");
@@@ -2417,7 -2414,6 +2414,6 @@@ static void amdgpu_drv_delayed_reset_wo
                        amdgpu_amdkfd_device_init(adev);
                amdgpu_ttm_set_buffer_funcs_status(adev, true);
        }
-       return;
  }
  
  static int amdgpu_pmops_prepare(struct device *dev)
@@@ -2614,6 -2610,7 +2610,7 @@@ static int amdgpu_pmops_runtime_suspend
        /* wait for all rings to drain before suspending */
        for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
                struct amdgpu_ring *ring = adev->rings[i];
                if (ring && ring->sched.ready) {
                        ret = amdgpu_fence_wait_empty(ring);
                        if (ret)
@@@ -2738,6 -2735,7 +2735,7 @@@ long amdgpu_drm_ioctl(struct file *filp
        struct drm_file *file_priv = filp->private_data;
        struct drm_device *dev;
        long ret;
        dev = file_priv->minor->dev;
        ret = pm_runtime_get_sync(dev->dev);
        if (ret < 0)
@@@ -2802,9 -2800,8 +2800,8 @@@ int amdgpu_file_to_fpriv(struct file *f
        if (!filp)
                return -EINVAL;
  
-       if (filp->f_op != &amdgpu_driver_kms_fops) {
+       if (filp->f_op != &amdgpu_driver_kms_fops)
                return -EINVAL;
-       }
  
        file = filp->private_data;
        *fpriv = file->driver_priv;
@@@ -2850,7 -2847,10 +2847,7 @@@ static const struct drm_driver amdgpu_k
        .show_fdinfo = amdgpu_show_fdinfo,
  #endif
  
 -      .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 -      .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
        .gem_prime_import = amdgpu_gem_prime_import,
 -      .gem_prime_mmap = drm_gem_prime_mmap,
  
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
@@@ -2874,7 -2874,10 +2871,7 @@@ const struct drm_driver amdgpu_partitio
        .fops = &amdgpu_driver_kms_fops,
        .release = &amdgpu_driver_release_kms,
  
 -      .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 -      .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
        .gem_prime_import = amdgpu_gem_prime_import,
 -      .gem_prime_mmap = drm_gem_prime_mmap,
  
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
@@@ -2891,16 -2894,13 +2888,13 @@@ static struct pci_error_handlers amdgpu
        .resume         = amdgpu_pci_resume,
  };
  
- extern const struct attribute_group amdgpu_vram_mgr_attr_group;
- extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
  static const struct attribute_group *amdgpu_sysfs_groups[] = {
        &amdgpu_vram_mgr_attr_group,
        &amdgpu_gtt_mgr_attr_group,
+       &amdgpu_flash_attr_group,
        NULL,
  };
  
  static struct pci_driver amdgpu_kms_pci_driver = {
        .name = DRIVER_NAME,
        .id_table = pciidlist,
index 7da871972a8eeec76ccfff4523ad6ede05f62f19,992dfd3de49c0ef3e4b021ed8e9968c6d7963d65..693b1fd1191a56c4a4c4f741b4e392f4c49d4484
@@@ -33,7 -33,6 +33,7 @@@
  
  #include <drm/amdgpu_drm.h>
  #include <drm/drm_drv.h>
 +#include <drm/drm_exec.h>
  #include <drm/drm_gem_ttm_helper.h>
  #include <drm/ttm/ttm_tt.h>
  
@@@ -182,11 -181,10 +182,10 @@@ static int amdgpu_gem_object_open(struc
                return r;
  
        bo_va = amdgpu_vm_bo_find(vm, abo);
-       if (!bo_va) {
+       if (!bo_va)
                bo_va = amdgpu_vm_bo_add(adev, vm, abo);
-       } else {
+       else
                ++bo_va->ref_count;
-       }
        amdgpu_bo_unreserve(abo);
        return 0;
  }
@@@ -199,24 -197,29 +198,24 @@@ static void amdgpu_gem_object_close(str
        struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
        struct amdgpu_vm *vm = &fpriv->vm;
  
 -      struct amdgpu_bo_list_entry vm_pd;
 -      struct list_head list, duplicates;
        struct dma_fence *fence = NULL;
 -      struct ttm_validate_buffer tv;
 -      struct ww_acquire_ctx ticket;
        struct amdgpu_bo_va *bo_va;
 +      struct drm_exec exec;
        long r;
  
 -      INIT_LIST_HEAD(&list);
 -      INIT_LIST_HEAD(&duplicates);
 -
 -      tv.bo = &bo->tbo;
 -      tv.num_shared = 2;
 -      list_add(&tv.head, &list);
 -
 -      amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
 -
 -      r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
 -      if (r) {
 -              dev_err(adev->dev, "leaking bo va because we fail to reserve bo (%ld)\n",
 -                      r);
 -              return;
 +      drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES);
 +      drm_exec_until_all_locked(&exec) {
 +              r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto out_unlock;
 +
 +              r = amdgpu_vm_lock_pd(vm, &exec, 0);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto out_unlock;
        }
 +
        bo_va = amdgpu_vm_bo_find(vm, bo);
        if (!bo_va || --bo_va->ref_count)
                goto out_unlock;
                goto out_unlock;
  
        r = amdgpu_vm_clear_freed(adev, vm, &fence);
 +      if (unlikely(r < 0))
 +              dev_err(adev->dev, "failed to clear page "
 +                      "tables on GEM object close (%ld)\n", r);
        if (r || !fence)
                goto out_unlock;
  
        dma_fence_put(fence);
  
  out_unlock:
 -      if (unlikely(r < 0))
 -              dev_err(adev->dev, "failed to clear page tables on GEM object close (%ld)\n",
 -                      r);
 -      ttm_eu_backoff_reservation(&ticket, &list);
 +      if (r)
 +              dev_err(adev->dev, "leaking bo va (%ld)\n", r);
 +      drm_exec_fini(&exec);
  }
  
  static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
@@@ -461,9 -462,9 +460,9 @@@ int amdgpu_mode_dumb_mmap(struct drm_fi
        struct amdgpu_bo *robj;
  
        gobj = drm_gem_object_lookup(filp, handle);
-       if (gobj == NULL) {
+       if (!gobj)
                return -ENOENT;
-       }
        robj = gem_to_amdgpu_bo(gobj);
        if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||
            (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
@@@ -480,6 -481,7 +479,7 @@@ int amdgpu_gem_mmap_ioctl(struct drm_de
  {
        union drm_amdgpu_gem_mmap *args = data;
        uint32_t handle = args->in.handle;
        memset(args, 0, sizeof(*args));
        return amdgpu_mode_dumb_mmap(filp, dev, handle, &args->out.addr_ptr);
  }
@@@ -506,7 -508,7 +506,7 @@@ unsigned long amdgpu_gem_timeout(uint64
  
        timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout));
        /*  clamp timeout to avoid unsigned-> signed overflow */
-       if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT )
+       if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT)
                return MAX_SCHEDULE_TIMEOUT - 1;
  
        return timeout_jiffies;
@@@ -524,9 -526,9 +524,9 @@@ int amdgpu_gem_wait_idle_ioctl(struct d
        long ret;
  
        gobj = drm_gem_object_lookup(filp, handle);
-       if (gobj == NULL) {
+       if (!gobj)
                return -ENOENT;
-       }
        robj = gem_to_amdgpu_bo(gobj);
        ret = dma_resv_wait_timeout(robj->tbo.base.resv, DMA_RESV_USAGE_READ,
                                    true, timeout);
@@@ -553,7 -555,7 +553,7 @@@ int amdgpu_gem_metadata_ioctl(struct dr
        struct amdgpu_bo *robj;
        int r = -1;
  
-       DRM_DEBUG("%d \n", args->handle);
+       DRM_DEBUG("%d\n", args->handle);
        gobj = drm_gem_object_lookup(filp, args->handle);
        if (gobj == NULL)
                return -ENOENT;
@@@ -673,14 -675,17 +673,14 @@@ int amdgpu_gem_va_ioctl(struct drm_devi
        struct amdgpu_fpriv *fpriv = filp->driver_priv;
        struct amdgpu_bo *abo;
        struct amdgpu_bo_va *bo_va;
 -      struct amdgpu_bo_list_entry vm_pd;
 -      struct ttm_validate_buffer tv;
 -      struct ww_acquire_ctx ticket;
 -      struct list_head list, duplicates;
 +      struct drm_exec exec;
        uint64_t va_flags;
        uint64_t vm_size;
        int r = 0;
  
        if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
                dev_dbg(dev->dev,
-                       "va_address 0x%LX is in reserved area 0x%LX\n",
+                       "va_address 0x%llx is in reserved area 0x%llx\n",
                        args->va_address, AMDGPU_VA_RESERVED_SIZE);
                return -EINVAL;
        }
        if (args->va_address >= AMDGPU_GMC_HOLE_START &&
            args->va_address < AMDGPU_GMC_HOLE_END) {
                dev_dbg(dev->dev,
-                       "va_address 0x%LX is in VA hole 0x%LX-0x%LX\n",
+                       "va_address 0x%llx is in VA hole 0x%llx-0x%llx\n",
                        args->va_address, AMDGPU_GMC_HOLE_START,
                        AMDGPU_GMC_HOLE_END);
                return -EINVAL;
                return -EINVAL;
        }
  
 -      INIT_LIST_HEAD(&list);
 -      INIT_LIST_HEAD(&duplicates);
        if ((args->operation != AMDGPU_VA_OP_CLEAR) &&
            !(args->flags & AMDGPU_VM_PAGE_PRT)) {
                gobj = drm_gem_object_lookup(filp, args->handle);
                if (gobj == NULL)
                        return -ENOENT;
                abo = gem_to_amdgpu_bo(gobj);
 -              tv.bo = &abo->tbo;
 -              if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID)
 -                      tv.num_shared = 1;
 -              else
 -                      tv.num_shared = 0;
 -              list_add(&tv.head, &list);
        } else {
                gobj = NULL;
                abo = NULL;
        }
  
 -      amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
 +      drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
 +                    DRM_EXEC_IGNORE_DUPLICATES);
 +      drm_exec_until_all_locked(&exec) {
 +              if (gobj) {
 +                      r = drm_exec_lock_obj(&exec, gobj);
 +                      drm_exec_retry_on_contention(&exec);
 +                      if (unlikely(r))
 +                              goto error;
 +              }
  
 -      r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
 -      if (r)
 -              goto error_unref;
 +              r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 2);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto error;
 +      }
  
        if (abo) {
                bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo);
                if (!bo_va) {
                        r = -ENOENT;
 -                      goto error_backoff;
 +                      goto error;
                }
        } else if (args->operation != AMDGPU_VA_OP_CLEAR) {
                bo_va = fpriv->prt_va;
                amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
                                        args->operation);
  
 -error_backoff:
 -      ttm_eu_backoff_reservation(&ticket, &list);
 -
 -error_unref:
 +error:
 +      drm_exec_fini(&exec);
        drm_gem_object_put(gobj);
        return r;
  }
@@@ -808,9 -813,9 +808,9 @@@ int amdgpu_gem_op_ioctl(struct drm_devi
        int r;
  
        gobj = drm_gem_object_lookup(filp, args->handle);
-       if (gobj == NULL) {
+       if (!gobj)
                return -ENOENT;
-       }
        robj = gem_to_amdgpu_bo(gobj);
  
        r = amdgpu_bo_reserve(robj, false);
@@@ -936,9 -941,9 +936,9 @@@ int amdgpu_mode_dumb_create(struct drm_
        r = drm_gem_handle_create(file_priv, gobj, &handle);
        /* drop reference from allocate - handle holds it now */
        drm_gem_object_put(gobj);
-       if (r) {
+       if (r)
                return r;
-       }
        args->handle = handle;
        return 0;
  }
index 3e3dadd6d0f39c4952403f1823ea1c95e38ac5c7,72ab6a838bb68b925864a797df4dd7266443b34f..37f15abf7543c7387598e9cb16780d985f143028
@@@ -22,7 -22,6 +22,7 @@@
   */
  
  #include <linux/firmware.h>
 +#include <drm/drm_exec.h>
  
  #include "amdgpu_mes.h"
  #include "amdgpu.h"
@@@ -643,6 -642,8 +643,8 @@@ int amdgpu_mes_add_hw_queue(struct amdg
        unsigned long flags;
        int r;
  
+       memset(&queue_input, 0, sizeof(struct mes_add_queue_input));
        /* allocate the mes queue buffer */
        queue = kzalloc(sizeof(struct amdgpu_mes_queue), GFP_KERNEL);
        if (!queue) {
@@@ -1169,31 -1170,34 +1171,31 @@@ int amdgpu_mes_ctx_map_meta_data(struc
                                 struct amdgpu_mes_ctx_data *ctx_data)
  {
        struct amdgpu_bo_va *bo_va;
 -      struct ww_acquire_ctx ticket;
 -      struct list_head list;
 -      struct amdgpu_bo_list_entry pd;
 -      struct ttm_validate_buffer csa_tv;
        struct amdgpu_sync sync;
 +      struct drm_exec exec;
        int r;
  
        amdgpu_sync_create(&sync);
 -      INIT_LIST_HEAD(&list);
 -      INIT_LIST_HEAD(&csa_tv.head);
  
 -      csa_tv.bo = &ctx_data->meta_data_obj->tbo;
 -      csa_tv.num_shared = 1;
 -
 -      list_add(&csa_tv.head, &list);
 -      amdgpu_vm_get_pd_bo(vm, &list, &pd);
 -
 -      r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
 -      if (r) {
 -              DRM_ERROR("failed to reserve meta data BO: err=%d\n", r);
 -              return r;
 +      drm_exec_init(&exec, 0);
 +      drm_exec_until_all_locked(&exec) {
 +              r = drm_exec_lock_obj(&exec,
 +                                    &ctx_data->meta_data_obj->tbo.base);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto error_fini_exec;
 +
 +              r = amdgpu_vm_lock_pd(vm, &exec, 0);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto error_fini_exec;
        }
  
        bo_va = amdgpu_vm_bo_add(adev, vm, ctx_data->meta_data_obj);
        if (!bo_va) {
 -              ttm_eu_backoff_reservation(&ticket, &list);
                DRM_ERROR("failed to create bo_va for meta data BO\n");
 -              return -ENOMEM;
 +              r = -ENOMEM;
 +              goto error_fini_exec;
        }
  
        r = amdgpu_vm_bo_map(adev, bo_va, ctx_data->meta_data_gpu_addr, 0,
  
        if (r) {
                DRM_ERROR("failed to do bo_map on meta data, err=%d\n", r);
 -              goto error;
 +              goto error_del_bo_va;
        }
  
        r = amdgpu_vm_bo_update(adev, bo_va, false);
        if (r) {
                DRM_ERROR("failed to do vm_bo_update on meta data\n");
 -              goto error;
 +              goto error_del_bo_va;
        }
        amdgpu_sync_fence(&sync, bo_va->last_pt_update);
  
        r = amdgpu_vm_update_pdes(adev, vm, false);
        if (r) {
                DRM_ERROR("failed to update pdes on meta data\n");
 -              goto error;
 +              goto error_del_bo_va;
        }
        amdgpu_sync_fence(&sync, vm->last_update);
  
        amdgpu_sync_wait(&sync, false);
 -      ttm_eu_backoff_reservation(&ticket, &list);
 +      drm_exec_fini(&exec);
  
        amdgpu_sync_free(&sync);
        ctx_data->meta_data_va = bo_va;
        return 0;
  
 -error:
 +error_del_bo_va:
        amdgpu_vm_bo_del(adev, bo_va);
 -      ttm_eu_backoff_reservation(&ticket, &list);
 +
 +error_fini_exec:
 +      drm_exec_fini(&exec);
        amdgpu_sync_free(&sync);
        return r;
  }
@@@ -1242,30 -1244,34 +1244,30 @@@ int amdgpu_mes_ctx_unmap_meta_data(stru
        struct amdgpu_bo_va *bo_va = ctx_data->meta_data_va;
        struct amdgpu_bo *bo = ctx_data->meta_data_obj;
        struct amdgpu_vm *vm = bo_va->base.vm;
 -      struct amdgpu_bo_list_entry vm_pd;
 -      struct list_head list, duplicates;
 -      struct dma_fence *fence = NULL;
 -      struct ttm_validate_buffer tv;
 -      struct ww_acquire_ctx ticket;
 -      long r = 0;
 -
 -      INIT_LIST_HEAD(&list);
 -      INIT_LIST_HEAD(&duplicates);
 -
 -      tv.bo = &bo->tbo;
 -      tv.num_shared = 2;
 -      list_add(&tv.head, &list);
 -
 -      amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
 -
 -      r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
 -      if (r) {
 -              dev_err(adev->dev, "leaking bo va because "
 -                      "we fail to reserve bo (%ld)\n", r);
 -              return r;
 +      struct dma_fence *fence;
 +      struct drm_exec exec;
 +      long r;
 +
 +      drm_exec_init(&exec, 0);
 +      drm_exec_until_all_locked(&exec) {
 +              r = drm_exec_lock_obj(&exec,
 +                                    &ctx_data->meta_data_obj->tbo.base);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto out_unlock;
 +
 +              r = amdgpu_vm_lock_pd(vm, &exec, 0);
 +              drm_exec_retry_on_contention(&exec);
 +              if (unlikely(r))
 +                      goto out_unlock;
        }
  
        amdgpu_vm_bo_del(adev, bo_va);
        if (!amdgpu_vm_ready(vm))
                goto out_unlock;
  
 -      r = dma_resv_get_singleton(bo->tbo.base.resv, DMA_RESV_USAGE_BOOKKEEP, &fence);
 +      r = dma_resv_get_singleton(bo->tbo.base.resv, DMA_RESV_USAGE_BOOKKEEP,
 +                                 &fence);
        if (r)
                goto out_unlock;
        if (fence) {
  out_unlock:
        if (unlikely(r < 0))
                dev_err(adev->dev, "failed to clear page tables (%ld)\n", r);
 -      ttm_eu_backoff_reservation(&ticket, &list);
 +      drm_exec_fini(&exec);
  
        return r;
  }
@@@ -1378,7 -1384,7 +1380,7 @@@ int amdgpu_mes_self_test(struct amdgpu_
                goto error_pasid;
        }
  
-       r = amdgpu_vm_init(adev, vm);
+       r = amdgpu_vm_init(adev, vm, -1);
        if (r) {
                DRM_ERROR("failed to initialize vm\n");
                goto error_pasid;
index d0e6009a985bc0ce8748bbc88c902aae1dd506ed,74380b21e7a5571a521941a5811ba498e27f00a2..f5daadcec865d6863650d1d515fd416ac890595c
@@@ -34,7 -34,6 +34,7 @@@
  #include <drm/amdgpu_drm.h>
  #include <drm/drm_drv.h>
  #include <drm/ttm/ttm_tt.h>
 +#include <drm/drm_exec.h>
  #include "amdgpu.h"
  #include "amdgpu_trace.h"
  #include "amdgpu_amdkfd.h"
@@@ -112,9 -111,9 +112,9 @@@ struct amdgpu_prt_cb 
  };
  
  /**
-  * struct amdgpu_vm_tlb_seq_cb - Helper to increment the TLB flush sequence
+  * struct amdgpu_vm_tlb_seq_struct - Helper to increment the TLB flush sequence
   */
- struct amdgpu_vm_tlb_seq_cb {
+ struct amdgpu_vm_tlb_seq_struct {
        /**
         * @vm: pointer to the amdgpu_vm structure to set the fence sequence on
         */
@@@ -340,20 -339,25 +340,20 @@@ void amdgpu_vm_bo_base_init(struct amdg
  }
  
  /**
 - * amdgpu_vm_get_pd_bo - add the VM PD to a validation list
 + * amdgpu_vm_lock_pd - lock PD in drm_exec
   *
   * @vm: vm providing the BOs
 - * @validated: head of validation list
 - * @entry: entry to add
 + * @exec: drm execution context
 + * @num_fences: number of extra fences to reserve
   *
 - * Add the page directory to the list of BOs to
 - * validate for command submission.
 + * Lock the VM root PD in the DRM execution context.
   */
 -void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
 -                       struct list_head *validated,
 -                       struct amdgpu_bo_list_entry *entry)
 +int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec,
 +                    unsigned int num_fences)
  {
 -      entry->priority = 0;
 -      entry->tv.bo = &vm->root.bo->tbo;
 -      /* Two for VM updates, one for TTM and one for the CS job */
 -      entry->tv.num_shared = 4;
 -      entry->user_pages = NULL;
 -      list_add(&entry->tv.head, validated);
 +      /* We need at least two fences for the VM PD/PT updates */
 +      return drm_exec_prepare_obj(exec, &vm->root.bo->tbo.base,
 +                                  2 + num_fences);
  }
  
  /**
@@@ -829,7 -833,7 +829,7 @@@ error
  static void amdgpu_vm_tlb_seq_cb(struct dma_fence *fence,
                                 struct dma_fence_cb *cb)
  {
-       struct amdgpu_vm_tlb_seq_cb *tlb_cb;
+       struct amdgpu_vm_tlb_seq_struct *tlb_cb;
  
        tlb_cb = container_of(cb, typeof(*tlb_cb), cb);
        atomic64_inc(&tlb_cb->vm->tlb_seq);
@@@ -867,7 -871,7 +867,7 @@@ int amdgpu_vm_update_range(struct amdgp
                           struct dma_fence **fence)
  {
        struct amdgpu_vm_update_params params;
-       struct amdgpu_vm_tlb_seq_cb *tlb_cb;
+       struct amdgpu_vm_tlb_seq_struct *tlb_cb;
        struct amdgpu_res_cursor cursor;
        enum amdgpu_sync_mode sync_mode;
        int r, idx;
@@@ -2117,13 -2121,14 +2117,14 @@@ long amdgpu_vm_wait_idle(struct amdgpu_
   *
   * @adev: amdgpu_device pointer
   * @vm: requested vm
+  * @xcp_id: GPU partition selection id
   *
   * Init @vm fields.
   *
   * Returns:
   * 0 for success, error for failure.
   */
- int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)
  {
        struct amdgpu_bo *root_bo;
        struct amdgpu_bo_vm *root;
        vm->evicting = false;
  
        r = amdgpu_vm_pt_create(adev, vm, adev->vm_manager.root_level,
-                               false, &root);
+                               false, &root, xcp_id);
        if (r)
                goto error_free_delayed;
        root_bo = &root->bo;
@@@ -2275,16 -2280,13 +2276,13 @@@ int amdgpu_vm_make_compute(struct amdgp
                        goto unreserve_bo;
  
                vm->update_funcs = &amdgpu_vm_cpu_funcs;
+               r = amdgpu_vm_pt_map_tables(adev, vm);
+               if (r)
+                       goto unreserve_bo;
        } else {
                vm->update_funcs = &amdgpu_vm_sdma_funcs;
        }
-       /*
-        * Make sure root PD gets mapped. As vm_update_mode could be changed
-        * when turning a GFX VM into a compute VM.
-        */
-       r = vm->update_funcs->map_table(to_amdgpu_bo_vm(vm->root.bo));
-       if (r)
-               goto unreserve_bo;
  
        dma_fence_put(vm->last_update);
        vm->last_update = dma_fence_get_stub();
@@@ -2600,7 -2602,7 +2598,7 @@@ bool amdgpu_vm_handle_fault(struct amdg
                /* Intentionally setting invalid PTE flag
                 * combination to force a no-retry-fault
                 */
-               flags = AMDGPU_PTE_SNOOPED | AMDGPU_PTE_PRT;
+               flags = AMDGPU_VM_NORETRY_FLAGS;
                value = 0;
        } else if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_NEVER) {
                /* Redirect the access to the dummy page */
index 45bcf46c6f591a54716e633be6f4b695ceee333c,bca258c3891914adb15eb8851312f273413e889c..204ab13184ed1ce1b040e36b67e5a038060505d6
@@@ -36,8 -36,6 +36,8 @@@
  #include "amdgpu_ring.h"
  #include "amdgpu_ids.h"
  
 +struct drm_exec;
 +
  struct amdgpu_bo_va;
  struct amdgpu_job;
  struct amdgpu_bo_list_entry;
@@@ -86,7 -84,13 +86,13 @@@ struct amdgpu_mem_stats
  /* PDE Block Fragment Size for VEGA10 */
  #define AMDGPU_PDE_BFS(a)     ((uint64_t)a << 59)
  
+ /* Flag combination to set no-retry with TF disabled */
+ #define AMDGPU_VM_NORETRY_FLAGS       (AMDGPU_PTE_EXECUTABLE | AMDGPU_PDE_PTE | \
+                               AMDGPU_PTE_TF)
  
+ /* Flag combination to set no-retry with TF enabled */
+ #define AMDGPU_VM_NORETRY_FLAGS_TF (AMDGPU_PTE_VALID | AMDGPU_PTE_SYSTEM | \
+                                  AMDGPU_PTE_PRT)
  /* For GFX9 */
  #define AMDGPU_PTE_MTYPE_VG10(a)      ((uint64_t)(a) << 57)
  #define AMDGPU_PTE_MTYPE_VG10_MASK    AMDGPU_PTE_MTYPE_VG10(3ULL)
@@@ -394,12 -398,13 +400,12 @@@ int amdgpu_vm_set_pasid(struct amdgpu_d
                        u32 pasid);
  
  long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
- int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
+ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id);
  int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
  void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
  void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
 -void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
 -                       struct list_head *validated,
 -                       struct amdgpu_bo_list_entry *entry);
 +int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec,
 +                    unsigned int num_fences);
  bool amdgpu_vm_ready(struct amdgpu_vm *vm);
  uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm);
  int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
@@@ -476,7 -481,8 +482,8 @@@ void amdgpu_vm_get_memory(struct amdgpu
  int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                       struct amdgpu_bo_vm *vmbo, bool immediate);
  int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-                       int level, bool immediate, struct amdgpu_bo_vm **vmbo);
+                       int level, bool immediate, struct amdgpu_bo_vm **vmbo,
+                       int32_t xcp_id);
  void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm);
  bool amdgpu_vm_pt_is_root_clean(struct amdgpu_device *adev,
                                struct amdgpu_vm *vm);
@@@ -492,6 -498,8 +499,8 @@@ void amdgpu_vm_pt_free_work(struct work
  void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
  #endif
  
+ int amdgpu_vm_pt_map_tables(struct amdgpu_device *adev, struct amdgpu_vm *vm);
  /**
   * amdgpu_vm_tlb_seq - return tlb flush sequence number
   * @vm: the amdgpu_vm structure to query
index aa32b06eea7759e5158fa49a8727ba8870ca8c4d,1b50eae051a4bcab7447048f44d8b378bf274f59..01c7de2d6e1991619bd4d26b9e5e391e97ee5a40
@@@ -24,8 -24,6 +24,8 @@@
  #include <linux/types.h>
  #include <linux/sched/task.h>
  #include <drm/ttm/ttm_tt.h>
 +#include <drm/drm_exec.h>
 +
  #include "amdgpu_sync.h"
  #include "amdgpu_object.h"
  #include "amdgpu_vm.h"
@@@ -48,6 -46,8 +48,8 @@@
   * page table is updated.
   */
  #define AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING  (2UL * NSEC_PER_MSEC)
+ #define dynamic_svm_range_dump(svms) \
+       _dynamic_func_call_no_desc("svm_range_dump", svm_range_debug_dump, svms)
  
  /* Giant svm range split into smaller ranges based on this, it is decided using
   * minimum of all dGPU/APU 1/32 VRAM size, between 2MB to 1GB and alignment to
@@@ -1457,34 -1457,37 +1459,34 @@@ struct svm_validate_context 
        struct svm_range *prange;
        bool intr;
        DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE);
 -      struct ttm_validate_buffer tv[MAX_GPU_INSTANCE];
 -      struct list_head validate_list;
 -      struct ww_acquire_ctx ticket;
 +      struct drm_exec exec;
  };
  
 -static int svm_range_reserve_bos(struct svm_validate_context *ctx)
 +static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr)
  {
        struct kfd_process_device *pdd;
        struct amdgpu_vm *vm;
        uint32_t gpuidx;
        int r;
  
 -      INIT_LIST_HEAD(&ctx->validate_list);
 -      for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) {
 -              pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx);
 -              if (!pdd) {
 -                      pr_debug("failed to find device idx %d\n", gpuidx);
 -                      return -EINVAL;
 -              }
 -              vm = drm_priv_to_vm(pdd->drm_priv);
 -
 -              ctx->tv[gpuidx].bo = &vm->root.bo->tbo;
 -              ctx->tv[gpuidx].num_shared = 4;
 -              list_add(&ctx->tv[gpuidx].head, &ctx->validate_list);
 -      }
 +      drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0);
 +      drm_exec_until_all_locked(&ctx->exec) {
 +              for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) {
 +                      pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx);
 +                      if (!pdd) {
 +                              pr_debug("failed to find device idx %d\n", gpuidx);
 +                              r = -EINVAL;
 +                              goto unreserve_out;
 +                      }
 +                      vm = drm_priv_to_vm(pdd->drm_priv);
  
 -      r = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->validate_list,
 -                                 ctx->intr, NULL);
 -      if (r) {
 -              pr_debug("failed %d to reserve bo\n", r);
 -              return r;
 +                      r = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
 +                      drm_exec_retry_on_contention(&ctx->exec);
 +                      if (unlikely(r)) {
 +                              pr_debug("failed %d to reserve bo\n", r);
 +                              goto unreserve_out;
 +                      }
 +              }
        }
  
        for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) {
        return 0;
  
  unreserve_out:
 -      ttm_eu_backoff_reservation(&ctx->ticket, &ctx->validate_list);
 +      drm_exec_fini(&ctx->exec);
        return r;
  }
  
  static void svm_range_unreserve_bos(struct svm_validate_context *ctx)
  {
 -      ttm_eu_backoff_reservation(&ctx->ticket, &ctx->validate_list);
 +      drm_exec_fini(&ctx->exec);
  }
  
  static void *kfd_svm_page_owner(struct kfd_process *p, int32_t gpuidx)
        struct kfd_process_device *pdd;
  
        pdd = kfd_process_device_from_gpuidx(p, gpuidx);
+       if (!pdd)
+               return NULL;
  
        return SVM_ADEV_PGMAP_OWNER(pdd->dev->adev);
  }
@@@ -1595,12 -1600,12 +1599,12 @@@ static int svm_range_validate_and_map(s
        }
  
        if (bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE)) {
-               if (!prange->mapped_to_gpu) {
+               bitmap_copy(ctx->bitmap, prange->bitmap_access, MAX_GPU_INSTANCE);
+               if (!prange->mapped_to_gpu ||
+                   bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE)) {
                        r = 0;
                        goto free_ctx;
                }
-               bitmap_copy(ctx->bitmap, prange->bitmap_access, MAX_GPU_INSTANCE);
        }
  
        if (prange->actual_loc && !prange->ttm_res) {
                goto free_ctx;
        }
  
 -      svm_range_reserve_bos(ctx);
 +      svm_range_reserve_bos(ctx, intr);
  
        p = container_of(prange->svms, struct kfd_process, svms);
        owner = kfd_svm_page_owner(p, find_first_bit(ctx->bitmap,
@@@ -3560,7 -3565,7 +3564,7 @@@ out_unlock_range
                        break;
        }
  
-       svm_range_debug_dump(svms);
+       dynamic_svm_range_dump(svms);
  
        mutex_unlock(&svms->lock);
        mmap_read_unlock(mm);
index 39cdede460b51c5e0f704a804a2d7d89f2d23f77,aa02697e5ea363b4d0b641b82fb5b3e4a7ffd4ea..fa531493b11134caabb8967ab1581427f3873ef2
  #define KMS_DRIVER_MAJOR      2
  #define KMS_DRIVER_MINOR      50
  #define KMS_DRIVER_PATCHLEVEL 0
- int radeon_suspend_kms(struct drm_device *dev, bool suspend,
-                      bool fbcon, bool freeze);
- int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
- extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc,
-                                     unsigned int flags, int *vpos, int *hpos,
-                                     ktime_t *stime, ktime_t *etime,
-                                     const struct drm_display_mode *mode);
- extern bool radeon_is_px(struct drm_device *dev);
- int radeon_mode_dumb_mmap(struct drm_file *filp,
-                         struct drm_device *dev,
-                         uint32_t handle, uint64_t *offset_p);
- int radeon_mode_dumb_create(struct drm_file *file_priv,
-                           struct drm_device *dev,
-                           struct drm_mode_create_dumb *args);
- /* atpx handler */
- #if defined(CONFIG_VGA_SWITCHEROO)
- void radeon_register_atpx_handler(void);
- void radeon_unregister_atpx_handler(void);
- bool radeon_has_atpx_dgpu_power_cntl(void);
- bool radeon_is_atpx_hybrid(void);
- #else
- static inline void radeon_register_atpx_handler(void) {}
- static inline void radeon_unregister_atpx_handler(void) {}
- static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; }
- static inline bool radeon_is_atpx_hybrid(void) { return false; }
- #endif
  
  int radeon_no_wb;
  int radeon_modeset = -1;
  int radeon_dynclks = -1;
- int radeon_r4xx_atom = 0;
+ int radeon_r4xx_atom;
  int radeon_agpmode = -1;
- int radeon_vram_limit = 0;
+ int radeon_vram_limit;
  int radeon_gart_size = -1; /* auto */
- int radeon_benchmarking = 0;
- int radeon_testing = 0;
- int radeon_connector_table = 0;
+ int radeon_benchmarking;
+ int radeon_testing;
+ int radeon_connector_table;
  int radeon_tv = 1;
  int radeon_audio = -1;
- int radeon_disp_priority = 0;
- int radeon_hw_i2c = 0;
+ int radeon_disp_priority;
+ int radeon_hw_i2c;
  int radeon_pcie_gen2 = -1;
  int radeon_msi = -1;
  int radeon_lockup_timeout = 10000;
- int radeon_fastfb = 0;
+ int radeon_fastfb;
  int radeon_dpm = -1;
  int radeon_aspm = -1;
  int radeon_runtime_pm = -1;
- int radeon_hard_reset = 0;
+ int radeon_hard_reset;
  int radeon_vm_size = 8;
  int radeon_vm_block_size = -1;
- int radeon_deep_color = 0;
+ int radeon_deep_color;
  int radeon_use_pflipirq = 2;
  int radeon_bapm = -1;
  int radeon_backlight = -1;
@@@ -384,6 -357,7 +357,7 @@@ radeon_pci_shutdown(struct pci_dev *pde
  static int radeon_pmops_suspend(struct device *dev)
  {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
        return radeon_suspend_kms(drm_dev, true, true, false);
  }
  
@@@ -404,12 -378,14 +378,14 @@@ static int radeon_pmops_resume(struct d
  static int radeon_pmops_freeze(struct device *dev)
  {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
        return radeon_suspend_kms(drm_dev, false, true, true);
  }
  
  static int radeon_pmops_thaw(struct device *dev)
  {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
        return radeon_resume_kms(drm_dev, false, true);
  }
  
@@@ -494,6 -470,7 +470,7 @@@ long radeon_drm_ioctl(struct file *filp
        struct drm_file *file_priv = filp->private_data;
        struct drm_device *dev;
        long ret;
        dev = file_priv->minor->dev;
        ret = pm_runtime_get_sync(dev->dev);
        if (ret < 0) {
@@@ -604,7 -581,10 +581,7 @@@ static const struct drm_driver kms_driv
        .dumb_map_offset = radeon_mode_dumb_mmap,
        .fops = &radeon_driver_kms_fops,
  
 -      .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 -      .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
        .gem_prime_import_sg_table = radeon_gem_prime_import_sg_table,
 -      .gem_prime_mmap = drm_gem_prime_mmap,
  
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,