// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
 * Copyright 2020-2021 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <linux/types.h>
#include <linux/sched/task.h>
#include <linux/dynamic_debug.h>
#include <drm/ttm/ttm_tt.h>
#include <drm/drm_exec.h>

#include "amdgpu_sync.h"
#include "amdgpu_object.h"
#include "amdgpu_vm.h"
#include "amdgpu_hmm.h"
#include "amdgpu.h"
#include "amdgpu_xgmi.h"
#include "kfd_priv.h"
#include "kfd_svm.h"
#include "kfd_migrate.h"
#include "kfd_smi_events.h"

#ifdef dev_fmt
#undef dev_fmt
#endif
#define dev_fmt(fmt) "kfd_svm: %s: " fmt, __func__

#define AMDGPU_SVM_RANGE_RESTORE_DELAY_MS 1

/* Long enough to ensure no retry fault comes after svm range is restored and
 * page table is updated.
 */
#define AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING	(2UL * NSEC_PER_MSEC)
#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
#define dynamic_svm_range_dump(svms) \
	_dynamic_func_call_no_desc("svm_range_dump", svm_range_debug_dump, svms)
#else
#define dynamic_svm_range_dump(svms) \
	do { if (0) svm_range_debug_dump(svms); } while (0)
#endif

/* 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
 * power of 2MB.
 */
static uint64_t max_svm_range_pages;

struct criu_svm_metadata {
	struct list_head list;
	struct kfd_criu_svm_range_priv_data data;
};

static void svm_range_evict_svm_bo_worker(struct work_struct *work);
static bool
svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
				    const struct mmu_notifier_range *range,
				    unsigned long cur_seq);
static int
svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last,
		   uint64_t *bo_s, uint64_t *bo_l);
static const struct mmu_interval_notifier_ops svm_range_mn_ops = {
	.invalidate = svm_range_cpu_invalidate_pagetables,
};

/**
 * svm_range_unlink - unlink svm_range from lists and interval tree
 * @prange: svm range structure to be removed
 *
 * Remove the svm_range from the svms and svm_bo lists and the svms
 * interval tree.
 *
 * Context: The caller must hold svms->lock
 */
static void svm_range_unlink(struct svm_range *prange)
{
	pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
		 prange, prange->start, prange->last);

	if (prange->svm_bo) {
		spin_lock(&prange->svm_bo->list_lock);
		list_del(&prange->svm_bo_list);
		spin_unlock(&prange->svm_bo->list_lock);
	}

	list_del(&prange->list);
	if (prange->it_node.start != 0 && prange->it_node.last != 0)
		interval_tree_remove(&prange->it_node, &prange->svms->objects);
}

static void
svm_range_add_notifier_locked(struct mm_struct *mm, struct svm_range *prange)
{
	pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
		 prange, prange->start, prange->last);

	mmu_interval_notifier_insert_locked(&prange->notifier, mm,
				     prange->start << PAGE_SHIFT,
				     prange->npages << PAGE_SHIFT,
				     &svm_range_mn_ops);
}

/**
 * svm_range_add_to_svms - add svm range to svms
 * @prange: svm range structure to be added
 *
 * Add the svm range to svms interval tree and link list
 *
 * Context: The caller must hold svms->lock
 */
static void svm_range_add_to_svms(struct svm_range *prange)
{
	pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms,
		 prange, prange->start, prange->last);

	list_move_tail(&prange->list, &prange->svms->list);
	prange->it_node.start = prange->start;
	prange->it_node.last = prange->last;
	interval_tree_insert(&prange->it_node, &prange->svms->objects);
}

static void svm_range_remove_notifier(struct svm_range *prange)
{
	pr_debug("remove notifier svms 0x%p prange 0x%p [0x%lx 0x%lx]\n",
		 prange->svms, prange,
		 prange->notifier.interval_tree.start >> PAGE_SHIFT,
		 prange->notifier.interval_tree.last >> PAGE_SHIFT);

	if (prange->notifier.interval_tree.start != 0 &&
	    prange->notifier.interval_tree.last != 0)
		mmu_interval_notifier_remove(&prange->notifier);
}

static bool
svm_is_valid_dma_mapping_addr(struct device *dev, dma_addr_t dma_addr)
{
	return dma_addr && !dma_mapping_error(dev, dma_addr) &&
	       !(dma_addr & SVM_RANGE_VRAM_DOMAIN);
}

static int
svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
		      unsigned long offset, unsigned long npages,
		      unsigned long *hmm_pfns, uint32_t gpuidx)
{
	enum dma_data_direction dir = DMA_BIDIRECTIONAL;
	dma_addr_t *addr = prange->dma_addr[gpuidx];
	struct device *dev = adev->dev;
	struct page *page;
	int i, r;

	if (!addr) {
		addr = kvcalloc(prange->npages, sizeof(*addr), GFP_KERNEL);
		if (!addr)
			return -ENOMEM;
		prange->dma_addr[gpuidx] = addr;
	}

	addr += offset;
	for (i = 0; i < npages; i++) {
		if (svm_is_valid_dma_mapping_addr(dev, addr[i]))
			dma_unmap_page(dev, addr[i], PAGE_SIZE, dir);

		page = hmm_pfn_to_page(hmm_pfns[i]);
		if (is_zone_device_page(page)) {
			struct amdgpu_device *bo_adev = prange->svm_bo->node->adev;

			addr[i] = (hmm_pfns[i] << PAGE_SHIFT) +
				   bo_adev->vm_manager.vram_base_offset -
				   bo_adev->kfd.pgmap.range.start;
			addr[i] |= SVM_RANGE_VRAM_DOMAIN;
			pr_debug_ratelimited("vram address: 0x%llx\n", addr[i]);
			continue;
		}
		addr[i] = dma_map_page(dev, page, 0, PAGE_SIZE, dir);
		r = dma_mapping_error(dev, addr[i]);
		if (r) {
			dev_err(dev, "failed %d dma_map_page\n", r);
			return r;
		}
		pr_debug_ratelimited("dma mapping 0x%llx for page addr 0x%lx\n",
				     addr[i] >> PAGE_SHIFT, page_to_pfn(page));
	}

	return 0;
}

static int
svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap,
		  unsigned long offset, unsigned long npages,
		  unsigned long *hmm_pfns)
{
	struct kfd_process *p;
	uint32_t gpuidx;
	int r;

	p = container_of(prange->svms, struct kfd_process, svms);

	for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
		struct kfd_process_device *pdd;

		pr_debug("mapping to gpu idx 0x%x\n", gpuidx);
		pdd = kfd_process_device_from_gpuidx(p, gpuidx);
		if (!pdd) {
			pr_debug("failed to find device idx %d\n", gpuidx);
			return -EINVAL;
		}

		r = svm_range_dma_map_dev(pdd->dev->adev, prange, offset, npages,
					  hmm_pfns, gpuidx);
		if (r)
			break;
	}

	return r;
}

void svm_range_dma_unmap_dev(struct device *dev, dma_addr_t *dma_addr,
			 unsigned long offset, unsigned long npages)
{
	enum dma_data_direction dir = DMA_BIDIRECTIONAL;
	int i;

	if (!dma_addr)
		return;

	for (i = offset; i < offset + npages; i++) {
		if (!svm_is_valid_dma_mapping_addr(dev, dma_addr[i]))
			continue;
		pr_debug_ratelimited("unmap 0x%llx\n", dma_addr[i] >> PAGE_SHIFT);
		dma_unmap_page(dev, dma_addr[i], PAGE_SIZE, dir);
		dma_addr[i] = 0;
	}
}

void svm_range_dma_unmap(struct svm_range *prange)
{
	struct kfd_process_device *pdd;
	dma_addr_t *dma_addr;
	struct device *dev;
	struct kfd_process *p;
	uint32_t gpuidx;

	p = container_of(prange->svms, struct kfd_process, svms);

	for (gpuidx = 0; gpuidx < MAX_GPU_INSTANCE; gpuidx++) {
		dma_addr = prange->dma_addr[gpuidx];
		if (!dma_addr)
			continue;

		pdd = kfd_process_device_from_gpuidx(p, gpuidx);
		if (!pdd) {
			pr_debug("failed to find device idx %d\n", gpuidx);
			continue;
		}
		dev = &pdd->dev->adev->pdev->dev;

		svm_range_dma_unmap_dev(dev, dma_addr, 0, prange->npages);
	}
}

static void svm_range_free(struct svm_range *prange, bool do_unmap)
{
	uint64_t size = (prange->last - prange->start + 1) << PAGE_SHIFT;
	struct kfd_process *p = container_of(prange->svms, struct kfd_process, svms);
	uint32_t gpuidx;

	pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms, prange,
		 prange->start, prange->last);

	svm_range_vram_node_free(prange);
	if (do_unmap)
		svm_range_dma_unmap(prange);

	if (do_unmap && !p->xnack_enabled) {
		pr_debug("unreserve prange 0x%p size: 0x%llx\n", prange, size);
		amdgpu_amdkfd_unreserve_mem_limit(NULL, size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
	}

	/* free dma_addr array for each gpu */
	for (gpuidx = 0; gpuidx < MAX_GPU_INSTANCE; gpuidx++) {
		if (prange->dma_addr[gpuidx]) {
			kvfree(prange->dma_addr[gpuidx]);
			prange->dma_addr[gpuidx] = NULL;
		}
	}

	mutex_destroy(&prange->lock);
	mutex_destroy(&prange->migrate_mutex);
	kfree(prange);
}

static void
svm_range_set_default_attributes(int32_t *location, int32_t *prefetch_loc,
				 uint8_t *granularity, uint32_t *flags)
{
	*location = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
	*prefetch_loc = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
	*granularity = 9;
	*flags =
		KFD_IOCTL_SVM_FLAG_HOST_ACCESS | KFD_IOCTL_SVM_FLAG_COHERENT;
}

static struct
svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start,
			 uint64_t last, bool update_mem_usage)
{
	uint64_t size = last - start + 1;
	struct svm_range *prange;
	struct kfd_process *p;

	prange = kzalloc(sizeof(*prange), GFP_KERNEL);
	if (!prange)
		return NULL;

	p = container_of(svms, struct kfd_process, svms);
	if (!p->xnack_enabled && update_mem_usage &&
	    amdgpu_amdkfd_reserve_mem_limit(NULL, size << PAGE_SHIFT,
				    KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0)) {
		pr_info("SVM mapping failed, exceeds resident system memory limit\n");
		kfree(prange);
		return NULL;
	}
	prange->npages = size;
	prange->svms = svms;
	prange->start = start;
	prange->last = last;
	INIT_LIST_HEAD(&prange->list);
	INIT_LIST_HEAD(&prange->update_list);
	INIT_LIST_HEAD(&prange->svm_bo_list);
	INIT_LIST_HEAD(&prange->deferred_list);
	INIT_LIST_HEAD(&prange->child_list);
	atomic_set(&prange->invalid, 0);
	prange->validate_timestamp = 0;
	prange->vram_pages = 0;
	mutex_init(&prange->migrate_mutex);
	mutex_init(&prange->lock);

	if (p->xnack_enabled)
		bitmap_copy(prange->bitmap_access, svms->bitmap_supported,
			    MAX_GPU_INSTANCE);

	svm_range_set_default_attributes(&prange->preferred_loc,
					 &prange->prefetch_loc,
					 &prange->granularity, &prange->flags);

	pr_debug("svms 0x%p [0x%llx 0x%llx]\n", svms, start, last);

	return prange;
}

static bool svm_bo_ref_unless_zero(struct svm_range_bo *svm_bo)
{
	if (!svm_bo || !kref_get_unless_zero(&svm_bo->kref))
		return false;

	return true;
}

static void svm_range_bo_release(struct kref *kref)
{
	struct svm_range_bo *svm_bo;

	svm_bo = container_of(kref, struct svm_range_bo, kref);
	pr_debug("svm_bo 0x%p\n", svm_bo);

	spin_lock(&svm_bo->list_lock);
	while (!list_empty(&svm_bo->range_list)) {
		struct svm_range *prange =
				list_first_entry(&svm_bo->range_list,
						struct svm_range, svm_bo_list);
		/* list_del_init tells a concurrent svm_range_vram_node_new when
		 * it's safe to reuse the svm_bo pointer and svm_bo_list head.
		 */
		list_del_init(&prange->svm_bo_list);
		spin_unlock(&svm_bo->list_lock);

		pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms,
			 prange->start, prange->last);
		mutex_lock(&prange->lock);
		prange->svm_bo = NULL;
		/* prange should not hold vram page now */
		WARN_ONCE(prange->actual_loc, "prange should not hold vram page");
		mutex_unlock(&prange->lock);

		spin_lock(&svm_bo->list_lock);
	}
	spin_unlock(&svm_bo->list_lock);
	if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
		/* We're not in the eviction worker. Signal the fence. */
		dma_fence_signal(&svm_bo->eviction_fence->base);
	dma_fence_put(&svm_bo->eviction_fence->base);
	amdgpu_bo_unref(&svm_bo->bo);
	kfree(svm_bo);
}

static void svm_range_bo_wq_release(struct work_struct *work)
{
	struct svm_range_bo *svm_bo;

	svm_bo = container_of(work, struct svm_range_bo, release_work);
	svm_range_bo_release(&svm_bo->kref);
}

static void svm_range_bo_release_async(struct kref *kref)
{
	struct svm_range_bo *svm_bo;

	svm_bo = container_of(kref, struct svm_range_bo, kref);
	pr_debug("svm_bo 0x%p\n", svm_bo);
	INIT_WORK(&svm_bo->release_work, svm_range_bo_wq_release);
	schedule_work(&svm_bo->release_work);
}

void svm_range_bo_unref_async(struct svm_range_bo *svm_bo)
{
	kref_put(&svm_bo->kref, svm_range_bo_release_async);
}

static void svm_range_bo_unref(struct svm_range_bo *svm_bo)
{
	if (svm_bo)
		kref_put(&svm_bo->kref, svm_range_bo_release);
}

static bool
svm_range_validate_svm_bo(struct kfd_node *node, struct svm_range *prange)
{
	mutex_lock(&prange->lock);
	if (!prange->svm_bo) {
		mutex_unlock(&prange->lock);
		return false;
	}
	if (prange->ttm_res) {
		/* We still have a reference, all is well */
		mutex_unlock(&prange->lock);
		return true;
	}
	if (svm_bo_ref_unless_zero(prange->svm_bo)) {
		/*
		 * Migrate from GPU to GPU, remove range from source svm_bo->node
		 * range list, and return false to allocate svm_bo from destination
		 * node.
		 */
		if (prange->svm_bo->node != node) {
			mutex_unlock(&prange->lock);

			spin_lock(&prange->svm_bo->list_lock);
			list_del_init(&prange->svm_bo_list);
			spin_unlock(&prange->svm_bo->list_lock);

			svm_range_bo_unref(prange->svm_bo);
			return false;
		}
		if (READ_ONCE(prange->svm_bo->evicting)) {
			struct dma_fence *f;
			struct svm_range_bo *svm_bo;
			/* The BO is getting evicted,
			 * we need to get a new one
			 */
			mutex_unlock(&prange->lock);
			svm_bo = prange->svm_bo;
			f = dma_fence_get(&svm_bo->eviction_fence->base);
			svm_range_bo_unref(prange->svm_bo);
			/* wait for the fence to avoid long spin-loop
			 * at list_empty_careful
			 */
			dma_fence_wait(f, false);
			dma_fence_put(f);
		} else {
			/* The BO was still around and we got
			 * a new reference to it
			 */
			mutex_unlock(&prange->lock);
			pr_debug("reuse old bo svms 0x%p [0x%lx 0x%lx]\n",
				 prange->svms, prange->start, prange->last);

			prange->ttm_res = prange->svm_bo->bo->tbo.resource;
			return true;
		}

	} else {
		mutex_unlock(&prange->lock);
	}

	/* We need a new svm_bo. Spin-loop to wait for concurrent
	 * svm_range_bo_release to finish removing this range from
	 * its range list and set prange->svm_bo to null. After this,
	 * it is safe to reuse the svm_bo pointer and svm_bo_list head.
	 */
	while (!list_empty_careful(&prange->svm_bo_list) || prange->svm_bo)
		cond_resched();

	return false;
}

static struct svm_range_bo *svm_range_bo_new(void)
{
	struct svm_range_bo *svm_bo;

	svm_bo = kzalloc(sizeof(*svm_bo), GFP_KERNEL);
	if (!svm_bo)
		return NULL;

	kref_init(&svm_bo->kref);
	INIT_LIST_HEAD(&svm_bo->range_list);
	spin_lock_init(&svm_bo->list_lock);

	return svm_bo;
}

int
svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
			bool clear)
{
	struct amdgpu_bo_param bp;
	struct svm_range_bo *svm_bo;
	struct amdgpu_bo_user *ubo;
	struct amdgpu_bo *bo;
	struct kfd_process *p;
	struct mm_struct *mm;
	int r;

	p = container_of(prange->svms, struct kfd_process, svms);
	pr_debug("pasid: %x svms 0x%p [0x%lx 0x%lx]\n", p->pasid, prange->svms,
		 prange->start, prange->last);

	if (svm_range_validate_svm_bo(node, prange))
		return 0;

	svm_bo = svm_range_bo_new();
	if (!svm_bo) {
		pr_debug("failed to alloc svm bo\n");
		return -ENOMEM;
	}
	mm = get_task_mm(p->lead_thread);
	if (!mm) {
		pr_debug("failed to get mm\n");
		kfree(svm_bo);
		return -ESRCH;
	}
	svm_bo->node = node;
	svm_bo->eviction_fence =
		amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1),
					   mm,
					   svm_bo);
	mmput(mm);
	INIT_WORK(&svm_bo->eviction_work, svm_range_evict_svm_bo_worker);
	svm_bo->evicting = 0;
	memset(&bp, 0, sizeof(bp));
	bp.size = prange->npages * PAGE_SIZE;
	bp.byte_align = PAGE_SIZE;
	bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
	bp.flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
	bp.flags |= clear ? AMDGPU_GEM_CREATE_VRAM_CLEARED : 0;
	bp.flags |= AMDGPU_GEM_CREATE_DISCARDABLE;
	bp.type = ttm_bo_type_device;
	bp.resv = NULL;
	if (node->xcp)
		bp.xcp_id_plus1 = node->xcp->id + 1;

	r = amdgpu_bo_create_user(node->adev, &bp, &ubo);
	if (r) {
		pr_debug("failed %d to create bo\n", r);
		goto create_bo_failed;
	}
	bo = &ubo->bo;

	pr_debug("alloc bo at offset 0x%lx size 0x%lx on partition %d\n",
		 bo->tbo.resource->start << PAGE_SHIFT, bp.size,
		 bp.xcp_id_plus1 - 1);

	r = amdgpu_bo_reserve(bo, true);
	if (r) {
		pr_debug("failed %d to reserve bo\n", r);
		goto reserve_bo_failed;
	}

	if (clear) {
		r = amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false);
		if (r) {
			pr_debug("failed %d to sync bo\n", r);
			amdgpu_bo_unreserve(bo);
			goto reserve_bo_failed;
		}
	}

	r = dma_resv_reserve_fences(bo->tbo.base.resv, 1);
	if (r) {
		pr_debug("failed %d to reserve bo\n", r);
		amdgpu_bo_unreserve(bo);
		goto reserve_bo_failed;
	}
	amdgpu_bo_fence(bo, &svm_bo->eviction_fence->base, true);

	amdgpu_bo_unreserve(bo);

	svm_bo->bo = bo;
	prange->svm_bo = svm_bo;
	prange->ttm_res = bo->tbo.resource;
	prange->offset = 0;

	spin_lock(&svm_bo->list_lock);
	list_add(&prange->svm_bo_list, &svm_bo->range_list);
	spin_unlock(&svm_bo->list_lock);

	return 0;

reserve_bo_failed:
	amdgpu_bo_unref(&bo);
create_bo_failed:
	dma_fence_put(&svm_bo->eviction_fence->base);
	kfree(svm_bo);
	prange->ttm_res = NULL;

	return r;
}

void svm_range_vram_node_free(struct svm_range *prange)
{
	/* serialize prange->svm_bo unref */
	mutex_lock(&prange->lock);
	/* prange->svm_bo has not been unref */
	if (prange->ttm_res) {
		prange->ttm_res = NULL;
		mutex_unlock(&prange->lock);
		svm_range_bo_unref(prange->svm_bo);
	} else
		mutex_unlock(&prange->lock);
}

struct kfd_node *
svm_range_get_node_by_id(struct svm_range *prange, uint32_t gpu_id)
{
	struct kfd_process *p;
	struct kfd_process_device *pdd;

	p = container_of(prange->svms, struct kfd_process, svms);
	pdd = kfd_process_device_data_by_id(p, gpu_id);
	if (!pdd) {
		pr_debug("failed to get kfd process device by id 0x%x\n", gpu_id);
		return NULL;
	}

	return pdd->dev;
}

struct kfd_process_device *
svm_range_get_pdd_by_node(struct svm_range *prange, struct kfd_node *node)
{
	struct kfd_process *p;

	p = container_of(prange->svms, struct kfd_process, svms);

	return kfd_get_process_device_data(node, p);
}

static int svm_range_bo_validate(void *param, struct amdgpu_bo *bo)
{
	struct ttm_operation_ctx ctx = { false, false };

	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);

	return ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
}

static int
svm_range_check_attr(struct kfd_process *p,
		     uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
{
	uint32_t i;

	for (i = 0; i < nattr; i++) {
		uint32_t val = attrs[i].value;
		int gpuidx = MAX_GPU_INSTANCE;

		switch (attrs[i].type) {
		case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
			if (val != KFD_IOCTL_SVM_LOCATION_SYSMEM &&
			    val != KFD_IOCTL_SVM_LOCATION_UNDEFINED)
				gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
			break;
		case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
			if (val != KFD_IOCTL_SVM_LOCATION_SYSMEM)
				gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
			break;
		case KFD_IOCTL_SVM_ATTR_ACCESS:
		case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
		case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
			gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
			break;
		case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
			break;
		case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
			break;
		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
			break;
		default:
			pr_debug("unknown attr type 0x%x\n", attrs[i].type);
			return -EINVAL;
		}

		if (gpuidx < 0) {
			pr_debug("no GPU 0x%x found\n", val);
			return -EINVAL;
		} else if (gpuidx < MAX_GPU_INSTANCE &&
			   !test_bit(gpuidx, p->svms.bitmap_supported)) {
			pr_debug("GPU 0x%x not supported\n", val);
			return -EINVAL;
		}
	}

	return 0;
}

static void
svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange,
		      uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs,
		      bool *update_mapping)
{
	uint32_t i;
	int gpuidx;

	for (i = 0; i < nattr; i++) {
		switch (attrs[i].type) {
		case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
			prange->preferred_loc = attrs[i].value;
			break;
		case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
			prange->prefetch_loc = attrs[i].value;
			break;
		case KFD_IOCTL_SVM_ATTR_ACCESS:
		case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
		case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
			if (!p->xnack_enabled)
				*update_mapping = true;

			gpuidx = kfd_process_gpuidx_from_gpuid(p,
							       attrs[i].value);
			if (attrs[i].type == KFD_IOCTL_SVM_ATTR_NO_ACCESS) {
				bitmap_clear(prange->bitmap_access, gpuidx, 1);
				bitmap_clear(prange->bitmap_aip, gpuidx, 1);
			} else if (attrs[i].type == KFD_IOCTL_SVM_ATTR_ACCESS) {
				bitmap_set(prange->bitmap_access, gpuidx, 1);
				bitmap_clear(prange->bitmap_aip, gpuidx, 1);
			} else {
				bitmap_clear(prange->bitmap_access, gpuidx, 1);
				bitmap_set(prange->bitmap_aip, gpuidx, 1);
			}
			break;
		case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
			*update_mapping = true;
			prange->flags |= attrs[i].value;
			break;
		case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
			*update_mapping = true;
			prange->flags &= ~attrs[i].value;
			break;
		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
			prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F);
			break;
		default:
			WARN_ONCE(1, "svm_range_check_attrs wasn't called?");
		}
	}
}

static bool
svm_range_is_same_attrs(struct kfd_process *p, struct svm_range *prange,
			uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
{
	uint32_t i;
	int gpuidx;

	for (i = 0; i < nattr; i++) {
		switch (attrs[i].type) {
		case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
			if (prange->preferred_loc != attrs[i].value)
				return false;
			break;
		case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
			/* Prefetch should always trigger a migration even
			 * if the value of the attribute didn't change.
			 */
			return false;
		case KFD_IOCTL_SVM_ATTR_ACCESS:
		case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
		case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
			gpuidx = kfd_process_gpuidx_from_gpuid(p,
							       attrs[i].value);
			if (attrs[i].type == KFD_IOCTL_SVM_ATTR_NO_ACCESS) {
				if (test_bit(gpuidx, prange->bitmap_access) ||
				    test_bit(gpuidx, prange->bitmap_aip))
					return false;
			} else if (attrs[i].type == KFD_IOCTL_SVM_ATTR_ACCESS) {
				if (!test_bit(gpuidx, prange->bitmap_access))
					return false;
			} else {
				if (!test_bit(gpuidx, prange->bitmap_aip))
					return false;
			}
			break;
		case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
			if ((prange->flags & attrs[i].value) != attrs[i].value)
				return false;
			break;
		case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
			if ((prange->flags & attrs[i].value) != 0)
				return false;
			break;
		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
			if (prange->granularity != attrs[i].value)
				return false;
			break;
		default:
			WARN_ONCE(1, "svm_range_check_attrs wasn't called?");
		}
	}

	return true;
}

/**
 * svm_range_debug_dump - print all range information from svms
 * @svms: svm range list header
 *
 * debug output svm range start, end, prefetch location from svms
 * interval tree and link list
 *
 * Context: The caller must hold svms->lock
 */
static void svm_range_debug_dump(struct svm_range_list *svms)
{
	struct interval_tree_node *node;
	struct svm_range *prange;

	pr_debug("dump svms 0x%p list\n", svms);
	pr_debug("range\tstart\tpage\tend\t\tlocation\n");

	list_for_each_entry(prange, &svms->list, list) {
		pr_debug("0x%p 0x%lx\t0x%llx\t0x%llx\t0x%x\n",
			 prange, prange->start, prange->npages,
			 prange->start + prange->npages - 1,
			 prange->actual_loc);
	}

	pr_debug("dump svms 0x%p interval tree\n", svms);
	pr_debug("range\tstart\tpage\tend\t\tlocation\n");
	node = interval_tree_iter_first(&svms->objects, 0, ~0ULL);
	while (node) {
		prange = container_of(node, struct svm_range, it_node);
		pr_debug("0x%p 0x%lx\t0x%llx\t0x%llx\t0x%x\n",
			 prange, prange->start, prange->npages,
			 prange->start + prange->npages - 1,
			 prange->actual_loc);
		node = interval_tree_iter_next(node, 0, ~0ULL);
	}
}

static void *
svm_range_copy_array(void *psrc, size_t size, uint64_t num_elements,
		     uint64_t offset, uint64_t *vram_pages)
{
	unsigned char *src = (unsigned char *)psrc + offset;
	unsigned char *dst;
	uint64_t i;

	dst = kvmalloc_array(num_elements, size, GFP_KERNEL);
	if (!dst)
		return NULL;

	if (!vram_pages) {
		memcpy(dst, src, num_elements * size);
		return (void *)dst;
	}

	*vram_pages = 0;
	for (i = 0; i < num_elements; i++) {
		dma_addr_t *temp;
		temp = (dma_addr_t *)dst + i;
		*temp = *((dma_addr_t *)src + i);
		if (*temp&SVM_RANGE_VRAM_DOMAIN)
			(*vram_pages)++;
	}

	return (void *)dst;
}

static int
svm_range_copy_dma_addrs(struct svm_range *dst, struct svm_range *src)
{
	int i;

	for (i = 0; i < MAX_GPU_INSTANCE; i++) {
		if (!src->dma_addr[i])
			continue;
		dst->dma_addr[i] = svm_range_copy_array(src->dma_addr[i],
					sizeof(*src->dma_addr[i]), src->npages, 0, NULL);
		if (!dst->dma_addr[i])
			return -ENOMEM;
	}

	return 0;
}

static int
svm_range_split_array(void *ppnew, void *ppold, size_t size,
		      uint64_t old_start, uint64_t old_n,
		      uint64_t new_start, uint64_t new_n, uint64_t *new_vram_pages)
{
	unsigned char *new, *old, *pold;
	uint64_t d;

	if (!ppold)
		return 0;
	pold = *(unsigned char **)ppold;
	if (!pold)
		return 0;

	d = (new_start - old_start) * size;
	/* get dma addr array for new range and calculte its vram page number */
	new = svm_range_copy_array(pold, size, new_n, d, new_vram_pages);
	if (!new)
		return -ENOMEM;
	d = (new_start == old_start) ? new_n * size : 0;
	old = svm_range_copy_array(pold, size, old_n, d, NULL);
	if (!old) {
		kvfree(new);
		return -ENOMEM;
	}
	kvfree(pold);
	*(void **)ppold = old;
	*(void **)ppnew = new;

	return 0;
}

static int
svm_range_split_pages(struct svm_range *new, struct svm_range *old,
		      uint64_t start, uint64_t last)
{
	uint64_t npages = last - start + 1;
	int i, r;

	for (i = 0; i < MAX_GPU_INSTANCE; i++) {
		r = svm_range_split_array(&new->dma_addr[i], &old->dma_addr[i],
					  sizeof(*old->dma_addr[i]), old->start,
					  npages, new->start, new->npages,
					  old->actual_loc ? &new->vram_pages : NULL);
		if (r)
			return r;
	}
	if (old->actual_loc)
		old->vram_pages -= new->vram_pages;

	return 0;
}

static int
svm_range_split_nodes(struct svm_range *new, struct svm_range *old,
		      uint64_t start, uint64_t last)
{
	uint64_t npages = last - start + 1;

	pr_debug("svms 0x%p new prange 0x%p start 0x%lx [0x%llx 0x%llx]\n",
		 new->svms, new, new->start, start, last);

	if (new->start == old->start) {
		new->offset = old->offset;
		old->offset += new->npages;
	} else {
		new->offset = old->offset + npages;
	}

	new->svm_bo = svm_range_bo_ref(old->svm_bo);
	new->ttm_res = old->ttm_res;

	spin_lock(&new->svm_bo->list_lock);
	list_add(&new->svm_bo_list, &new->svm_bo->range_list);
	spin_unlock(&new->svm_bo->list_lock);

	return 0;
}

/**
 * svm_range_split_adjust - split range and adjust
 *
 * @new: new range
 * @old: the old range
 * @start: the old range adjust to start address in pages
 * @last: the old range adjust to last address in pages
 *
 * Copy system memory dma_addr or vram ttm_res in old range to new
 * range from new_start up to size new->npages, the remaining old range is from
 * start to last
 *
 * Return:
 * 0 - OK, -ENOMEM - out of memory
 */
static int
svm_range_split_adjust(struct svm_range *new, struct svm_range *old,
		      uint64_t start, uint64_t last)
{
	int r;

	pr_debug("svms 0x%p new 0x%lx old [0x%lx 0x%lx] => [0x%llx 0x%llx]\n",
		 new->svms, new->start, old->start, old->last, start, last);

	if (new->start < old->start ||
	    new->last > old->last) {
		WARN_ONCE(1, "invalid new range start or last\n");
		return -EINVAL;
	}

	r = svm_range_split_pages(new, old, start, last);
	if (r)
		return r;

	if (old->actual_loc && old->ttm_res) {
		r = svm_range_split_nodes(new, old, start, last);
		if (r)
			return r;
	}

	old->npages = last - start + 1;
	old->start = start;
	old->last = last;
	new->flags = old->flags;
	new->preferred_loc = old->preferred_loc;
	new->prefetch_loc = old->prefetch_loc;
	new->actual_loc = old->actual_loc;
	new->granularity = old->granularity;
	new->mapped_to_gpu = old->mapped_to_gpu;
	bitmap_copy(new->bitmap_access, old->bitmap_access, MAX_GPU_INSTANCE);
	bitmap_copy(new->bitmap_aip, old->bitmap_aip, MAX_GPU_INSTANCE);

	return 0;
}

/**
 * svm_range_split - split a range in 2 ranges
 *
 * @prange: the svm range to split
 * @start: the remaining range start address in pages
 * @last: the remaining range last address in pages
 * @new: the result new range generated
 *
 * Two cases only:
 * case 1: if start == prange->start
 *         prange ==> prange[start, last]
 *         new range [last + 1, prange->last]
 *
 * case 2: if last == prange->last
 *         prange ==> prange[start, last]
 *         new range [prange->start, start - 1]
 *
 * Return:
 * 0 - OK, -ENOMEM - out of memory, -EINVAL - invalid start, last
 */
static int
svm_range_split(struct svm_range *prange, uint64_t start, uint64_t last,
		struct svm_range **new)
{
	uint64_t old_start = prange->start;
	uint64_t old_last = prange->last;
	struct svm_range_list *svms;
	int r = 0;

	pr_debug("svms 0x%p [0x%llx 0x%llx] to [0x%llx 0x%llx]\n", prange->svms,
		 old_start, old_last, start, last);

	if (old_start != start && old_last != last)
		return -EINVAL;
	if (start < old_start || last > old_last)
		return -EINVAL;

	svms = prange->svms;
	if (old_start == start)
		*new = svm_range_new(svms, last + 1, old_last, false);
	else
		*new = svm_range_new(svms, old_start, start - 1, false);
	if (!*new)
		return -ENOMEM;

	r = svm_range_split_adjust(*new, prange, start, last);
	if (r) {
		pr_debug("failed %d split [0x%llx 0x%llx] to [0x%llx 0x%llx]\n",
			 r, old_start, old_last, start, last);
		svm_range_free(*new, false);
		*new = NULL;
	}

	return r;
}

static int
svm_range_split_tail(struct svm_range *prange, uint64_t new_last,
		     struct list_head *insert_list, struct list_head *remap_list)
{
	struct svm_range *tail = NULL;
	int r = svm_range_split(prange, prange->start, new_last, &tail);

	if (!r) {
		list_add(&tail->list, insert_list);
		if (!IS_ALIGNED(new_last + 1, 1UL << prange->granularity))
			list_add(&tail->update_list, remap_list);
	}
	return r;
}

static int
svm_range_split_head(struct svm_range *prange, uint64_t new_start,
		     struct list_head *insert_list, struct list_head *remap_list)
{
	struct svm_range *head = NULL;
	int r = svm_range_split(prange, new_start, prange->last, &head);

	if (!r) {
		list_add(&head->list, insert_list);
		if (!IS_ALIGNED(new_start, 1UL << prange->granularity))
			list_add(&head->update_list, remap_list);
	}
	return r;
}

static void
svm_range_add_child(struct svm_range *prange, struct mm_struct *mm,
		    struct svm_range *pchild, enum svm_work_list_ops op)
{
	pr_debug("add child 0x%p [0x%lx 0x%lx] to prange 0x%p child list %d\n",
		 pchild, pchild->start, pchild->last, prange, op);

	pchild->work_item.mm = mm;
	pchild->work_item.op = op;
	list_add_tail(&pchild->child_list, &prange->child_list);
}

static bool
svm_nodes_in_same_hive(struct kfd_node *node_a, struct kfd_node *node_b)
{
	return (node_a->adev == node_b->adev ||
		amdgpu_xgmi_same_hive(node_a->adev, node_b->adev));
}

static uint64_t
svm_range_get_pte_flags(struct kfd_node *node,
			struct svm_range *prange, int domain)
{
	struct kfd_node *bo_node;
	uint32_t flags = prange->flags;
	uint32_t mapping_flags = 0;
	uint64_t pte_flags;
	bool snoop = (domain != SVM_RANGE_VRAM_DOMAIN);
	bool coherent = flags & (KFD_IOCTL_SVM_FLAG_COHERENT | KFD_IOCTL_SVM_FLAG_EXT_COHERENT);
	bool ext_coherent = flags & KFD_IOCTL_SVM_FLAG_EXT_COHERENT;
	bool uncached = false; /*flags & KFD_IOCTL_SVM_FLAG_UNCACHED;*/
	unsigned int mtype_local;

	if (domain == SVM_RANGE_VRAM_DOMAIN)
		bo_node = prange->svm_bo->node;

	switch (amdgpu_ip_version(node->adev, GC_HWIP, 0)) {
	case IP_VERSION(9, 4, 1):
		if (domain == SVM_RANGE_VRAM_DOMAIN) {
			if (bo_node == node) {
				mapping_flags |= coherent ?
					AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
			} else {
				mapping_flags |= coherent ?
					AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
				if (svm_nodes_in_same_hive(node, bo_node))
					snoop = true;
			}
		} else {
			mapping_flags |= coherent ?
				AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
		}
		break;
	case IP_VERSION(9, 4, 2):
		if (domain == SVM_RANGE_VRAM_DOMAIN) {
			if (bo_node == node) {
				mapping_flags |= coherent ?
					AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
				if (node->adev->gmc.xgmi.connected_to_cpu)
					snoop = true;
			} else {
				mapping_flags |= coherent ?
					AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
				if (svm_nodes_in_same_hive(node, bo_node))
					snoop = true;
			}
		} else {
			mapping_flags |= coherent ?
				AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
		}
		break;
	case IP_VERSION(9, 4, 3):
		if (ext_coherent)
			mtype_local = node->adev->rev_id ? AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_UC;
		else
			mtype_local = amdgpu_mtype_local == 1 ? AMDGPU_VM_MTYPE_NC :
				amdgpu_mtype_local == 2 ? AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
		snoop = true;
		if (uncached) {
			mapping_flags |= AMDGPU_VM_MTYPE_UC;
		} else if (domain == SVM_RANGE_VRAM_DOMAIN) {
			/* local HBM region close to partition */
			if (bo_node->adev == node->adev &&
			    (!bo_node->xcp || !node->xcp || bo_node->xcp->mem_id == node->xcp->mem_id))
				mapping_flags |= mtype_local;
			/* local HBM region far from partition or remote XGMI GPU
			 * with regular system scope coherence
			 */
			else if (svm_nodes_in_same_hive(bo_node, node) && !ext_coherent)
				mapping_flags |= AMDGPU_VM_MTYPE_NC;
			/* PCIe P2P or extended system scope coherence */
			else
				mapping_flags |= AMDGPU_VM_MTYPE_UC;
		/* system memory accessed by the APU */
		} else if (node->adev->flags & AMD_IS_APU) {
			/* On NUMA systems, locality is determined per-page
			 * in amdgpu_gmc_override_vm_pte_flags
			 */
			if (num_possible_nodes() <= 1)
				mapping_flags |= mtype_local;
			else
				mapping_flags |= ext_coherent ? AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
		/* system memory accessed by the dGPU */
		} else {
			mapping_flags |= AMDGPU_VM_MTYPE_UC;
		}
		break;
	default:
		mapping_flags |= coherent ?
			AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
	}

	mapping_flags |= AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE;

	if (flags & KFD_IOCTL_SVM_FLAG_GPU_RO)
		mapping_flags &= ~AMDGPU_VM_PAGE_WRITEABLE;
	if (flags & KFD_IOCTL_SVM_FLAG_GPU_EXEC)
		mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE;

	pte_flags = AMDGPU_PTE_VALID;
	pte_flags |= (domain == SVM_RANGE_VRAM_DOMAIN) ? 0 : AMDGPU_PTE_SYSTEM;
	pte_flags |= snoop ? AMDGPU_PTE_SNOOPED : 0;

	pte_flags |= amdgpu_gem_va_map_flags(node->adev, mapping_flags);
	return pte_flags;
}

static int
svm_range_unmap_from_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm,
			 uint64_t start, uint64_t last,
			 struct dma_fence **fence)
{
	uint64_t init_pte_value = 0;

	pr_debug("[0x%llx 0x%llx]\n", start, last);

	return amdgpu_vm_update_range(adev, vm, false, true, true, false, NULL, start,
				      last, init_pte_value, 0, 0, NULL, NULL,
				      fence);
}

static int
svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
			  unsigned long last, uint32_t trigger)
{
	DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE);
	struct kfd_process_device *pdd;
	struct dma_fence *fence = NULL;
	struct kfd_process *p;
	uint32_t gpuidx;
	int r = 0;

	if (!prange->mapped_to_gpu) {
		pr_debug("prange 0x%p [0x%lx 0x%lx] not mapped to GPU\n",
			 prange, prange->start, prange->last);
		return 0;
	}

	if (prange->start == start && prange->last == last) {
		pr_debug("unmap svms 0x%p prange 0x%p\n", prange->svms, prange);
		prange->mapped_to_gpu = false;
	}

	bitmap_or(bitmap, prange->bitmap_access, prange->bitmap_aip,
		  MAX_GPU_INSTANCE);
	p = container_of(prange->svms, struct kfd_process, svms);

	for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
		pr_debug("unmap from gpu idx 0x%x\n", gpuidx);
		pdd = kfd_process_device_from_gpuidx(p, gpuidx);
		if (!pdd) {
			pr_debug("failed to find device idx %d\n", gpuidx);
			return -EINVAL;
		}

		kfd_smi_event_unmap_from_gpu(pdd->dev, p->lead_thread->pid,
					     start, last, trigger);

		r = svm_range_unmap_from_gpu(pdd->dev->adev,
					     drm_priv_to_vm(pdd->drm_priv),
					     start, last, &fence);
		if (r)
			break;

		if (fence) {
			r = dma_fence_wait(fence, false);
			dma_fence_put(fence);
			fence = NULL;
			if (r)
				break;
		}
		kfd_flush_tlb(pdd, TLB_FLUSH_HEAVYWEIGHT);
	}

	return r;
}

static int
svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange,
		     unsigned long offset, unsigned long npages, bool readonly,
		     dma_addr_t *dma_addr, struct amdgpu_device *bo_adev,
		     struct dma_fence **fence, bool flush_tlb)
{
	struct amdgpu_device *adev = pdd->dev->adev;
	struct amdgpu_vm *vm = drm_priv_to_vm(pdd->drm_priv);
	uint64_t pte_flags;
	unsigned long last_start;
	int last_domain;
	int r = 0;
	int64_t i, j;

	last_start = prange->start + offset;

	pr_debug("svms 0x%p [0x%lx 0x%lx] readonly %d\n", prange->svms,
		 last_start, last_start + npages - 1, readonly);

	for (i = offset; i < offset + npages; i++) {
		last_domain = dma_addr[i] & SVM_RANGE_VRAM_DOMAIN;
		dma_addr[i] &= ~SVM_RANGE_VRAM_DOMAIN;

		/* Collect all pages in the same address range and memory domain
		 * that can be mapped with a single call to update mapping.
		 */
		if (i < offset + npages - 1 &&
		    last_domain == (dma_addr[i + 1] & SVM_RANGE_VRAM_DOMAIN))
			continue;

		pr_debug("Mapping range [0x%lx 0x%llx] on domain: %s\n",
			 last_start, prange->start + i, last_domain ? "GPU" : "CPU");

		pte_flags = svm_range_get_pte_flags(pdd->dev, prange, last_domain);
		if (readonly)
			pte_flags &= ~AMDGPU_PTE_WRITEABLE;

		pr_debug("svms 0x%p map [0x%lx 0x%llx] vram %d PTE 0x%llx\n",
			 prange->svms, last_start, prange->start + i,
			 (last_domain == SVM_RANGE_VRAM_DOMAIN) ? 1 : 0,
			 pte_flags);

		/* For dGPU mode, we use same vm_manager to allocate VRAM for
		 * different memory partition based on fpfn/lpfn, we should use
		 * same vm_manager.vram_base_offset regardless memory partition.
		 */
		r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb, true,
					   NULL, last_start, prange->start + i,
					   pte_flags,
					   (last_start - prange->start) << PAGE_SHIFT,
					   bo_adev ? bo_adev->vm_manager.vram_base_offset : 0,
					   NULL, dma_addr, &vm->last_update);

		for (j = last_start - prange->start; j <= i; j++)
			dma_addr[j] |= last_domain;

		if (r) {
			pr_debug("failed %d to map to gpu 0x%lx\n", r, prange->start);
			goto out;
		}
		last_start = prange->start + i + 1;
	}

	r = amdgpu_vm_update_pdes(adev, vm, false);
	if (r) {
		pr_debug("failed %d to update directories 0x%lx\n", r,
			 prange->start);
		goto out;
	}

	if (fence)
		*fence = dma_fence_get(vm->last_update);

out:
	return r;
}

static int
svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
		      unsigned long npages, bool readonly,
		      unsigned long *bitmap, bool wait, bool flush_tlb)
{
	struct kfd_process_device *pdd;
	struct amdgpu_device *bo_adev = NULL;
	struct kfd_process *p;
	struct dma_fence *fence = NULL;
	uint32_t gpuidx;
	int r = 0;

	if (prange->svm_bo && prange->ttm_res)
		bo_adev = prange->svm_bo->node->adev;

	p = container_of(prange->svms, struct kfd_process, svms);
	for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
		pr_debug("mapping to gpu idx 0x%x\n", gpuidx);
		pdd = kfd_process_device_from_gpuidx(p, gpuidx);
		if (!pdd) {
			pr_debug("failed to find device idx %d\n", gpuidx);
			return -EINVAL;
		}

		pdd = kfd_bind_process_to_device(pdd->dev, p);
		if (IS_ERR(pdd))
			return -EINVAL;

		if (bo_adev && pdd->dev->adev != bo_adev &&
		    !amdgpu_xgmi_same_hive(pdd->dev->adev, bo_adev)) {
			pr_debug("cannot map to device idx %d\n", gpuidx);
			continue;
		}

		r = svm_range_map_to_gpu(pdd, prange, offset, npages, readonly,
					 prange->dma_addr[gpuidx],
					 bo_adev, wait ? &fence : NULL,
					 flush_tlb);
		if (r)
			break;

		if (fence) {
			r = dma_fence_wait(fence, false);
			dma_fence_put(fence);
			fence = NULL;
			if (r) {
				pr_debug("failed %d to dma fence wait\n", r);
				break;
			}
		}

		kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
	}

	return r;
}

struct svm_validate_context {
	struct kfd_process *process;
	struct svm_range *prange;
	bool intr;
	DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE);
	struct drm_exec exec;
};

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;

	drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0, 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 = 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) {
		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;
		}

		r = amdgpu_vm_validate(pdd->dev->adev,
				       drm_priv_to_vm(pdd->drm_priv), NULL,
				       svm_range_bo_validate, NULL);
		if (r) {
			pr_debug("failed %d validate pt bos\n", r);
			goto unreserve_out;
		}
	}

	return 0;

unreserve_out:
	drm_exec_fini(&ctx->exec);
	return r;
}

static void svm_range_unreserve_bos(struct svm_validate_context *ctx)
{
	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);
}

/*
 * Validation+GPU mapping with concurrent invalidation (MMU notifiers)
 *
 * To prevent concurrent destruction or change of range attributes, the
 * svm_read_lock must be held. The caller must not hold the svm_write_lock
 * because that would block concurrent evictions and lead to deadlocks. To
 * serialize concurrent migrations or validations of the same range, the
 * prange->migrate_mutex must be held.
 *
 * For VRAM ranges, the SVM BO must be allocated and valid (protected by its
 * eviction fence.
 *
 * The following sequence ensures race-free validation and GPU mapping:
 *
 * 1. Reserve page table (and SVM BO if range is in VRAM)
 * 2. hmm_range_fault to get page addresses (if system memory)
 * 3. DMA-map pages (if system memory)
 * 4-a. Take notifier lock
 * 4-b. Check that pages still valid (mmu_interval_read_retry)
 * 4-c. Check that the range was not split or otherwise invalidated
 * 4-d. Update GPU page table
 * 4.e. Release notifier lock
 * 5. Release page table (and SVM BO) reservation
 */
static int svm_range_validate_and_map(struct mm_struct *mm,
				      unsigned long map_start, unsigned long map_last,
				      struct svm_range *prange, int32_t gpuidx,
				      bool intr, bool wait, bool flush_tlb)
{
	struct svm_validate_context *ctx;
	unsigned long start, end, addr;
	struct kfd_process *p;
	void *owner;
	int32_t idx;
	int r = 0;

	ctx = kzalloc(sizeof(struct svm_validate_context), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	ctx->process = container_of(prange->svms, struct kfd_process, svms);
	ctx->prange = prange;
	ctx->intr = intr;

	if (gpuidx < MAX_GPU_INSTANCE) {
		bitmap_zero(ctx->bitmap, MAX_GPU_INSTANCE);
		bitmap_set(ctx->bitmap, gpuidx, 1);
	} else if (ctx->process->xnack_enabled) {
		bitmap_copy(ctx->bitmap, prange->bitmap_aip, MAX_GPU_INSTANCE);

		/* If prefetch range to GPU, or GPU retry fault migrate range to
		 * GPU, which has ACCESS attribute to the range, create mapping
		 * on that GPU.
		 */
		if (prange->actual_loc) {
			gpuidx = kfd_process_gpuidx_from_gpuid(ctx->process,
							prange->actual_loc);
			if (gpuidx < 0) {
				WARN_ONCE(1, "failed get device by id 0x%x\n",
					 prange->actual_loc);
				r = -EINVAL;
				goto free_ctx;
			}
			if (test_bit(gpuidx, prange->bitmap_access))
				bitmap_set(ctx->bitmap, gpuidx, 1);
		}

		/*
		 * If prange is already mapped or with always mapped flag,
		 * update mapping on GPUs with ACCESS attribute
		 */
		if (bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE)) {
			if (prange->mapped_to_gpu ||
			    prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)
				bitmap_copy(ctx->bitmap, prange->bitmap_access, MAX_GPU_INSTANCE);
		}
	} else {
		bitmap_or(ctx->bitmap, prange->bitmap_access,
			  prange->bitmap_aip, MAX_GPU_INSTANCE);
	}

	if (bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE)) {
		r = 0;
		goto free_ctx;
	}

	if (prange->actual_loc && !prange->ttm_res) {
		/* This should never happen. actual_loc gets set by
		 * svm_migrate_ram_to_vram after allocating a BO.
		 */
		WARN_ONCE(1, "VRAM BO missing during validation\n");
		r = -EINVAL;
		goto free_ctx;
	}

	r = svm_range_reserve_bos(ctx, intr);
	if (r)
		goto free_ctx;

	p = container_of(prange->svms, struct kfd_process, svms);
	owner = kfd_svm_page_owner(p, find_first_bit(ctx->bitmap,
						MAX_GPU_INSTANCE));
	for_each_set_bit(idx, ctx->bitmap, MAX_GPU_INSTANCE) {
		if (kfd_svm_page_owner(p, idx) != owner) {
			owner = NULL;
			break;
		}
	}

	start = map_start << PAGE_SHIFT;
	end = (map_last + 1) << PAGE_SHIFT;
	for (addr = start; !r && addr < end; ) {
		struct hmm_range *hmm_range;
		unsigned long map_start_vma;
		unsigned long map_last_vma;
		struct vm_area_struct *vma;
		unsigned long next = 0;
		unsigned long offset;
		unsigned long npages;
		bool readonly;

		vma = vma_lookup(mm, addr);
		if (vma) {
			readonly = !(vma->vm_flags & VM_WRITE);

			next = min(vma->vm_end, end);
			npages = (next - addr) >> PAGE_SHIFT;
			WRITE_ONCE(p->svms.faulting_task, current);
			r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages,
						       readonly, owner, NULL,
						       &hmm_range);
			WRITE_ONCE(p->svms.faulting_task, NULL);
			if (r) {
				pr_debug("failed %d to get svm range pages\n", r);
				if (r == -EBUSY)
					r = -EAGAIN;
			}
		} else {
			r = -EFAULT;
		}

		if (!r) {
			offset = (addr >> PAGE_SHIFT) - prange->start;
			r = svm_range_dma_map(prange, ctx->bitmap, offset, npages,
					      hmm_range->hmm_pfns);
			if (r)
				pr_debug("failed %d to dma map range\n", r);
		}

		svm_range_lock(prange);
		if (!r && amdgpu_hmm_range_get_pages_done(hmm_range)) {
			pr_debug("hmm update the range, need validate again\n");
			r = -EAGAIN;
		}

		if (!r && !list_empty(&prange->child_list)) {
			pr_debug("range split by unmap in parallel, validate again\n");
			r = -EAGAIN;
		}

		if (!r) {
			map_start_vma = max(map_start, prange->start + offset);
			map_last_vma = min(map_last, prange->start + offset + npages - 1);
			if (map_start_vma <= map_last_vma) {
				offset = map_start_vma - prange->start;
				npages = map_last_vma - map_start_vma + 1;
				r = svm_range_map_to_gpus(prange, offset, npages, readonly,
							  ctx->bitmap, wait, flush_tlb);
			}
		}

		if (!r && next == end)
			prange->mapped_to_gpu = true;

		svm_range_unlock(prange);

		addr = next;
	}

	svm_range_unreserve_bos(ctx);
	if (!r)
		prange->validate_timestamp = ktime_get_boottime();

free_ctx:
	kfree(ctx);

	return r;
}

/**
 * svm_range_list_lock_and_flush_work - flush pending deferred work
 *
 * @svms: the svm range list
 * @mm: the mm structure
 *
 * Context: Returns with mmap write lock held, pending deferred work flushed
 *
 */
void
svm_range_list_lock_and_flush_work(struct svm_range_list *svms,
				   struct mm_struct *mm)
{
retry_flush_work:
	flush_work(&svms->deferred_list_work);
	mmap_write_lock(mm);

	if (list_empty(&svms->deferred_range_list))
		return;
	mmap_write_unlock(mm);
	pr_debug("retry flush\n");
	goto retry_flush_work;
}

static void svm_range_restore_work(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct amdkfd_process_info *process_info;
	struct svm_range_list *svms;
	struct svm_range *prange;
	struct kfd_process *p;
	struct mm_struct *mm;
	int evicted_ranges;
	int invalid;
	int r;

	svms = container_of(dwork, struct svm_range_list, restore_work);
	evicted_ranges = atomic_read(&svms->evicted_ranges);
	if (!evicted_ranges)
		return;

	pr_debug("restore svm ranges\n");

	p = container_of(svms, struct kfd_process, svms);
	process_info = p->kgd_process_info;

	/* Keep mm reference when svm_range_validate_and_map ranges */
	mm = get_task_mm(p->lead_thread);
	if (!mm) {
		pr_debug("svms 0x%p process mm gone\n", svms);
		return;
	}

	mutex_lock(&process_info->lock);
	svm_range_list_lock_and_flush_work(svms, mm);
	mutex_lock(&svms->lock);

	evicted_ranges = atomic_read(&svms->evicted_ranges);

	list_for_each_entry(prange, &svms->list, list) {
		invalid = atomic_read(&prange->invalid);
		if (!invalid)
			continue;

		pr_debug("restoring svms 0x%p prange 0x%p [0x%lx %lx] inv %d\n",
			 prange->svms, prange, prange->start, prange->last,
			 invalid);

		/*
		 * If range is migrating, wait for migration is done.
		 */
		mutex_lock(&prange->migrate_mutex);

		r = svm_range_validate_and_map(mm, prange->start, prange->last, prange,
					       MAX_GPU_INSTANCE, false, true, false);
		if (r)
			pr_debug("failed %d to map 0x%lx to gpus\n", r,
				 prange->start);

		mutex_unlock(&prange->migrate_mutex);
		if (r)
			goto out_reschedule;

		if (atomic_cmpxchg(&prange->invalid, invalid, 0) != invalid)
			goto out_reschedule;
	}

	if (atomic_cmpxchg(&svms->evicted_ranges, evicted_ranges, 0) !=
	    evicted_ranges)
		goto out_reschedule;

	evicted_ranges = 0;

	r = kgd2kfd_resume_mm(mm);
	if (r) {
		/* No recovery from this failure. Probably the CP is
		 * hanging. No point trying again.
		 */
		pr_debug("failed %d to resume KFD\n", r);
	}

	pr_debug("restore svm ranges successfully\n");

out_reschedule:
	mutex_unlock(&svms->lock);
	mmap_write_unlock(mm);
	mutex_unlock(&process_info->lock);

	/* If validation failed, reschedule another attempt */
	if (evicted_ranges) {
		pr_debug("reschedule to restore svm range\n");
		queue_delayed_work(system_freezable_wq, &svms->restore_work,
			msecs_to_jiffies(AMDGPU_SVM_RANGE_RESTORE_DELAY_MS));

		kfd_smi_event_queue_restore_rescheduled(mm);
	}
	mmput(mm);
}

/**
 * svm_range_evict - evict svm range
 * @prange: svm range structure
 * @mm: current process mm_struct
 * @start: starting process queue number
 * @last: last process queue number
 * @event: mmu notifier event when range is evicted or migrated
 *
 * Stop all queues of the process to ensure GPU doesn't access the memory, then
 * return to let CPU evict the buffer and proceed CPU pagetable update.
 *
 * Don't need use lock to sync cpu pagetable invalidation with GPU execution.
 * If invalidation happens while restore work is running, restore work will
 * restart to ensure to get the latest CPU pages mapping to GPU, then start
 * the queues.
 */
static int
svm_range_evict(struct svm_range *prange, struct mm_struct *mm,
		unsigned long start, unsigned long last,
		enum mmu_notifier_event event)
{
	struct svm_range_list *svms = prange->svms;
	struct svm_range *pchild;
	struct kfd_process *p;
	int r = 0;

	p = container_of(svms, struct kfd_process, svms);

	pr_debug("invalidate svms 0x%p prange [0x%lx 0x%lx] [0x%lx 0x%lx]\n",
		 svms, prange->start, prange->last, start, last);

	if (!p->xnack_enabled ||
	    (prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)) {
		int evicted_ranges;
		bool mapped = prange->mapped_to_gpu;

		list_for_each_entry(pchild, &prange->child_list, child_list) {
			if (!pchild->mapped_to_gpu)
				continue;
			mapped = true;
			mutex_lock_nested(&pchild->lock, 1);
			if (pchild->start <= last && pchild->last >= start) {
				pr_debug("increment pchild invalid [0x%lx 0x%lx]\n",
					 pchild->start, pchild->last);
				atomic_inc(&pchild->invalid);
			}
			mutex_unlock(&pchild->lock);
		}

		if (!mapped)
			return r;

		if (prange->start <= last && prange->last >= start)
			atomic_inc(&prange->invalid);

		evicted_ranges = atomic_inc_return(&svms->evicted_ranges);
		if (evicted_ranges != 1)
			return r;

		pr_debug("evicting svms 0x%p range [0x%lx 0x%lx]\n",
			 prange->svms, prange->start, prange->last);

		/* First eviction, stop the queues */
		r = kgd2kfd_quiesce_mm(mm, KFD_QUEUE_EVICTION_TRIGGER_SVM);
		if (r)
			pr_debug("failed to quiesce KFD\n");

		pr_debug("schedule to restore svm %p ranges\n", svms);
		queue_delayed_work(system_freezable_wq, &svms->restore_work,
			msecs_to_jiffies(AMDGPU_SVM_RANGE_RESTORE_DELAY_MS));
	} else {
		unsigned long s, l;
		uint32_t trigger;

		if (event == MMU_NOTIFY_MIGRATE)
			trigger = KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY_MIGRATE;
		else
			trigger = KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY;

		pr_debug("invalidate unmap svms 0x%p [0x%lx 0x%lx] from GPUs\n",
			 prange->svms, start, last);
		list_for_each_entry(pchild, &prange->child_list, child_list) {
			mutex_lock_nested(&pchild->lock, 1);
			s = max(start, pchild->start);
			l = min(last, pchild->last);
			if (l >= s)
				svm_range_unmap_from_gpus(pchild, s, l, trigger);
			mutex_unlock(&pchild->lock);
		}
		s = max(start, prange->start);
		l = min(last, prange->last);
		if (l >= s)
			svm_range_unmap_from_gpus(prange, s, l, trigger);
	}

	return r;
}

static struct svm_range *svm_range_clone(struct svm_range *old)
{
	struct svm_range *new;

	new = svm_range_new(old->svms, old->start, old->last, false);
	if (!new)
		return NULL;
	if (svm_range_copy_dma_addrs(new, old)) {
		svm_range_free(new, false);
		return NULL;
	}
	if (old->svm_bo) {
		new->ttm_res = old->ttm_res;
		new->offset = old->offset;
		new->svm_bo = svm_range_bo_ref(old->svm_bo);
		spin_lock(&new->svm_bo->list_lock);
		list_add(&new->svm_bo_list, &new->svm_bo->range_list);
		spin_unlock(&new->svm_bo->list_lock);
	}
	new->flags = old->flags;
	new->preferred_loc = old->preferred_loc;
	new->prefetch_loc = old->prefetch_loc;
	new->actual_loc = old->actual_loc;
	new->granularity = old->granularity;
	new->mapped_to_gpu = old->mapped_to_gpu;
	new->vram_pages = old->vram_pages;
	bitmap_copy(new->bitmap_access, old->bitmap_access, MAX_GPU_INSTANCE);
	bitmap_copy(new->bitmap_aip, old->bitmap_aip, MAX_GPU_INSTANCE);

	return new;
}

void svm_range_set_max_pages(struct amdgpu_device *adev)
{
	uint64_t max_pages;
	uint64_t pages, _pages;
	uint64_t min_pages = 0;
	int i, id;

	for (i = 0; i < adev->kfd.dev->num_nodes; i++) {
		if (adev->kfd.dev->nodes[i]->xcp)
			id = adev->kfd.dev->nodes[i]->xcp->id;
		else
			id = -1;
		pages = KFD_XCP_MEMORY_SIZE(adev, id) >> 17;
		pages = clamp(pages, 1ULL << 9, 1ULL << 18);
		pages = rounddown_pow_of_two(pages);
		min_pages = min_not_zero(min_pages, pages);
	}

	do {
		max_pages = READ_ONCE(max_svm_range_pages);
		_pages = min_not_zero(max_pages, min_pages);
	} while (cmpxchg(&max_svm_range_pages, max_pages, _pages) != max_pages);
}

static int
svm_range_split_new(struct svm_range_list *svms, uint64_t start, uint64_t last,
		    uint64_t max_pages, struct list_head *insert_list,
		    struct list_head *update_list)
{
	struct svm_range *prange;
	uint64_t l;

	pr_debug("max_svm_range_pages 0x%llx adding [0x%llx 0x%llx]\n",
		 max_pages, start, last);

	while (last >= start) {
		l = min(last, ALIGN_DOWN(start + max_pages, max_pages) - 1);

		prange = svm_range_new(svms, start, l, true);
		if (!prange)
			return -ENOMEM;
		list_add(&prange->list, insert_list);
		list_add(&prange->update_list, update_list);

		start = l + 1;
	}
	return 0;
}

/**
 * svm_range_add - add svm range and handle overlap
 * @p: the range add to this process svms
 * @start: page size aligned
 * @size: page size aligned
 * @nattr: number of attributes
 * @attrs: array of attributes
 * @update_list: output, the ranges need validate and update GPU mapping
 * @insert_list: output, the ranges need insert to svms
 * @remove_list: output, the ranges are replaced and need remove from svms
 * @remap_list: output, remap unaligned svm ranges
 *
 * Check if the virtual address range has overlap with any existing ranges,
 * split partly overlapping ranges and add new ranges in the gaps. All changes
 * should be applied to the range_list and interval tree transactionally. If
 * any range split or allocation fails, the entire update fails. Therefore any
 * existing overlapping svm_ranges are cloned and the original svm_ranges left
 * unchanged.
 *
 * If the transaction succeeds, the caller can update and insert clones and
 * new ranges, then free the originals.
 *
 * Otherwise the caller can free the clones and new ranges, while the old
 * svm_ranges remain unchanged.
 *
 * Context: Process context, caller must hold svms->lock
 *
 * Return:
 * 0 - OK, otherwise error code
 */
static int
svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size,
	      uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs,
	      struct list_head *update_list, struct list_head *insert_list,
	      struct list_head *remove_list, struct list_head *remap_list)
{
	unsigned long last = start + size - 1UL;
	struct svm_range_list *svms = &p->svms;
	struct interval_tree_node *node;
	struct svm_range *prange;
	struct svm_range *tmp;
	struct list_head new_list;
	int r = 0;

	pr_debug("svms 0x%p [0x%llx 0x%lx]\n", &p->svms, start, last);

	INIT_LIST_HEAD(update_list);
	INIT_LIST_HEAD(insert_list);
	INIT_LIST_HEAD(remove_list);
	INIT_LIST_HEAD(&new_list);
	INIT_LIST_HEAD(remap_list);

	node = interval_tree_iter_first(&svms->objects, start, last);
	while (node) {
		struct interval_tree_node *next;
		unsigned long next_start;

		pr_debug("found overlap node [0x%lx 0x%lx]\n", node->start,
			 node->last);

		prange = container_of(node, struct svm_range, it_node);
		next = interval_tree_iter_next(node, start, last);
		next_start = min(node->last, last) + 1;

		if (svm_range_is_same_attrs(p, prange, nattr, attrs) &&
		    prange->mapped_to_gpu) {
			/* nothing to do */
		} else if (node->start < start || node->last > last) {
			/* node intersects the update range and its attributes
			 * will change. Clone and split it, apply updates only
			 * to the overlapping part
			 */
			struct svm_range *old = prange;

			prange = svm_range_clone(old);
			if (!prange) {
				r = -ENOMEM;
				goto out;
			}

			list_add(&old->update_list, remove_list);
			list_add(&prange->list, insert_list);
			list_add(&prange->update_list, update_list);

			if (node->start < start) {
				pr_debug("change old range start\n");
				r = svm_range_split_head(prange, start,
							 insert_list, remap_list);
				if (r)
					goto out;
			}
			if (node->last > last) {
				pr_debug("change old range last\n");
				r = svm_range_split_tail(prange, last,
							 insert_list, remap_list);
				if (r)
					goto out;
			}
		} else {
			/* The node is contained within start..last,
			 * just update it
			 */
			list_add(&prange->update_list, update_list);
		}

		/* insert a new node if needed */
		if (node->start > start) {
			r = svm_range_split_new(svms, start, node->start - 1,
						READ_ONCE(max_svm_range_pages),
						&new_list, update_list);
			if (r)
				goto out;
		}

		node = next;
		start = next_start;
	}

	/* add a final range at the end if needed */
	if (start <= last)
		r = svm_range_split_new(svms, start, last,
					READ_ONCE(max_svm_range_pages),
					&new_list, update_list);

out:
	if (r) {
		list_for_each_entry_safe(prange, tmp, insert_list, list)
			svm_range_free(prange, false);
		list_for_each_entry_safe(prange, tmp, &new_list, list)
			svm_range_free(prange, true);
	} else {
		list_splice(&new_list, insert_list);
	}

	return r;
}

static void
svm_range_update_notifier_and_interval_tree(struct mm_struct *mm,
					    struct svm_range *prange)
{
	unsigned long start;
	unsigned long last;

	start = prange->notifier.interval_tree.start >> PAGE_SHIFT;
	last = prange->notifier.interval_tree.last >> PAGE_SHIFT;

	if (prange->start == start && prange->last == last)
		return;

	pr_debug("up notifier 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n",
		  prange->svms, prange, start, last, prange->start,
		  prange->last);

	if (start != 0 && last != 0) {
		interval_tree_remove(&prange->it_node, &prange->svms->objects);
		svm_range_remove_notifier(prange);
	}
	prange->it_node.start = prange->start;
	prange->it_node.last = prange->last;

	interval_tree_insert(&prange->it_node, &prange->svms->objects);
	svm_range_add_notifier_locked(mm, prange);
}

static void
svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange,
			 struct mm_struct *mm)
{
	switch (prange->work_item.op) {
	case SVM_OP_NULL:
		pr_debug("NULL OP 0x%p prange 0x%p [0x%lx 0x%lx]\n",
			 svms, prange, prange->start, prange->last);
		break;
	case SVM_OP_UNMAP_RANGE:
		pr_debug("remove 0x%p prange 0x%p [0x%lx 0x%lx]\n",
			 svms, prange, prange->start, prange->last);
		svm_range_unlink(prange);
		svm_range_remove_notifier(prange);
		svm_range_free(prange, true);
		break;
	case SVM_OP_UPDATE_RANGE_NOTIFIER:
		pr_debug("update notifier 0x%p prange 0x%p [0x%lx 0x%lx]\n",
			 svms, prange, prange->start, prange->last);
		svm_range_update_notifier_and_interval_tree(mm, prange);
		break;
	case SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP:
		pr_debug("update and map 0x%p prange 0x%p [0x%lx 0x%lx]\n",
			 svms, prange, prange->start, prange->last);
		svm_range_update_notifier_and_interval_tree(mm, prange);
		/* TODO: implement deferred validation and mapping */
		break;
	case SVM_OP_ADD_RANGE:
		pr_debug("add 0x%p prange 0x%p [0x%lx 0x%lx]\n", svms, prange,
			 prange->start, prange->last);
		svm_range_add_to_svms(prange);
		svm_range_add_notifier_locked(mm, prange);
		break;
	case SVM_OP_ADD_RANGE_AND_MAP:
		pr_debug("add and map 0x%p prange 0x%p [0x%lx 0x%lx]\n", svms,
			 prange, prange->start, prange->last);
		svm_range_add_to_svms(prange);
		svm_range_add_notifier_locked(mm, prange);
		/* TODO: implement deferred validation and mapping */
		break;
	default:
		WARN_ONCE(1, "Unknown prange 0x%p work op %d\n", prange,
			 prange->work_item.op);
	}
}

static void svm_range_drain_retry_fault(struct svm_range_list *svms)
{
	struct kfd_process_device *pdd;
	struct kfd_process *p;
	int drain;
	uint32_t i;

	p = container_of(svms, struct kfd_process, svms);

restart:
	drain = atomic_read(&svms->drain_pagefaults);
	if (!drain)
		return;

	for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) {
		pdd = p->pdds[i];
		if (!pdd)
			continue;

		pr_debug("drain retry fault gpu %d svms %p\n", i, svms);

		amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev,
				pdd->dev->adev->irq.retry_cam_enabled ?
				&pdd->dev->adev->irq.ih :
				&pdd->dev->adev->irq.ih1);

		if (pdd->dev->adev->irq.retry_cam_enabled)
			amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev,
				&pdd->dev->adev->irq.ih_soft);


		pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms);
	}
	if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain)
		goto restart;
}

static void svm_range_deferred_list_work(struct work_struct *work)
{
	struct svm_range_list *svms;
	struct svm_range *prange;
	struct mm_struct *mm;

	svms = container_of(work, struct svm_range_list, deferred_list_work);
	pr_debug("enter svms 0x%p\n", svms);

	spin_lock(&svms->deferred_list_lock);
	while (!list_empty(&svms->deferred_range_list)) {
		prange = list_first_entry(&svms->deferred_range_list,
					  struct svm_range, deferred_list);
		spin_unlock(&svms->deferred_list_lock);

		pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange,
			 prange->start, prange->last, prange->work_item.op);

		mm = prange->work_item.mm;
retry:
		mmap_write_lock(mm);

		/* Checking for the need to drain retry faults must be inside
		 * mmap write lock to serialize with munmap notifiers.
		 */
		if (unlikely(atomic_read(&svms->drain_pagefaults))) {
			mmap_write_unlock(mm);
			svm_range_drain_retry_fault(svms);
			goto retry;
		}

		/* Remove from deferred_list must be inside mmap write lock, for
		 * two race cases:
		 * 1. unmap_from_cpu may change work_item.op and add the range
		 *    to deferred_list again, cause use after free bug.
		 * 2. svm_range_list_lock_and_flush_work may hold mmap write
		 *    lock and continue because deferred_list is empty, but
		 *    deferred_list work is actually waiting for mmap lock.
		 */
		spin_lock(&svms->deferred_list_lock);
		list_del_init(&prange->deferred_list);
		spin_unlock(&svms->deferred_list_lock);

		mutex_lock(&svms->lock);
		mutex_lock(&prange->migrate_mutex);
		while (!list_empty(&prange->child_list)) {
			struct svm_range *pchild;

			pchild = list_first_entry(&prange->child_list,
						struct svm_range, child_list);
			pr_debug("child prange 0x%p op %d\n", pchild,
				 pchild->work_item.op);
			list_del_init(&pchild->child_list);
			svm_range_handle_list_op(svms, pchild, mm);
		}
		mutex_unlock(&prange->migrate_mutex);

		svm_range_handle_list_op(svms, prange, mm);
		mutex_unlock(&svms->lock);
		mmap_write_unlock(mm);

		/* Pairs with mmget in svm_range_add_list_work. If dropping the
		 * last mm refcount, schedule release work to avoid circular locking
		 */
		mmput_async(mm);

		spin_lock(&svms->deferred_list_lock);
	}
	spin_unlock(&svms->deferred_list_lock);
	pr_debug("exit svms 0x%p\n", svms);
}

void
svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
			struct mm_struct *mm, enum svm_work_list_ops op)
{
	spin_lock(&svms->deferred_list_lock);
	/* if prange is on the deferred list */
	if (!list_empty(&prange->deferred_list)) {
		pr_debug("update exist prange 0x%p work op %d\n", prange, op);
		WARN_ONCE(prange->work_item.mm != mm, "unmatch mm\n");
		if (op != SVM_OP_NULL &&
		    prange->work_item.op != SVM_OP_UNMAP_RANGE)
			prange->work_item.op = op;
	} else {
		prange->work_item.op = op;

		/* Pairs with mmput in deferred_list_work */
		mmget(mm);
		prange->work_item.mm = mm;
		list_add_tail(&prange->deferred_list,
			      &prange->svms->deferred_range_list);
		pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n",
			 prange, prange->start, prange->last, op);
	}
	spin_unlock(&svms->deferred_list_lock);
}

void schedule_deferred_list_work(struct svm_range_list *svms)
{
	spin_lock(&svms->deferred_list_lock);
	if (!list_empty(&svms->deferred_range_list))
		schedule_work(&svms->deferred_list_work);
	spin_unlock(&svms->deferred_list_lock);
}

static void
svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent,
		      struct svm_range *prange, unsigned long start,
		      unsigned long last)
{
	struct svm_range *head;
	struct svm_range *tail;

	if (prange->work_item.op == SVM_OP_UNMAP_RANGE) {
		pr_debug("prange 0x%p [0x%lx 0x%lx] is already freed\n", prange,
			 prange->start, prange->last);
		return;
	}
	if (start > prange->last || last < prange->start)
		return;

	head = tail = prange;
	if (start > prange->start)
		svm_range_split(prange, prange->start, start - 1, &tail);
	if (last < tail->last)
		svm_range_split(tail, last + 1, tail->last, &head);

	if (head != prange && tail != prange) {
		svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE);
		svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE);
	} else if (tail != prange) {
		svm_range_add_child(parent, mm, tail, SVM_OP_UNMAP_RANGE);
	} else if (head != prange) {
		svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE);
	} else if (parent != prange) {
		prange->work_item.op = SVM_OP_UNMAP_RANGE;
	}
}

static void
svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange,
			 unsigned long start, unsigned long last)
{
	uint32_t trigger = KFD_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU;
	struct svm_range_list *svms;
	struct svm_range *pchild;
	struct kfd_process *p;
	unsigned long s, l;
	bool unmap_parent;

	p = kfd_lookup_process_by_mm(mm);
	if (!p)
		return;
	svms = &p->svms;

	pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n", svms,
		 prange, prange->start, prange->last, start, last);

	/* Make sure pending page faults are drained in the deferred worker
	 * before the range is freed to avoid straggler interrupts on
	 * unmapped memory causing "phantom faults".
	 */
	atomic_inc(&svms->drain_pagefaults);

	unmap_parent = start <= prange->start && last >= prange->last;

	list_for_each_entry(pchild, &prange->child_list, child_list) {
		mutex_lock_nested(&pchild->lock, 1);
		s = max(start, pchild->start);
		l = min(last, pchild->last);
		if (l >= s)
			svm_range_unmap_from_gpus(pchild, s, l, trigger);
		svm_range_unmap_split(mm, prange, pchild, start, last);
		mutex_unlock(&pchild->lock);
	}
	s = max(start, prange->start);
	l = min(last, prange->last);
	if (l >= s)
		svm_range_unmap_from_gpus(prange, s, l, trigger);
	svm_range_unmap_split(mm, prange, prange, start, last);

	if (unmap_parent)
		svm_range_add_list_work(svms, prange, mm, SVM_OP_UNMAP_RANGE);
	else
		svm_range_add_list_work(svms, prange, mm,
					SVM_OP_UPDATE_RANGE_NOTIFIER);
	schedule_deferred_list_work(svms);

	kfd_unref_process(p);
}

/**
 * svm_range_cpu_invalidate_pagetables - interval notifier callback
 * @mni: mmu_interval_notifier struct
 * @range: mmu_notifier_range struct
 * @cur_seq: value to pass to mmu_interval_set_seq()
 *
 * If event is MMU_NOTIFY_UNMAP, this is from CPU unmap range, otherwise, it
 * is from migration, or CPU page invalidation callback.
 *
 * For unmap event, unmap range from GPUs, remove prange from svms in a delayed
 * work thread, and split prange if only part of prange is unmapped.
 *
 * For invalidation event, if GPU retry fault is not enabled, evict the queues,
 * then schedule svm_range_restore_work to update GPU mapping and resume queues.
 * If GPU retry fault is enabled, unmap the svm range from GPU, retry fault will
 * update GPU mapping to recover.
 *
 * Context: mmap lock, notifier_invalidate_start lock are held
 *          for invalidate event, prange lock is held if this is from migration
 */
static bool
svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
				    const struct mmu_notifier_range *range,
				    unsigned long cur_seq)
{
	struct svm_range *prange;
	unsigned long start;
	unsigned long last;

	if (range->event == MMU_NOTIFY_RELEASE)
		return true;
	if (!mmget_not_zero(mni->mm))
		return true;

	start = mni->interval_tree.start;
	last = mni->interval_tree.last;
	start = max(start, range->start) >> PAGE_SHIFT;
	last = min(last, range->end - 1) >> PAGE_SHIFT;
	pr_debug("[0x%lx 0x%lx] range[0x%lx 0x%lx] notifier[0x%lx 0x%lx] %d\n",
		 start, last, range->start >> PAGE_SHIFT,
		 (range->end - 1) >> PAGE_SHIFT,
		 mni->interval_tree.start >> PAGE_SHIFT,
		 mni->interval_tree.last >> PAGE_SHIFT, range->event);

	prange = container_of(mni, struct svm_range, notifier);

	svm_range_lock(prange);
	mmu_interval_set_seq(mni, cur_seq);

	switch (range->event) {
	case MMU_NOTIFY_UNMAP:
		svm_range_unmap_from_cpu(mni->mm, prange, start, last);
		break;
	default:
		svm_range_evict(prange, mni->mm, start, last, range->event);
		break;
	}

	svm_range_unlock(prange);
	mmput(mni->mm);

	return true;
}

/**
 * svm_range_from_addr - find svm range from fault address
 * @svms: svm range list header
 * @addr: address to search range interval tree, in pages
 * @parent: parent range if range is on child list
 *
 * Context: The caller must hold svms->lock
 *
 * Return: the svm_range found or NULL
 */
struct svm_range *
svm_range_from_addr(struct svm_range_list *svms, unsigned long addr,
		    struct svm_range **parent)
{
	struct interval_tree_node *node;
	struct svm_range *prange;
	struct svm_range *pchild;

	node = interval_tree_iter_first(&svms->objects, addr, addr);
	if (!node)
		return NULL;

	prange = container_of(node, struct svm_range, it_node);
	pr_debug("address 0x%lx prange [0x%lx 0x%lx] node [0x%lx 0x%lx]\n",
		 addr, prange->start, prange->last, node->start, node->last);

	if (addr >= prange->start && addr <= prange->last) {
		if (parent)
			*parent = prange;
		return prange;
	}
	list_for_each_entry(pchild, &prange->child_list, child_list)
		if (addr >= pchild->start && addr <= pchild->last) {
			pr_debug("found address 0x%lx pchild [0x%lx 0x%lx]\n",
				 addr, pchild->start, pchild->last);
			if (parent)
				*parent = prange;
			return pchild;
		}

	return NULL;
}

/* svm_range_best_restore_location - decide the best fault restore location
 * @prange: svm range structure
 * @adev: the GPU on which vm fault happened
 *
 * This is only called when xnack is on, to decide the best location to restore
 * the range mapping after GPU vm fault. Caller uses the best location to do
 * migration if actual loc is not best location, then update GPU page table
 * mapping to the best location.
 *
 * If the preferred loc is accessible by faulting GPU, use preferred loc.
 * If vm fault gpu idx is on range ACCESSIBLE bitmap, best_loc is vm fault gpu
 * If vm fault gpu idx is on range ACCESSIBLE_IN_PLACE bitmap, then
 *    if range actual loc is cpu, best_loc is cpu
 *    if vm fault gpu is on xgmi same hive of range actual loc gpu, best_loc is
 *    range actual loc.
 * Otherwise, GPU no access, best_loc is -1.
 *
 * Return:
 * -1 means vm fault GPU no access
 * 0 for CPU or GPU id
 */
static int32_t
svm_range_best_restore_location(struct svm_range *prange,
				struct kfd_node *node,
				int32_t *gpuidx)
{
	struct kfd_node *bo_node, *preferred_node;
	struct kfd_process *p;
	uint32_t gpuid;
	int r;

	p = container_of(prange->svms, struct kfd_process, svms);

	r = kfd_process_gpuid_from_node(p, node, &gpuid, gpuidx);
	if (r < 0) {
		pr_debug("failed to get gpuid from kgd\n");
		return -1;
	}

	if (node->adev->gmc.is_app_apu)
		return 0;

	if (prange->preferred_loc == gpuid ||
	    prange->preferred_loc == KFD_IOCTL_SVM_LOCATION_SYSMEM) {
		return prange->preferred_loc;
	} else if (prange->preferred_loc != KFD_IOCTL_SVM_LOCATION_UNDEFINED) {
		preferred_node = svm_range_get_node_by_id(prange, prange->preferred_loc);
		if (preferred_node && svm_nodes_in_same_hive(node, preferred_node))
			return prange->preferred_loc;
		/* fall through */
	}

	if (test_bit(*gpuidx, prange->bitmap_access))
		return gpuid;

	if (test_bit(*gpuidx, prange->bitmap_aip)) {
		if (!prange->actual_loc)
			return 0;

		bo_node = svm_range_get_node_by_id(prange, prange->actual_loc);
		if (bo_node && svm_nodes_in_same_hive(node, bo_node))
			return prange->actual_loc;
		else
			return 0;
	}

	return -1;
}

static int
svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
			       unsigned long *start, unsigned long *last,
			       bool *is_heap_stack)
{
	struct vm_area_struct *vma;
	struct interval_tree_node *node;
	struct rb_node *rb_node;
	unsigned long start_limit, end_limit;

	vma = vma_lookup(p->mm, addr << PAGE_SHIFT);
	if (!vma) {
		pr_debug("VMA does not exist in address [0x%llx]\n", addr);
		return -EFAULT;
	}

	*is_heap_stack = vma_is_initial_heap(vma) || vma_is_initial_stack(vma);

	start_limit = max(vma->vm_start >> PAGE_SHIFT,
		      (unsigned long)ALIGN_DOWN(addr, 2UL << 8));
	end_limit = min(vma->vm_end >> PAGE_SHIFT,
		    (unsigned long)ALIGN(addr + 1, 2UL << 8));
	/* First range that starts after the fault address */
	node = interval_tree_iter_first(&p->svms.objects, addr + 1, ULONG_MAX);
	if (node) {
		end_limit = min(end_limit, node->start);
		/* Last range that ends before the fault address */
		rb_node = rb_prev(&node->rb);
	} else {
		/* Last range must end before addr because
		 * there was no range after addr
		 */
		rb_node = rb_last(&p->svms.objects.rb_root);
	}
	if (rb_node) {
		node = container_of(rb_node, struct interval_tree_node, rb);
		if (node->last >= addr) {
			WARN(1, "Overlap with prev node and page fault addr\n");
			return -EFAULT;
		}
		start_limit = max(start_limit, node->last + 1);
	}

	*start = start_limit;
	*last = end_limit - 1;

	pr_debug("vma [0x%lx 0x%lx] range [0x%lx 0x%lx] is_heap_stack %d\n",
		 vma->vm_start >> PAGE_SHIFT, vma->vm_end >> PAGE_SHIFT,
		 *start, *last, *is_heap_stack);

	return 0;
}

static int
svm_range_check_vm_userptr(struct kfd_process *p, uint64_t start, uint64_t last,
			   uint64_t *bo_s, uint64_t *bo_l)
{
	struct amdgpu_bo_va_mapping *mapping;
	struct interval_tree_node *node;
	struct amdgpu_bo *bo = NULL;
	unsigned long userptr;
	uint32_t i;
	int r;

	for (i = 0; i < p->n_pdds; i++) {
		struct amdgpu_vm *vm;

		if (!p->pdds[i]->drm_priv)
			continue;

		vm = drm_priv_to_vm(p->pdds[i]->drm_priv);
		r = amdgpu_bo_reserve(vm->root.bo, false);
		if (r)
			return r;

		/* Check userptr by searching entire vm->va interval tree */
		node = interval_tree_iter_first(&vm->va, 0, ~0ULL);
		while (node) {
			mapping = container_of((struct rb_node *)node,
					       struct amdgpu_bo_va_mapping, rb);
			bo = mapping->bo_va->base.bo;

			if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm,
							 start << PAGE_SHIFT,
							 last << PAGE_SHIFT,
							 &userptr)) {
				node = interval_tree_iter_next(node, 0, ~0ULL);
				continue;
			}

			pr_debug("[0x%llx 0x%llx] already userptr mapped\n",
				 start, last);
			if (bo_s && bo_l) {
				*bo_s = userptr >> PAGE_SHIFT;
				*bo_l = *bo_s + bo->tbo.ttm->num_pages - 1;
			}
			amdgpu_bo_unreserve(vm->root.bo);
			return -EADDRINUSE;
		}
		amdgpu_bo_unreserve(vm->root.bo);
	}
	return 0;
}

static struct
svm_range *svm_range_create_unregistered_range(struct kfd_node *node,
						struct kfd_process *p,
						struct mm_struct *mm,
						int64_t addr)
{
	struct svm_range *prange = NULL;
	unsigned long start, last;
	uint32_t gpuid, gpuidx;
	bool is_heap_stack;
	uint64_t bo_s = 0;
	uint64_t bo_l = 0;
	int r;

	if (svm_range_get_range_boundaries(p, addr, &start, &last,
					   &is_heap_stack))
		return NULL;

	r = svm_range_check_vm(p, start, last, &bo_s, &bo_l);
	if (r != -EADDRINUSE)
		r = svm_range_check_vm_userptr(p, start, last, &bo_s, &bo_l);

	if (r == -EADDRINUSE) {
		if (addr >= bo_s && addr <= bo_l)
			return NULL;

		/* Create one page svm range if 2MB range overlapping */
		start = addr;
		last = addr;
	}

	prange = svm_range_new(&p->svms, start, last, true);
	if (!prange) {
		pr_debug("Failed to create prange in address [0x%llx]\n", addr);
		return NULL;
	}
	if (kfd_process_gpuid_from_node(p, node, &gpuid, &gpuidx)) {
		pr_debug("failed to get gpuid from kgd\n");
		svm_range_free(prange, true);
		return NULL;
	}

	if (is_heap_stack)
		prange->preferred_loc = KFD_IOCTL_SVM_LOCATION_SYSMEM;

	svm_range_add_to_svms(prange);
	svm_range_add_notifier_locked(mm, prange);

	return prange;
}

/* svm_range_skip_recover - decide if prange can be recovered
 * @prange: svm range structure
 *
 * GPU vm retry fault handle skip recover the range for cases:
 * 1. prange is on deferred list to be removed after unmap, it is stale fault,
 *    deferred list work will drain the stale fault before free the prange.
 * 2. prange is on deferred list to add interval notifier after split, or
 * 3. prange is child range, it is split from parent prange, recover later
 *    after interval notifier is added.
 *
 * Return: true to skip recover, false to recover
 */
static bool svm_range_skip_recover(struct svm_range *prange)
{
	struct svm_range_list *svms = prange->svms;

	spin_lock(&svms->deferred_list_lock);
	if (list_empty(&prange->deferred_list) &&
	    list_empty(&prange->child_list)) {
		spin_unlock(&svms->deferred_list_lock);
		return false;
	}
	spin_unlock(&svms->deferred_list_lock);

	if (prange->work_item.op == SVM_OP_UNMAP_RANGE) {
		pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] unmapped\n",
			 svms, prange, prange->start, prange->last);
		return true;
	}
	if (prange->work_item.op == SVM_OP_ADD_RANGE_AND_MAP ||
	    prange->work_item.op == SVM_OP_ADD_RANGE) {
		pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] not added yet\n",
			 svms, prange, prange->start, prange->last);
		return true;
	}
	return false;
}

static void
svm_range_count_fault(struct kfd_node *node, struct kfd_process *p,
		      int32_t gpuidx)
{
	struct kfd_process_device *pdd;

	/* fault is on different page of same range
	 * or fault is skipped to recover later
	 * or fault is on invalid virtual address
	 */
	if (gpuidx == MAX_GPU_INSTANCE) {
		uint32_t gpuid;
		int r;

		r = kfd_process_gpuid_from_node(p, node, &gpuid, &gpuidx);
		if (r < 0)
			return;
	}

	/* fault is recovered
	 * or fault cannot recover because GPU no access on the range
	 */
	pdd = kfd_process_device_from_gpuidx(p, gpuidx);
	if (pdd)
		WRITE_ONCE(pdd->faults, pdd->faults + 1);
}

static bool
svm_fault_allowed(struct vm_area_struct *vma, bool write_fault)
{
	unsigned long requested = VM_READ;

	if (write_fault)
		requested |= VM_WRITE;

	pr_debug("requested 0x%lx, vma permission flags 0x%lx\n", requested,
		vma->vm_flags);
	return (vma->vm_flags & requested) == requested;
}

int
svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
			uint32_t vmid, uint32_t node_id,
			uint64_t addr, bool write_fault)
{
	unsigned long start, last, size;
	struct mm_struct *mm = NULL;
	struct svm_range_list *svms;
	struct svm_range *prange;
	struct kfd_process *p;
	ktime_t timestamp = ktime_get_boottime();
	struct kfd_node *node;
	int32_t best_loc;
	int32_t gpuidx = MAX_GPU_INSTANCE;
	bool write_locked = false;
	struct vm_area_struct *vma;
	bool migration = false;
	int r = 0;

	if (!KFD_IS_SVM_API_SUPPORTED(adev)) {
		pr_debug("device does not support SVM\n");
		return -EFAULT;
	}

	p = kfd_lookup_process_by_pasid(pasid);
	if (!p) {
		pr_debug("kfd process not founded pasid 0x%x\n", pasid);
		return 0;
	}
	svms = &p->svms;

	pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr);

	if (atomic_read(&svms->drain_pagefaults)) {
		pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
		r = 0;
		goto out;
	}

	if (!p->xnack_enabled) {
		pr_debug("XNACK not enabled for pasid 0x%x\n", pasid);
		r = -EFAULT;
		goto out;
	}

	/* p->lead_thread is available as kfd_process_wq_release flush the work
	 * before releasing task ref.
	 */
	mm = get_task_mm(p->lead_thread);
	if (!mm) {
		pr_debug("svms 0x%p failed to get mm\n", svms);
		r = 0;
		goto out;
	}

	node = kfd_node_by_irq_ids(adev, node_id, vmid);
	if (!node) {
		pr_debug("kfd node does not exist node_id: %d, vmid: %d\n", node_id,
			 vmid);
		r = -EFAULT;
		goto out;
	}
	mmap_read_lock(mm);
retry_write_locked:
	mutex_lock(&svms->lock);
	prange = svm_range_from_addr(svms, addr, NULL);
	if (!prange) {
		pr_debug("failed to find prange svms 0x%p address [0x%llx]\n",
			 svms, addr);
		if (!write_locked) {
			/* Need the write lock to create new range with MMU notifier.
			 * Also flush pending deferred work to make sure the interval
			 * tree is up to date before we add a new range
			 */
			mutex_unlock(&svms->lock);
			mmap_read_unlock(mm);
			mmap_write_lock(mm);
			write_locked = true;
			goto retry_write_locked;
		}
		prange = svm_range_create_unregistered_range(node, p, mm, addr);
		if (!prange) {
			pr_debug("failed to create unregistered range svms 0x%p address [0x%llx]\n",
				 svms, addr);
			mmap_write_downgrade(mm);
			r = -EFAULT;
			goto out_unlock_svms;
		}
	}
	if (write_locked)
		mmap_write_downgrade(mm);

	mutex_lock(&prange->migrate_mutex);

	if (svm_range_skip_recover(prange)) {
		amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
		r = 0;
		goto out_unlock_range;
	}

	/* skip duplicate vm fault on different pages of same range */
	if (ktime_before(timestamp, ktime_add_ns(prange->validate_timestamp,
				AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING))) {
		pr_debug("svms 0x%p [0x%lx %lx] already restored\n",
			 svms, prange->start, prange->last);
		r = 0;
		goto out_unlock_range;
	}

	/* __do_munmap removed VMA, return success as we are handling stale
	 * retry fault.
	 */
	vma = vma_lookup(mm, addr << PAGE_SHIFT);
	if (!vma) {
		pr_debug("address 0x%llx VMA is removed\n", addr);
		r = 0;
		goto out_unlock_range;
	}

	if (!svm_fault_allowed(vma, write_fault)) {
		pr_debug("fault addr 0x%llx no %s permission\n", addr,
			write_fault ? "write" : "read");
		r = -EPERM;
		goto out_unlock_range;
	}

	best_loc = svm_range_best_restore_location(prange, node, &gpuidx);
	if (best_loc == -1) {
		pr_debug("svms %p failed get best restore loc [0x%lx 0x%lx]\n",
			 svms, prange->start, prange->last);
		r = -EACCES;
		goto out_unlock_range;
	}

	pr_debug("svms %p [0x%lx 0x%lx] best restore 0x%x, actual loc 0x%x\n",
		 svms, prange->start, prange->last, best_loc,
		 prange->actual_loc);

	kfd_smi_event_page_fault_start(node, p->lead_thread->pid, addr,
				       write_fault, timestamp);

	/* Align migration range start and size to granularity size */
	size = 1UL << prange->granularity;
	start = max_t(unsigned long, ALIGN_DOWN(addr, size), prange->start);
	last = min_t(unsigned long, ALIGN(addr + 1, size) - 1, prange->last);
	if (prange->actual_loc != 0 || best_loc != 0) {
		migration = true;

		if (best_loc) {
			r = svm_migrate_to_vram(prange, best_loc, start, last,
					mm, KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU);
			if (r) {
				pr_debug("svm_migrate_to_vram failed (%d) at %llx, falling back to system memory\n",
					 r, addr);
				/* Fallback to system memory if migration to
				 * VRAM failed
				 */
				if (prange->actual_loc && prange->actual_loc != best_loc)
					r = svm_migrate_vram_to_ram(prange, mm, start, last,
						KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU, NULL);
				else
					r = 0;
			}
		} else {
			r = svm_migrate_vram_to_ram(prange, mm, start, last,
					KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU, NULL);
		}
		if (r) {
			pr_debug("failed %d to migrate svms %p [0x%lx 0x%lx]\n",
				 r, svms, start, last);
			goto out_unlock_range;
		}
	}

	r = svm_range_validate_and_map(mm, start, last, prange, gpuidx, false,
				       false, false);
	if (r)
		pr_debug("failed %d to map svms 0x%p [0x%lx 0x%lx] to gpus\n",
			 r, svms, start, last);

	kfd_smi_event_page_fault_end(node, p->lead_thread->pid, addr,
				     migration);

out_unlock_range:
	mutex_unlock(&prange->migrate_mutex);
out_unlock_svms:
	mutex_unlock(&svms->lock);
	mmap_read_unlock(mm);

	svm_range_count_fault(node, p, gpuidx);

	mmput(mm);
out:
	kfd_unref_process(p);

	if (r == -EAGAIN) {
		pr_debug("recover vm fault later\n");
		amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
		r = 0;
	}
	return r;
}

int
svm_range_switch_xnack_reserve_mem(struct kfd_process *p, bool xnack_enabled)
{
	struct svm_range *prange, *pchild;
	uint64_t reserved_size = 0;
	uint64_t size;
	int r = 0;

	pr_debug("switching xnack from %d to %d\n", p->xnack_enabled, xnack_enabled);

	mutex_lock(&p->svms.lock);

	list_for_each_entry(prange, &p->svms.list, list) {
		svm_range_lock(prange);
		list_for_each_entry(pchild, &prange->child_list, child_list) {
			size = (pchild->last - pchild->start + 1) << PAGE_SHIFT;
			if (xnack_enabled) {
				amdgpu_amdkfd_unreserve_mem_limit(NULL, size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
			} else {
				r = amdgpu_amdkfd_reserve_mem_limit(NULL, size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
				if (r)
					goto out_unlock;
				reserved_size += size;
			}
		}

		size = (prange->last - prange->start + 1) << PAGE_SHIFT;
		if (xnack_enabled) {
			amdgpu_amdkfd_unreserve_mem_limit(NULL, size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
		} else {
			r = amdgpu_amdkfd_reserve_mem_limit(NULL, size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
			if (r)
				goto out_unlock;
			reserved_size += size;
		}
out_unlock:
		svm_range_unlock(prange);
		if (r)
			break;
	}

	if (r)
		amdgpu_amdkfd_unreserve_mem_limit(NULL, reserved_size,
					KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0);
	else
		/* Change xnack mode must be inside svms lock, to avoid race with
		 * svm_range_deferred_list_work unreserve memory in parallel.
		 */
		p->xnack_enabled = xnack_enabled;

	mutex_unlock(&p->svms.lock);
	return r;
}

void svm_range_list_fini(struct kfd_process *p)
{
	struct svm_range *prange;
	struct svm_range *next;

	pr_debug("pasid 0x%x svms 0x%p\n", p->pasid, &p->svms);

	cancel_delayed_work_sync(&p->svms.restore_work);

	/* Ensure list work is finished before process is destroyed */
	flush_work(&p->svms.deferred_list_work);

	/*
	 * Ensure no retry fault comes in afterwards, as page fault handler will
	 * not find kfd process and take mm lock to recover fault.
	 */
	atomic_inc(&p->svms.drain_pagefaults);
	svm_range_drain_retry_fault(&p->svms);

	list_for_each_entry_safe(prange, next, &p->svms.list, list) {
		svm_range_unlink(prange);
		svm_range_remove_notifier(prange);
		svm_range_free(prange, true);
	}

	mutex_destroy(&p->svms.lock);

	pr_debug("pasid 0x%x svms 0x%p done\n", p->pasid, &p->svms);
}

int svm_range_list_init(struct kfd_process *p)
{
	struct svm_range_list *svms = &p->svms;
	int i;

	svms->objects = RB_ROOT_CACHED;
	mutex_init(&svms->lock);
	INIT_LIST_HEAD(&svms->list);
	atomic_set(&svms->evicted_ranges, 0);
	atomic_set(&svms->drain_pagefaults, 0);
	INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work);
	INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work);
	INIT_LIST_HEAD(&svms->deferred_range_list);
	INIT_LIST_HEAD(&svms->criu_svm_metadata_list);
	spin_lock_init(&svms->deferred_list_lock);

	for (i = 0; i < p->n_pdds; i++)
		if (KFD_IS_SVM_API_SUPPORTED(p->pdds[i]->dev->adev))
			bitmap_set(svms->bitmap_supported, i, 1);

	return 0;
}

/**
 * svm_range_check_vm - check if virtual address range mapped already
 * @p: current kfd_process
 * @start: range start address, in pages
 * @last: range last address, in pages
 * @bo_s: mapping start address in pages if address range already mapped
 * @bo_l: mapping last address in pages if address range already mapped
 *
 * The purpose is to avoid virtual address ranges already allocated by
 * kfd_ioctl_alloc_memory_of_gpu ioctl.
 * It looks for each pdd in the kfd_process.
 *
 * Context: Process context
 *
 * Return 0 - OK, if the range is not mapped.
 * Otherwise error code:
 * -EADDRINUSE - if address is mapped already by kfd_ioctl_alloc_memory_of_gpu
 * -ERESTARTSYS - A wait for the buffer to become unreserved was interrupted by
 * a signal. Release all buffer reservations and return to user-space.
 */
static int
svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last,
		   uint64_t *bo_s, uint64_t *bo_l)
{
	struct amdgpu_bo_va_mapping *mapping;
	struct interval_tree_node *node;
	uint32_t i;
	int r;

	for (i = 0; i < p->n_pdds; i++) {
		struct amdgpu_vm *vm;

		if (!p->pdds[i]->drm_priv)
			continue;

		vm = drm_priv_to_vm(p->pdds[i]->drm_priv);
		r = amdgpu_bo_reserve(vm->root.bo, false);
		if (r)
			return r;

		node = interval_tree_iter_first(&vm->va, start, last);
		if (node) {
			pr_debug("range [0x%llx 0x%llx] already TTM mapped\n",
				 start, last);
			mapping = container_of((struct rb_node *)node,
					       struct amdgpu_bo_va_mapping, rb);
			if (bo_s && bo_l) {
				*bo_s = mapping->start;
				*bo_l = mapping->last;
			}
			amdgpu_bo_unreserve(vm->root.bo);
			return -EADDRINUSE;
		}
		amdgpu_bo_unreserve(vm->root.bo);
	}

	return 0;
}

/**
 * svm_range_is_valid - check if virtual address range is valid
 * @p: current kfd_process
 * @start: range start address, in pages
 * @size: range size, in pages
 *
 * Valid virtual address range means it belongs to one or more VMAs
 *
 * Context: Process context
 *
 * Return:
 *  0 - OK, otherwise error code
 */
static int
svm_range_is_valid(struct kfd_process *p, uint64_t start, uint64_t size)
{
	const unsigned long device_vma = VM_IO | VM_PFNMAP | VM_MIXEDMAP;
	struct vm_area_struct *vma;
	unsigned long end;
	unsigned long start_unchg = start;

	start <<= PAGE_SHIFT;
	end = start + (size << PAGE_SHIFT);
	do {
		vma = vma_lookup(p->mm, start);
		if (!vma || (vma->vm_flags & device_vma))
			return -EFAULT;
		start = min(end, vma->vm_end);
	} while (start < end);

	return svm_range_check_vm(p, start_unchg, (end - 1) >> PAGE_SHIFT, NULL,
				  NULL);
}

/**
 * svm_range_best_prefetch_location - decide the best prefetch location
 * @prange: svm range structure
 *
 * For xnack off:
 * If range map to single GPU, the best prefetch location is prefetch_loc, which
 * can be CPU or GPU.
 *
 * If range is ACCESS or ACCESS_IN_PLACE by mGPUs, only if mGPU connection on
 * XGMI same hive, the best prefetch location is prefetch_loc GPU, othervise
 * the best prefetch location is always CPU, because GPU can not have coherent
 * mapping VRAM of other GPUs even with large-BAR PCIe connection.
 *
 * For xnack on:
 * If range is not ACCESS_IN_PLACE by mGPUs, the best prefetch location is
 * prefetch_loc, other GPU access will generate vm fault and trigger migration.
 *
 * If range is ACCESS_IN_PLACE by mGPUs, only if mGPU connection on XGMI same
 * hive, the best prefetch location is prefetch_loc GPU, otherwise the best
 * prefetch location is always CPU.
 *
 * Context: Process context
 *
 * Return:
 * 0 for CPU or GPU id
 */
static uint32_t
svm_range_best_prefetch_location(struct svm_range *prange)
{
	DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE);
	uint32_t best_loc = prange->prefetch_loc;
	struct kfd_process_device *pdd;
	struct kfd_node *bo_node;
	struct kfd_process *p;
	uint32_t gpuidx;

	p = container_of(prange->svms, struct kfd_process, svms);

	if (!best_loc || best_loc == KFD_IOCTL_SVM_LOCATION_UNDEFINED)
		goto out;

	bo_node = svm_range_get_node_by_id(prange, best_loc);
	if (!bo_node) {
		WARN_ONCE(1, "failed to get valid kfd node at id%x\n", best_loc);
		best_loc = 0;
		goto out;
	}

	if (bo_node->adev->gmc.is_app_apu) {
		best_loc = 0;
		goto out;
	}

	if (p->xnack_enabled)
		bitmap_copy(bitmap, prange->bitmap_aip, MAX_GPU_INSTANCE);
	else
		bitmap_or(bitmap, prange->bitmap_access, prange->bitmap_aip,
			  MAX_GPU_INSTANCE);

	for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
		pdd = kfd_process_device_from_gpuidx(p, gpuidx);
		if (!pdd) {
			pr_debug("failed to get device by idx 0x%x\n", gpuidx);
			continue;
		}

		if (pdd->dev->adev == bo_node->adev)
			continue;

		if (!svm_nodes_in_same_hive(pdd->dev, bo_node)) {
			best_loc = 0;
			break;
		}
	}

out:
	pr_debug("xnack %d svms 0x%p [0x%lx 0x%lx] best loc 0x%x\n",
		 p->xnack_enabled, &p->svms, prange->start, prange->last,
		 best_loc);

	return best_loc;
}

/* svm_range_trigger_migration - start page migration if prefetch loc changed
 * @mm: current process mm_struct
 * @prange: svm range structure
 * @migrated: output, true if migration is triggered
 *
 * If range perfetch_loc is GPU, actual loc is cpu 0, then migrate the range
 * from ram to vram.
 * If range prefetch_loc is cpu 0, actual loc is GPU, then migrate the range
 * from vram to ram.
 *
 * If GPU vm fault retry is not enabled, migration interact with MMU notifier
 * and restore work:
 * 1. migrate_vma_setup invalidate pages, MMU notifier callback svm_range_evict
 *    stops all queues, schedule restore work
 * 2. svm_range_restore_work wait for migration is done by
 *    a. svm_range_validate_vram takes prange->migrate_mutex
 *    b. svm_range_validate_ram HMM get pages wait for CPU fault handle returns
 * 3. restore work update mappings of GPU, resume all queues.
 *
 * Context: Process context
 *
 * Return:
 * 0 - OK, otherwise - error code of migration
 */
static int
svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange,
			    bool *migrated)
{
	uint32_t best_loc;
	int r = 0;

	*migrated = false;
	best_loc = svm_range_best_prefetch_location(prange);

	/* when best_loc is a gpu node and same as prange->actual_loc
	 * we still need do migration as prange->actual_loc !=0 does
	 * not mean all pages in prange are vram. hmm migrate will pick
	 * up right pages during migration.
	 */
	if ((best_loc == KFD_IOCTL_SVM_LOCATION_UNDEFINED) ||
	    (best_loc == 0 && prange->actual_loc == 0))
		return 0;

	if (!best_loc) {
		r = svm_migrate_vram_to_ram(prange, mm, prange->start, prange->last,
					KFD_MIGRATE_TRIGGER_PREFETCH, NULL);
		*migrated = !r;
		return r;
	}

	r = svm_migrate_to_vram(prange, best_loc, prange->start, prange->last,
				mm, KFD_MIGRATE_TRIGGER_PREFETCH);
	*migrated = !r;

	return r;
}

int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
{
	/* Dereferencing fence->svm_bo is safe here because the fence hasn't
	 * signaled yet and we're under the protection of the fence->lock.
	 * After the fence is signaled in svm_range_bo_release, we cannot get
	 * here any more.
	 *
	 * Reference is dropped in svm_range_evict_svm_bo_worker.
	 */
	if (svm_bo_ref_unless_zero(fence->svm_bo)) {
		WRITE_ONCE(fence->svm_bo->evicting, 1);
		schedule_work(&fence->svm_bo->eviction_work);
	}

	return 0;
}

static void svm_range_evict_svm_bo_worker(struct work_struct *work)
{
	struct svm_range_bo *svm_bo;
	struct mm_struct *mm;
	int r = 0;

	svm_bo = container_of(work, struct svm_range_bo, eviction_work);

	if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
		mm = svm_bo->eviction_fence->mm;
	} else {
		svm_range_bo_unref(svm_bo);
		return;
	}

	mmap_read_lock(mm);
	spin_lock(&svm_bo->list_lock);
	while (!list_empty(&svm_bo->range_list) && !r) {
		struct svm_range *prange =
				list_first_entry(&svm_bo->range_list,
						struct svm_range, svm_bo_list);
		int retries = 3;

		list_del_init(&prange->svm_bo_list);
		spin_unlock(&svm_bo->list_lock);

		pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms,
			 prange->start, prange->last);

		mutex_lock(&prange->migrate_mutex);
		do {
			/* migrate all vram pages in this prange to sys ram
			 * after that prange->actual_loc should be zero
			 */
			r = svm_migrate_vram_to_ram(prange, mm,
					prange->start, prange->last,
					KFD_MIGRATE_TRIGGER_TTM_EVICTION, NULL);
		} while (!r && prange->actual_loc && --retries);

		if (!r && prange->actual_loc)
			pr_info_once("Migration failed during eviction");

		if (!prange->actual_loc) {
			mutex_lock(&prange->lock);
			prange->svm_bo = NULL;
			mutex_unlock(&prange->lock);
		}
		mutex_unlock(&prange->migrate_mutex);

		spin_lock(&svm_bo->list_lock);
	}
	spin_unlock(&svm_bo->list_lock);
	mmap_read_unlock(mm);
	mmput(mm);

	dma_fence_signal(&svm_bo->eviction_fence->base);

	/* This is the last reference to svm_bo, after svm_range_vram_node_free
	 * has been called in svm_migrate_vram_to_ram
	 */
	WARN_ONCE(!r && kref_read(&svm_bo->kref) != 1, "This was not the last reference\n");
	svm_range_bo_unref(svm_bo);
}

static int
svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,
		   uint64_t start, uint64_t size, uint32_t nattr,
		   struct kfd_ioctl_svm_attribute *attrs)
{
	struct amdkfd_process_info *process_info = p->kgd_process_info;
	struct list_head update_list;
	struct list_head insert_list;
	struct list_head remove_list;
	struct list_head remap_list;
	struct svm_range_list *svms;
	struct svm_range *prange;
	struct svm_range *next;
	bool update_mapping = false;
	bool flush_tlb;
	int r, ret = 0;

	pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] pages 0x%llx\n",
		 p->pasid, &p->svms, start, start + size - 1, size);

	r = svm_range_check_attr(p, nattr, attrs);
	if (r)
		return r;

	svms = &p->svms;

	mutex_lock(&process_info->lock);

	svm_range_list_lock_and_flush_work(svms, mm);

	r = svm_range_is_valid(p, start, size);
	if (r) {
		pr_debug("invalid range r=%d\n", r);
		mmap_write_unlock(mm);
		goto out;
	}

	mutex_lock(&svms->lock);

	/* Add new range and split existing ranges as needed */
	r = svm_range_add(p, start, size, nattr, attrs, &update_list,
			  &insert_list, &remove_list, &remap_list);
	if (r) {
		mutex_unlock(&svms->lock);
		mmap_write_unlock(mm);
		goto out;
	}
	/* Apply changes as a transaction */
	list_for_each_entry_safe(prange, next, &insert_list, list) {
		svm_range_add_to_svms(prange);
		svm_range_add_notifier_locked(mm, prange);
	}
	list_for_each_entry(prange, &update_list, update_list) {
		svm_range_apply_attrs(p, prange, nattr, attrs, &update_mapping);
		/* TODO: unmap ranges from GPU that lost access */
	}
	list_for_each_entry_safe(prange, next, &remove_list, update_list) {
		pr_debug("unlink old 0x%p prange 0x%p [0x%lx 0x%lx]\n",
			 prange->svms, prange, prange->start,
			 prange->last);
		svm_range_unlink(prange);
		svm_range_remove_notifier(prange);
		svm_range_free(prange, false);
	}

	mmap_write_downgrade(mm);
	/* Trigger migrations and revalidate and map to GPUs as needed. If
	 * this fails we may be left with partially completed actions. There
	 * is no clean way of rolling back to the previous state in such a
	 * case because the rollback wouldn't be guaranteed to work either.
	 */
	list_for_each_entry(prange, &update_list, update_list) {
		bool migrated;

		mutex_lock(&prange->migrate_mutex);

		r = svm_range_trigger_migration(mm, prange, &migrated);
		if (r)
			goto out_unlock_range;

		if (migrated && (!p->xnack_enabled ||
		    (prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)) &&
		    prange->mapped_to_gpu) {
			pr_debug("restore_work will update mappings of GPUs\n");
			mutex_unlock(&prange->migrate_mutex);
			continue;
		}

		if (!migrated && !update_mapping) {
			mutex_unlock(&prange->migrate_mutex);
			continue;
		}

		flush_tlb = !migrated && update_mapping && prange->mapped_to_gpu;

		r = svm_range_validate_and_map(mm, prange->start, prange->last, prange,
					       MAX_GPU_INSTANCE, true, true, flush_tlb);
		if (r)
			pr_debug("failed %d to map svm range\n", r);

out_unlock_range:
		mutex_unlock(&prange->migrate_mutex);
		if (r)
			ret = r;
	}

	list_for_each_entry(prange, &remap_list, update_list) {
		pr_debug("Remapping prange 0x%p [0x%lx 0x%lx]\n",
			 prange, prange->start, prange->last);
		mutex_lock(&prange->migrate_mutex);
		r = svm_range_validate_and_map(mm,  prange->start, prange->last, prange,
					       MAX_GPU_INSTANCE, true, true, prange->mapped_to_gpu);
		if (r)
			pr_debug("failed %d on remap svm range\n", r);
		mutex_unlock(&prange->migrate_mutex);
		if (r)
			ret = r;
	}

	dynamic_svm_range_dump(svms);

	mutex_unlock(&svms->lock);
	mmap_read_unlock(mm);
out:
	mutex_unlock(&process_info->lock);

	pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid,
		 &p->svms, start, start + size - 1, r);

	return ret ? ret : r;
}

static int
svm_range_get_attr(struct kfd_process *p, struct mm_struct *mm,
		   uint64_t start, uint64_t size, uint32_t nattr,
		   struct kfd_ioctl_svm_attribute *attrs)
{
	DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
	DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
	bool get_preferred_loc = false;
	bool get_prefetch_loc = false;
	bool get_granularity = false;
	bool get_accessible = false;
	bool get_flags = false;
	uint64_t last = start + size - 1UL;
	uint8_t granularity = 0xff;
	struct interval_tree_node *node;
	struct svm_range_list *svms;
	struct svm_range *prange;
	uint32_t prefetch_loc = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
	uint32_t location = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
	uint32_t flags_and = 0xffffffff;
	uint32_t flags_or = 0;
	int gpuidx;
	uint32_t i;
	int r = 0;

	pr_debug("svms 0x%p [0x%llx 0x%llx] nattr 0x%x\n", &p->svms, start,
		 start + size - 1, nattr);

	/* Flush pending deferred work to avoid racing with deferred actions from
	 * previous memory map changes (e.g. munmap). Concurrent memory map changes
	 * can still race with get_attr because we don't hold the mmap lock. But that
	 * would be a race condition in the application anyway, and undefined
	 * behaviour is acceptable in that case.
	 */
	flush_work(&p->svms.deferred_list_work);

	mmap_read_lock(mm);
	r = svm_range_is_valid(p, start, size);
	mmap_read_unlock(mm);
	if (r) {
		pr_debug("invalid range r=%d\n", r);
		return r;
	}

	for (i = 0; i < nattr; i++) {
		switch (attrs[i].type) {
		case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
			get_preferred_loc = true;
			break;
		case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
			get_prefetch_loc = true;
			break;
		case KFD_IOCTL_SVM_ATTR_ACCESS:
			get_accessible = true;
			break;
		case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
		case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
			get_flags = true;
			break;
		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
			get_granularity = true;
			break;
		case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
		case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
			fallthrough;
		default:
			pr_debug("get invalid attr type 0x%x\n", attrs[i].type);
			return -EINVAL;
		}
	}

	svms = &p->svms;

	mutex_lock(&svms->lock);

	node = interval_tree_iter_first(&svms->objects, start, last);
	if (!node) {
		pr_debug("range attrs not found return default values\n");
		svm_range_set_default_attributes(&location, &prefetch_loc,
						 &granularity, &flags_and);
		flags_or = flags_and;
		if (p->xnack_enabled)
			bitmap_copy(bitmap_access, svms->bitmap_supported,
				    MAX_GPU_INSTANCE);
		else
			bitmap_zero(bitmap_access, MAX_GPU_INSTANCE);
		bitmap_zero(bitmap_aip, MAX_GPU_INSTANCE);
		goto fill_values;
	}
	bitmap_copy(bitmap_access, svms->bitmap_supported, MAX_GPU_INSTANCE);
	bitmap_copy(bitmap_aip, svms->bitmap_supported, MAX_GPU_INSTANCE);

	while (node) {
		struct interval_tree_node *next;

		prange = container_of(node, struct svm_range, it_node);
		next = interval_tree_iter_next(node, start, last);

		if (get_preferred_loc) {
			if (prange->preferred_loc ==
					KFD_IOCTL_SVM_LOCATION_UNDEFINED ||
			    (location != KFD_IOCTL_SVM_LOCATION_UNDEFINED &&
			     location != prange->preferred_loc)) {
				location = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
				get_preferred_loc = false;
			} else {
				location = prange->preferred_loc;
			}
		}
		if (get_prefetch_loc) {
			if (prange->prefetch_loc ==
					KFD_IOCTL_SVM_LOCATION_UNDEFINED ||
			    (prefetch_loc != KFD_IOCTL_SVM_LOCATION_UNDEFINED &&
			     prefetch_loc != prange->prefetch_loc)) {
				prefetch_loc = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
				get_prefetch_loc = false;
			} else {
				prefetch_loc = prange->prefetch_loc;
			}
		}
		if (get_accessible) {
			bitmap_and(bitmap_access, bitmap_access,
				   prange->bitmap_access, MAX_GPU_INSTANCE);
			bitmap_and(bitmap_aip, bitmap_aip,
				   prange->bitmap_aip, MAX_GPU_INSTANCE);
		}
		if (get_flags) {
			flags_and &= prange->flags;
			flags_or |= prange->flags;
		}

		if (get_granularity && prange->granularity < granularity)
			granularity = prange->granularity;

		node = next;
	}
fill_values:
	mutex_unlock(&svms->lock);

	for (i = 0; i < nattr; i++) {
		switch (attrs[i].type) {
		case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
			attrs[i].value = location;
			break;
		case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
			attrs[i].value = prefetch_loc;
			break;
		case KFD_IOCTL_SVM_ATTR_ACCESS:
			gpuidx = kfd_process_gpuidx_from_gpuid(p,
							       attrs[i].value);
			if (gpuidx < 0) {
				pr_debug("invalid gpuid %x\n", attrs[i].value);
				return -EINVAL;
			}
			if (test_bit(gpuidx, bitmap_access))
				attrs[i].type = KFD_IOCTL_SVM_ATTR_ACCESS;
			else if (test_bit(gpuidx, bitmap_aip))
				attrs[i].type =
					KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE;
			else
				attrs[i].type = KFD_IOCTL_SVM_ATTR_NO_ACCESS;
			break;
		case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
			attrs[i].value = flags_and;
			break;
		case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
			attrs[i].value = ~flags_or;
			break;
		case KFD_IOCTL_SVM_ATTR_GRANULARITY:
			attrs[i].value = (uint32_t)granularity;
			break;
		}
	}

	return 0;
}

int kfd_criu_resume_svm(struct kfd_process *p)
{
	struct kfd_ioctl_svm_attribute *set_attr_new, *set_attr = NULL;
	int nattr_common = 4, nattr_accessibility = 1;
	struct criu_svm_metadata *criu_svm_md = NULL;
	struct svm_range_list *svms = &p->svms;
	struct criu_svm_metadata *next = NULL;
	uint32_t set_flags = 0xffffffff;
	int i, j, num_attrs, ret = 0;
	uint64_t set_attr_size;
	struct mm_struct *mm;

	if (list_empty(&svms->criu_svm_metadata_list)) {
		pr_debug("No SVM data from CRIU restore stage 2\n");
		return ret;
	}

	mm = get_task_mm(p->lead_thread);
	if (!mm) {
		pr_err("failed to get mm for the target process\n");
		return -ESRCH;
	}

	num_attrs = nattr_common + (nattr_accessibility * p->n_pdds);

	i = j = 0;
	list_for_each_entry(criu_svm_md, &svms->criu_svm_metadata_list, list) {
		pr_debug("criu_svm_md[%d]\n\tstart: 0x%llx size: 0x%llx (npages)\n",
			 i, criu_svm_md->data.start_addr, criu_svm_md->data.size);

		for (j = 0; j < num_attrs; j++) {
			pr_debug("\ncriu_svm_md[%d]->attrs[%d].type : 0x%x\ncriu_svm_md[%d]->attrs[%d].value : 0x%x\n",
				 i, j, criu_svm_md->data.attrs[j].type,
				 i, j, criu_svm_md->data.attrs[j].value);
			switch (criu_svm_md->data.attrs[j].type) {
			/* During Checkpoint operation, the query for
			 * KFD_IOCTL_SVM_ATTR_PREFETCH_LOC attribute might
			 * return KFD_IOCTL_SVM_LOCATION_UNDEFINED if they were
			 * not used by the range which was checkpointed. Care
			 * must be taken to not restore with an invalid value
			 * otherwise the gpuidx value will be invalid and
			 * set_attr would eventually fail so just replace those
			 * with another dummy attribute such as
			 * KFD_IOCTL_SVM_ATTR_SET_FLAGS.
			 */
			case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
				if (criu_svm_md->data.attrs[j].value ==
				    KFD_IOCTL_SVM_LOCATION_UNDEFINED) {
					criu_svm_md->data.attrs[j].type =
						KFD_IOCTL_SVM_ATTR_SET_FLAGS;
					criu_svm_md->data.attrs[j].value = 0;
				}
				break;
			case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
				set_flags = criu_svm_md->data.attrs[j].value;
				break;
			default:
				break;
			}
		}

		/* CLR_FLAGS is not available via get_attr during checkpoint but
		 * it needs to be inserted before restoring the ranges so
		 * allocate extra space for it before calling set_attr
		 */
		set_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
						(num_attrs + 1);
		set_attr_new = krealloc(set_attr, set_attr_size,
					    GFP_KERNEL);
		if (!set_attr_new) {
			ret = -ENOMEM;
			goto exit;
		}
		set_attr = set_attr_new;

		memcpy(set_attr, criu_svm_md->data.attrs, num_attrs *
					sizeof(struct kfd_ioctl_svm_attribute));
		set_attr[num_attrs].type = KFD_IOCTL_SVM_ATTR_CLR_FLAGS;
		set_attr[num_attrs].value = ~set_flags;

		ret = svm_range_set_attr(p, mm, criu_svm_md->data.start_addr,
					 criu_svm_md->data.size, num_attrs + 1,
					 set_attr);
		if (ret) {
			pr_err("CRIU: failed to set range attributes\n");
			goto exit;
		}

		i++;
	}
exit:
	kfree(set_attr);
	list_for_each_entry_safe(criu_svm_md, next, &svms->criu_svm_metadata_list, list) {
		pr_debug("freeing criu_svm_md[]\n\tstart: 0x%llx\n",
						criu_svm_md->data.start_addr);
		kfree(criu_svm_md);
	}

	mmput(mm);
	return ret;

}

int kfd_criu_restore_svm(struct kfd_process *p,
			 uint8_t __user *user_priv_ptr,
			 uint64_t *priv_data_offset,
			 uint64_t max_priv_data_size)
{
	uint64_t svm_priv_data_size, svm_object_md_size, svm_attrs_size;
	int nattr_common = 4, nattr_accessibility = 1;
	struct criu_svm_metadata *criu_svm_md = NULL;
	struct svm_range_list *svms = &p->svms;
	uint32_t num_devices;
	int ret = 0;

	num_devices = p->n_pdds;
	/* Handle one SVM range object at a time, also the number of gpus are
	 * assumed to be same on the restore node, checking must be done while
	 * evaluating the topology earlier
	 */

	svm_attrs_size = sizeof(struct kfd_ioctl_svm_attribute) *
		(nattr_common + nattr_accessibility * num_devices);
	svm_object_md_size = sizeof(struct criu_svm_metadata) + svm_attrs_size;

	svm_priv_data_size = sizeof(struct kfd_criu_svm_range_priv_data) +
								svm_attrs_size;

	criu_svm_md = kzalloc(svm_object_md_size, GFP_KERNEL);
	if (!criu_svm_md) {
		pr_err("failed to allocate memory to store svm metadata\n");
		return -ENOMEM;
	}
	if (*priv_data_offset + svm_priv_data_size > max_priv_data_size) {
		ret = -EINVAL;
		goto exit;
	}

	ret = copy_from_user(&criu_svm_md->data, user_priv_ptr + *priv_data_offset,
			     svm_priv_data_size);
	if (ret) {
		ret = -EFAULT;
		goto exit;
	}
	*priv_data_offset += svm_priv_data_size;

	list_add_tail(&criu_svm_md->list, &svms->criu_svm_metadata_list);

	return 0;


exit:
	kfree(criu_svm_md);
	return ret;
}

int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
		       uint64_t *svm_priv_data_size)
{
	uint64_t total_size, accessibility_size, common_attr_size;
	int nattr_common = 4, nattr_accessibility = 1;
	int num_devices = p->n_pdds;
	struct svm_range_list *svms;
	struct svm_range *prange;
	uint32_t count = 0;

	*svm_priv_data_size = 0;

	svms = &p->svms;
	if (!svms)
		return -EINVAL;

	mutex_lock(&svms->lock);
	list_for_each_entry(prange, &svms->list, list) {
		pr_debug("prange: 0x%p start: 0x%lx\t npages: 0x%llx\t end: 0x%llx\n",
			 prange, prange->start, prange->npages,
			 prange->start + prange->npages - 1);
		count++;
	}
	mutex_unlock(&svms->lock);

	*num_svm_ranges = count;
	/* Only the accessbility attributes need to be queried for all the gpus
	 * individually, remaining ones are spanned across the entire process
	 * regardless of the various gpu nodes. Of the remaining attributes,
	 * KFD_IOCTL_SVM_ATTR_CLR_FLAGS need not be saved.
	 *
	 * KFD_IOCTL_SVM_ATTR_PREFERRED_LOC
	 * KFD_IOCTL_SVM_ATTR_PREFETCH_LOC
	 * KFD_IOCTL_SVM_ATTR_SET_FLAGS
	 * KFD_IOCTL_SVM_ATTR_GRANULARITY
	 *
	 * ** ACCESSBILITY ATTRIBUTES **
	 * (Considered as one, type is altered during query, value is gpuid)
	 * KFD_IOCTL_SVM_ATTR_ACCESS
	 * KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE
	 * KFD_IOCTL_SVM_ATTR_NO_ACCESS
	 */
	if (*num_svm_ranges > 0) {
		common_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
			nattr_common;
		accessibility_size = sizeof(struct kfd_ioctl_svm_attribute) *
			nattr_accessibility * num_devices;

		total_size = sizeof(struct kfd_criu_svm_range_priv_data) +
			common_attr_size + accessibility_size;

		*svm_priv_data_size = *num_svm_ranges * total_size;
	}

	pr_debug("num_svm_ranges %u total_priv_size %llu\n", *num_svm_ranges,
		 *svm_priv_data_size);
	return 0;
}

int kfd_criu_checkpoint_svm(struct kfd_process *p,
			    uint8_t __user *user_priv_data,
			    uint64_t *priv_data_offset)
{
	struct kfd_criu_svm_range_priv_data *svm_priv = NULL;
	struct kfd_ioctl_svm_attribute *query_attr = NULL;
	uint64_t svm_priv_data_size, query_attr_size = 0;
	int index, nattr_common = 4, ret = 0;
	struct svm_range_list *svms;
	int num_devices = p->n_pdds;
	struct svm_range *prange;
	struct mm_struct *mm;

	svms = &p->svms;
	if (!svms)
		return -EINVAL;

	mm = get_task_mm(p->lead_thread);
	if (!mm) {
		pr_err("failed to get mm for the target process\n");
		return -ESRCH;
	}

	query_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
				(nattr_common + num_devices);

	query_attr = kzalloc(query_attr_size, GFP_KERNEL);
	if (!query_attr) {
		ret = -ENOMEM;
		goto exit;
	}

	query_attr[0].type = KFD_IOCTL_SVM_ATTR_PREFERRED_LOC;
	query_attr[1].type = KFD_IOCTL_SVM_ATTR_PREFETCH_LOC;
	query_attr[2].type = KFD_IOCTL_SVM_ATTR_SET_FLAGS;
	query_attr[3].type = KFD_IOCTL_SVM_ATTR_GRANULARITY;

	for (index = 0; index < num_devices; index++) {
		struct kfd_process_device *pdd = p->pdds[index];

		query_attr[index + nattr_common].type =
			KFD_IOCTL_SVM_ATTR_ACCESS;
		query_attr[index + nattr_common].value = pdd->user_gpu_id;
	}

	svm_priv_data_size = sizeof(*svm_priv) + query_attr_size;

	svm_priv = kzalloc(svm_priv_data_size, GFP_KERNEL);
	if (!svm_priv) {
		ret = -ENOMEM;
		goto exit_query;
	}

	index = 0;
	list_for_each_entry(prange, &svms->list, list) {

		svm_priv->object_type = KFD_CRIU_OBJECT_TYPE_SVM_RANGE;
		svm_priv->start_addr = prange->start;
		svm_priv->size = prange->npages;
		memcpy(&svm_priv->attrs, query_attr, query_attr_size);
		pr_debug("CRIU: prange: 0x%p start: 0x%lx\t npages: 0x%llx end: 0x%llx\t size: 0x%llx\n",
			 prange, prange->start, prange->npages,
			 prange->start + prange->npages - 1,
			 prange->npages * PAGE_SIZE);

		ret = svm_range_get_attr(p, mm, svm_priv->start_addr,
					 svm_priv->size,
					 (nattr_common + num_devices),
					 svm_priv->attrs);
		if (ret) {
			pr_err("CRIU: failed to obtain range attributes\n");
			goto exit_priv;
		}

		if (copy_to_user(user_priv_data + *priv_data_offset, svm_priv,
				 svm_priv_data_size)) {
			pr_err("Failed to copy svm priv to user\n");
			ret = -EFAULT;
			goto exit_priv;
		}

		*priv_data_offset += svm_priv_data_size;

	}


exit_priv:
	kfree(svm_priv);
exit_query:
	kfree(query_attr);
exit:
	mmput(mm);
	return ret;
}

int
svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
	  uint64_t size, uint32_t nattrs, struct kfd_ioctl_svm_attribute *attrs)
{
	struct mm_struct *mm = current->mm;
	int r;

	start >>= PAGE_SHIFT;
	size >>= PAGE_SHIFT;

	switch (op) {
	case KFD_IOCTL_SVM_OP_SET_ATTR:
		r = svm_range_set_attr(p, mm, start, size, nattrs, attrs);
		break;
	case KFD_IOCTL_SVM_OP_GET_ATTR:
		r = svm_range_get_attr(p, mm, start, size, nattrs, attrs);
		break;
	default:
		r = EINVAL;
		break;
	}

	return r;
}
