/*
 * Copyright 2018 Red Hat 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 "nouveau_svm.h"
#include "nouveau_drv.h"
#include "nouveau_chan.h"
#include "nouveau_dmem.h"

#include <nvif/event.h>
#include <nvif/object.h>
#include <nvif/vmm.h>

#include <nvif/class.h>
#include <nvif/clb069.h>
#include <nvif/ifc00d.h>

#include <linux/sched/mm.h>
#include <linux/sort.h>
#include <linux/hmm.h>
#include <linux/memremap.h>
#include <linux/rmap.h>

struct nouveau_svm {
	struct nouveau_drm *drm;
	struct mutex mutex;
	struct list_head inst;

	struct nouveau_svm_fault_buffer {
		int id;
		struct nvif_object object;
		u32 entries;
		u32 getaddr;
		u32 putaddr;
		u32 get;
		u32 put;
		struct nvif_event notify;
		struct work_struct work;

		struct nouveau_svm_fault {
			u64 inst;
			u64 addr;
			u64 time;
			u32 engine;
			u8  gpc;
			u8  hub;
			u8  access;
			u8  client;
			u8  fault;
			struct nouveau_svmm *svmm;
		} **fault;
		int fault_nr;
	} buffer[1];
};

#define FAULT_ACCESS_READ 0
#define FAULT_ACCESS_WRITE 1
#define FAULT_ACCESS_ATOMIC 2
#define FAULT_ACCESS_PREFETCH 3

#define SVM_DBG(s,f,a...) NV_DEBUG((s)->drm, "svm: "f"\n", ##a)
#define SVM_ERR(s,f,a...) NV_WARN((s)->drm, "svm: "f"\n", ##a)

struct nouveau_pfnmap_args {
	struct nvif_ioctl_v0 i;
	struct nvif_ioctl_mthd_v0 m;
	struct nvif_vmm_pfnmap_v0 p;
};

struct nouveau_ivmm {
	struct nouveau_svmm *svmm;
	u64 inst;
	struct list_head head;
};

static struct nouveau_ivmm *
nouveau_ivmm_find(struct nouveau_svm *svm, u64 inst)
{
	struct nouveau_ivmm *ivmm;
	list_for_each_entry(ivmm, &svm->inst, head) {
		if (ivmm->inst == inst)
			return ivmm;
	}
	return NULL;
}

#define SVMM_DBG(s,f,a...)                                                     \
	NV_DEBUG((s)->vmm->cli->drm, "svm-%p: "f"\n", (s), ##a)
#define SVMM_ERR(s,f,a...)                                                     \
	NV_WARN((s)->vmm->cli->drm, "svm-%p: "f"\n", (s), ##a)

int
nouveau_svmm_bind(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct drm_nouveau_svm_bind *args = data;
	unsigned target, cmd, priority;
	unsigned long addr, end;
	struct mm_struct *mm;

	args->va_start &= PAGE_MASK;
	args->va_end = ALIGN(args->va_end, PAGE_SIZE);

	/* Sanity check arguments */
	if (args->reserved0 || args->reserved1)
		return -EINVAL;
	if (args->header & (~NOUVEAU_SVM_BIND_VALID_MASK))
		return -EINVAL;
	if (args->va_start >= args->va_end)
		return -EINVAL;

	cmd = args->header >> NOUVEAU_SVM_BIND_COMMAND_SHIFT;
	cmd &= NOUVEAU_SVM_BIND_COMMAND_MASK;
	switch (cmd) {
	case NOUVEAU_SVM_BIND_COMMAND__MIGRATE:
		break;
	default:
		return -EINVAL;
	}

	priority = args->header >> NOUVEAU_SVM_BIND_PRIORITY_SHIFT;
	priority &= NOUVEAU_SVM_BIND_PRIORITY_MASK;

	/* FIXME support CPU target ie all target value < GPU_VRAM */
	target = args->header >> NOUVEAU_SVM_BIND_TARGET_SHIFT;
	target &= NOUVEAU_SVM_BIND_TARGET_MASK;
	switch (target) {
	case NOUVEAU_SVM_BIND_TARGET__GPU_VRAM:
		break;
	default:
		return -EINVAL;
	}

	/*
	 * FIXME: For now refuse non 0 stride, we need to change the migrate
	 * kernel function to handle stride to avoid to create a mess within
	 * each device driver.
	 */
	if (args->stride)
		return -EINVAL;

	/*
	 * Ok we are ask to do something sane, for now we only support migrate
	 * commands but we will add things like memory policy (what to do on
	 * page fault) and maybe some other commands.
	 */

	mm = get_task_mm(current);
	if (!mm) {
		return -EINVAL;
	}
	mmap_read_lock(mm);

	if (!cli->svm.svmm) {
		mmap_read_unlock(mm);
		mmput(mm);
		return -EINVAL;
	}

	for (addr = args->va_start, end = args->va_end; addr < end;) {
		struct vm_area_struct *vma;
		unsigned long next;

		vma = find_vma_intersection(mm, addr, end);
		if (!vma)
			break;

		addr = max(addr, vma->vm_start);
		next = min(vma->vm_end, end);
		/* This is a best effort so we ignore errors */
		nouveau_dmem_migrate_vma(cli->drm, cli->svm.svmm, vma, addr,
					 next);
		addr = next;
	}

	/*
	 * FIXME Return the number of page we have migrated, again we need to
	 * update the migrate API to return that information so that we can
	 * report it to user space.
	 */
	args->result = 0;

	mmap_read_unlock(mm);
	mmput(mm);

	return 0;
}

/* Unlink channel instance from SVMM. */
void
nouveau_svmm_part(struct nouveau_svmm *svmm, u64 inst)
{
	struct nouveau_ivmm *ivmm;
	if (svmm) {
		mutex_lock(&svmm->vmm->cli->drm->svm->mutex);
		ivmm = nouveau_ivmm_find(svmm->vmm->cli->drm->svm, inst);
		if (ivmm) {
			list_del(&ivmm->head);
			kfree(ivmm);
		}
		mutex_unlock(&svmm->vmm->cli->drm->svm->mutex);
	}
}

/* Link channel instance to SVMM. */
int
nouveau_svmm_join(struct nouveau_svmm *svmm, u64 inst)
{
	struct nouveau_ivmm *ivmm;
	if (svmm) {
		if (!(ivmm = kmalloc(sizeof(*ivmm), GFP_KERNEL)))
			return -ENOMEM;
		ivmm->svmm = svmm;
		ivmm->inst = inst;

		mutex_lock(&svmm->vmm->cli->drm->svm->mutex);
		list_add(&ivmm->head, &svmm->vmm->cli->drm->svm->inst);
		mutex_unlock(&svmm->vmm->cli->drm->svm->mutex);
	}
	return 0;
}

/* Invalidate SVMM address-range on GPU. */
void
nouveau_svmm_invalidate(struct nouveau_svmm *svmm, u64 start, u64 limit)
{
	if (limit > start) {
		nvif_object_mthd(&svmm->vmm->vmm.object, NVIF_VMM_V0_PFNCLR,
				 &(struct nvif_vmm_pfnclr_v0) {
					.addr = start,
					.size = limit - start,
				 }, sizeof(struct nvif_vmm_pfnclr_v0));
	}
}

static int
nouveau_svmm_invalidate_range_start(struct mmu_notifier *mn,
				    const struct mmu_notifier_range *update)
{
	struct nouveau_svmm *svmm =
		container_of(mn, struct nouveau_svmm, notifier);
	unsigned long start = update->start;
	unsigned long limit = update->end;

	if (!mmu_notifier_range_blockable(update))
		return -EAGAIN;

	SVMM_DBG(svmm, "invalidate %016lx-%016lx", start, limit);

	mutex_lock(&svmm->mutex);
	if (unlikely(!svmm->vmm))
		goto out;

	/*
	 * Ignore invalidation callbacks for device private pages since
	 * the invalidation is handled as part of the migration process.
	 */
	if (update->event == MMU_NOTIFY_MIGRATE &&
	    update->owner == svmm->vmm->cli->drm->dev)
		goto out;

	if (limit > svmm->unmanaged.start && start < svmm->unmanaged.limit) {
		if (start < svmm->unmanaged.start) {
			nouveau_svmm_invalidate(svmm, start,
						svmm->unmanaged.limit);
		}
		start = svmm->unmanaged.limit;
	}

	nouveau_svmm_invalidate(svmm, start, limit);

out:
	mutex_unlock(&svmm->mutex);
	return 0;
}

static void nouveau_svmm_free_notifier(struct mmu_notifier *mn)
{
	kfree(container_of(mn, struct nouveau_svmm, notifier));
}

static const struct mmu_notifier_ops nouveau_mn_ops = {
	.invalidate_range_start = nouveau_svmm_invalidate_range_start,
	.free_notifier = nouveau_svmm_free_notifier,
};

void
nouveau_svmm_fini(struct nouveau_svmm **psvmm)
{
	struct nouveau_svmm *svmm = *psvmm;
	if (svmm) {
		mutex_lock(&svmm->mutex);
		svmm->vmm = NULL;
		mutex_unlock(&svmm->mutex);
		mmu_notifier_put(&svmm->notifier);
		*psvmm = NULL;
	}
}

int
nouveau_svmm_init(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_svmm *svmm;
	struct drm_nouveau_svm_init *args = data;
	int ret;

	/* We need to fail if svm is disabled */
	if (!cli->drm->svm)
		return -ENOSYS;

	/* Allocate tracking for SVM-enabled VMM. */
	if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL)))
		return -ENOMEM;
	svmm->vmm = &cli->svm;
	svmm->unmanaged.start = args->unmanaged_addr;
	svmm->unmanaged.limit = args->unmanaged_addr + args->unmanaged_size;
	mutex_init(&svmm->mutex);

	/* Check that SVM isn't already enabled for the client. */
	mutex_lock(&cli->mutex);
	if (cli->svm.cli) {
		ret = -EBUSY;
		goto out_free;
	}

	/* Allocate a new GPU VMM that can support SVM (managed by the
	 * client, with replayable faults enabled).
	 *
	 * All future channel/memory allocations will make use of this
	 * VMM instead of the standard one.
	 */
	ret = nvif_vmm_ctor(&cli->mmu, "svmVmm",
			    cli->vmm.vmm.object.oclass, true,
			    args->unmanaged_addr, args->unmanaged_size,
			    &(struct gp100_vmm_v0) {
				.fault_replay = true,
			    }, sizeof(struct gp100_vmm_v0), &cli->svm.vmm);
	if (ret)
		goto out_free;

	mmap_write_lock(current->mm);
	svmm->notifier.ops = &nouveau_mn_ops;
	ret = __mmu_notifier_register(&svmm->notifier, current->mm);
	if (ret)
		goto out_mm_unlock;
	/* Note, ownership of svmm transfers to mmu_notifier */

	cli->svm.svmm = svmm;
	cli->svm.cli = cli;
	mmap_write_unlock(current->mm);
	mutex_unlock(&cli->mutex);
	return 0;

out_mm_unlock:
	mmap_write_unlock(current->mm);
out_free:
	mutex_unlock(&cli->mutex);
	kfree(svmm);
	return ret;
}

/* Issue fault replay for GPU to retry accesses that faulted previously. */
static void
nouveau_svm_fault_replay(struct nouveau_svm *svm)
{
	SVM_DBG(svm, "replay");
	WARN_ON(nvif_object_mthd(&svm->drm->client.vmm.vmm.object,
				 GP100_VMM_VN_FAULT_REPLAY,
				 &(struct gp100_vmm_fault_replay_vn) {},
				 sizeof(struct gp100_vmm_fault_replay_vn)));
}

/* Cancel a replayable fault that could not be handled.
 *
 * Cancelling the fault will trigger recovery to reset the engine
 * and kill the offending channel (ie. GPU SIGSEGV).
 */
static void
nouveau_svm_fault_cancel(struct nouveau_svm *svm,
			 u64 inst, u8 hub, u8 gpc, u8 client)
{
	SVM_DBG(svm, "cancel %016llx %d %02x %02x", inst, hub, gpc, client);
	WARN_ON(nvif_object_mthd(&svm->drm->client.vmm.vmm.object,
				 GP100_VMM_VN_FAULT_CANCEL,
				 &(struct gp100_vmm_fault_cancel_v0) {
					.hub = hub,
					.gpc = gpc,
					.client = client,
					.inst = inst,
				 }, sizeof(struct gp100_vmm_fault_cancel_v0)));
}

static void
nouveau_svm_fault_cancel_fault(struct nouveau_svm *svm,
			       struct nouveau_svm_fault *fault)
{
	nouveau_svm_fault_cancel(svm, fault->inst,
				      fault->hub,
				      fault->gpc,
				      fault->client);
}

static int
nouveau_svm_fault_priority(u8 fault)
{
	switch (fault) {
	case FAULT_ACCESS_PREFETCH:
		return 0;
	case FAULT_ACCESS_READ:
		return 1;
	case FAULT_ACCESS_WRITE:
		return 2;
	case FAULT_ACCESS_ATOMIC:
		return 3;
	default:
		WARN_ON_ONCE(1);
		return -1;
	}
}

static int
nouveau_svm_fault_cmp(const void *a, const void *b)
{
	const struct nouveau_svm_fault *fa = *(struct nouveau_svm_fault **)a;
	const struct nouveau_svm_fault *fb = *(struct nouveau_svm_fault **)b;
	int ret;
	if ((ret = (s64)fa->inst - fb->inst))
		return ret;
	if ((ret = (s64)fa->addr - fb->addr))
		return ret;
	return nouveau_svm_fault_priority(fa->access) -
		nouveau_svm_fault_priority(fb->access);
}

static void
nouveau_svm_fault_cache(struct nouveau_svm *svm,
			struct nouveau_svm_fault_buffer *buffer, u32 offset)
{
	struct nvif_object *memory = &buffer->object;
	const u32 instlo = nvif_rd32(memory, offset + 0x00);
	const u32 insthi = nvif_rd32(memory, offset + 0x04);
	const u32 addrlo = nvif_rd32(memory, offset + 0x08);
	const u32 addrhi = nvif_rd32(memory, offset + 0x0c);
	const u32 timelo = nvif_rd32(memory, offset + 0x10);
	const u32 timehi = nvif_rd32(memory, offset + 0x14);
	const u32 engine = nvif_rd32(memory, offset + 0x18);
	const u32   info = nvif_rd32(memory, offset + 0x1c);
	const u64   inst = (u64)insthi << 32 | instlo;
	const u8     gpc = (info & 0x1f000000) >> 24;
	const u8     hub = (info & 0x00100000) >> 20;
	const u8  client = (info & 0x00007f00) >> 8;
	struct nouveau_svm_fault *fault;

	//XXX: i think we're supposed to spin waiting */
	if (WARN_ON(!(info & 0x80000000)))
		return;

	nvif_mask(memory, offset + 0x1c, 0x80000000, 0x00000000);

	if (!buffer->fault[buffer->fault_nr]) {
		fault = kmalloc(sizeof(*fault), GFP_KERNEL);
		if (WARN_ON(!fault)) {
			nouveau_svm_fault_cancel(svm, inst, hub, gpc, client);
			return;
		}
		buffer->fault[buffer->fault_nr] = fault;
	}

	fault = buffer->fault[buffer->fault_nr++];
	fault->inst   = inst;
	fault->addr   = (u64)addrhi << 32 | addrlo;
	fault->time   = (u64)timehi << 32 | timelo;
	fault->engine = engine;
	fault->gpc    = gpc;
	fault->hub    = hub;
	fault->access = (info & 0x000f0000) >> 16;
	fault->client = client;
	fault->fault  = (info & 0x0000001f);

	SVM_DBG(svm, "fault %016llx %016llx %02x",
		fault->inst, fault->addr, fault->access);
}

struct svm_notifier {
	struct mmu_interval_notifier notifier;
	struct nouveau_svmm *svmm;
};

static bool nouveau_svm_range_invalidate(struct mmu_interval_notifier *mni,
					 const struct mmu_notifier_range *range,
					 unsigned long cur_seq)
{
	struct svm_notifier *sn =
		container_of(mni, struct svm_notifier, notifier);

	if (range->event == MMU_NOTIFY_EXCLUSIVE &&
	    range->owner == sn->svmm->vmm->cli->drm->dev)
		return true;

	/*
	 * serializes the update to mni->invalidate_seq done by caller and
	 * prevents invalidation of the PTE from progressing while HW is being
	 * programmed. This is very hacky and only works because the normal
	 * notifier that does invalidation is always called after the range
	 * notifier.
	 */
	if (mmu_notifier_range_blockable(range))
		mutex_lock(&sn->svmm->mutex);
	else if (!mutex_trylock(&sn->svmm->mutex))
		return false;
	mmu_interval_set_seq(mni, cur_seq);
	mutex_unlock(&sn->svmm->mutex);
	return true;
}

static const struct mmu_interval_notifier_ops nouveau_svm_mni_ops = {
	.invalidate = nouveau_svm_range_invalidate,
};

static void nouveau_hmm_convert_pfn(struct nouveau_drm *drm,
				    struct hmm_range *range,
				    struct nouveau_pfnmap_args *args)
{
	struct page *page;

	/*
	 * The address prepared here is passed through nvif_object_ioctl()
	 * to an eventual DMA map in something like gp100_vmm_pgt_pfn()
	 *
	 * This is all just encoding the internal hmm representation into a
	 * different nouveau internal representation.
	 */
	if (!(range->hmm_pfns[0] & HMM_PFN_VALID)) {
		args->p.phys[0] = 0;
		return;
	}

	page = hmm_pfn_to_page(range->hmm_pfns[0]);
	/*
	 * Only map compound pages to the GPU if the CPU is also mapping the
	 * page as a compound page. Otherwise, the PTE protections might not be
	 * consistent (e.g., CPU only maps part of a compound page).
	 * Note that the underlying page might still be larger than the
	 * CPU mapping (e.g., a PUD sized compound page partially mapped with
	 * a PMD sized page table entry).
	 */
	if (hmm_pfn_to_map_order(range->hmm_pfns[0])) {
		unsigned long addr = args->p.addr;

		args->p.page = hmm_pfn_to_map_order(range->hmm_pfns[0]) +
				PAGE_SHIFT;
		args->p.size = 1UL << args->p.page;
		args->p.addr &= ~(args->p.size - 1);
		page -= (addr - args->p.addr) >> PAGE_SHIFT;
	}
	if (is_device_private_page(page))
		args->p.phys[0] = nouveau_dmem_page_addr(page) |
				NVIF_VMM_PFNMAP_V0_V |
				NVIF_VMM_PFNMAP_V0_VRAM;
	else
		args->p.phys[0] = page_to_phys(page) |
				NVIF_VMM_PFNMAP_V0_V |
				NVIF_VMM_PFNMAP_V0_HOST;
	if (range->hmm_pfns[0] & HMM_PFN_WRITE)
		args->p.phys[0] |= NVIF_VMM_PFNMAP_V0_W;
}

static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm,
			       struct nouveau_drm *drm,
			       struct nouveau_pfnmap_args *args, u32 size,
			       struct svm_notifier *notifier)
{
	unsigned long timeout =
		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
	struct mm_struct *mm = svmm->notifier.mm;
	struct page *page;
	unsigned long start = args->p.addr;
	unsigned long notifier_seq;
	int ret = 0;

	ret = mmu_interval_notifier_insert(&notifier->notifier, mm,
					args->p.addr, args->p.size,
					&nouveau_svm_mni_ops);
	if (ret)
		return ret;

	while (true) {
		if (time_after(jiffies, timeout)) {
			ret = -EBUSY;
			goto out;
		}

		notifier_seq = mmu_interval_read_begin(&notifier->notifier);
		mmap_read_lock(mm);
		ret = make_device_exclusive_range(mm, start, start + PAGE_SIZE,
					    &page, drm->dev);
		mmap_read_unlock(mm);
		if (ret <= 0 || !page) {
			ret = -EINVAL;
			goto out;
		}

		mutex_lock(&svmm->mutex);
		if (!mmu_interval_read_retry(&notifier->notifier,
					     notifier_seq))
			break;
		mutex_unlock(&svmm->mutex);
	}

	/* Map the page on the GPU. */
	args->p.page = 12;
	args->p.size = PAGE_SIZE;
	args->p.addr = start;
	args->p.phys[0] = page_to_phys(page) |
		NVIF_VMM_PFNMAP_V0_V |
		NVIF_VMM_PFNMAP_V0_W |
		NVIF_VMM_PFNMAP_V0_A |
		NVIF_VMM_PFNMAP_V0_HOST;

	ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL);
	mutex_unlock(&svmm->mutex);

	unlock_page(page);
	put_page(page);

out:
	mmu_interval_notifier_remove(&notifier->notifier);
	return ret;
}

static int nouveau_range_fault(struct nouveau_svmm *svmm,
			       struct nouveau_drm *drm,
			       struct nouveau_pfnmap_args *args, u32 size,
			       unsigned long hmm_flags,
			       struct svm_notifier *notifier)
{
	unsigned long timeout =
		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
	/* Have HMM fault pages within the fault window to the GPU. */
	unsigned long hmm_pfns[1];
	struct hmm_range range = {
		.notifier = &notifier->notifier,
		.default_flags = hmm_flags,
		.hmm_pfns = hmm_pfns,
		.dev_private_owner = drm->dev,
	};
	struct mm_struct *mm = svmm->notifier.mm;
	int ret;

	ret = mmu_interval_notifier_insert(&notifier->notifier, mm,
					args->p.addr, args->p.size,
					&nouveau_svm_mni_ops);
	if (ret)
		return ret;

	range.start = notifier->notifier.interval_tree.start;
	range.end = notifier->notifier.interval_tree.last + 1;

	while (true) {
		if (time_after(jiffies, timeout)) {
			ret = -EBUSY;
			goto out;
		}

		range.notifier_seq = mmu_interval_read_begin(range.notifier);
		mmap_read_lock(mm);
		ret = hmm_range_fault(&range);
		mmap_read_unlock(mm);
		if (ret) {
			if (ret == -EBUSY)
				continue;
			goto out;
		}

		mutex_lock(&svmm->mutex);
		if (mmu_interval_read_retry(range.notifier,
					    range.notifier_seq)) {
			mutex_unlock(&svmm->mutex);
			continue;
		}
		break;
	}

	nouveau_hmm_convert_pfn(drm, &range, args);

	ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL);
	mutex_unlock(&svmm->mutex);

out:
	mmu_interval_notifier_remove(&notifier->notifier);

	return ret;
}

static void
nouveau_svm_fault(struct work_struct *work)
{
	struct nouveau_svm_fault_buffer *buffer = container_of(work, typeof(*buffer), work);
	struct nouveau_svm *svm = container_of(buffer, typeof(*svm), buffer[buffer->id]);
	struct nvif_object *device = &svm->drm->client.device.object;
	struct nouveau_svmm *svmm;
	struct {
		struct nouveau_pfnmap_args i;
		u64 phys[1];
	} args;
	unsigned long hmm_flags;
	u64 inst, start, limit;
	int fi, fn;
	int replay = 0, atomic = 0, ret;

	/* Parse available fault buffer entries into a cache, and update
	 * the GET pointer so HW can reuse the entries.
	 */
	SVM_DBG(svm, "fault handler");
	if (buffer->get == buffer->put) {
		buffer->put = nvif_rd32(device, buffer->putaddr);
		buffer->get = nvif_rd32(device, buffer->getaddr);
		if (buffer->get == buffer->put)
			return;
	}
	buffer->fault_nr = 0;

	SVM_DBG(svm, "get %08x put %08x", buffer->get, buffer->put);
	while (buffer->get != buffer->put) {
		nouveau_svm_fault_cache(svm, buffer, buffer->get * 0x20);
		if (++buffer->get == buffer->entries)
			buffer->get = 0;
	}
	nvif_wr32(device, buffer->getaddr, buffer->get);
	SVM_DBG(svm, "%d fault(s) pending", buffer->fault_nr);

	/* Sort parsed faults by instance pointer to prevent unnecessary
	 * instance to SVMM translations, followed by address and access
	 * type to reduce the amount of work when handling the faults.
	 */
	sort(buffer->fault, buffer->fault_nr, sizeof(*buffer->fault),
	     nouveau_svm_fault_cmp, NULL);

	/* Lookup SVMM structure for each unique instance pointer. */
	mutex_lock(&svm->mutex);
	for (fi = 0, svmm = NULL; fi < buffer->fault_nr; fi++) {
		if (!svmm || buffer->fault[fi]->inst != inst) {
			struct nouveau_ivmm *ivmm =
				nouveau_ivmm_find(svm, buffer->fault[fi]->inst);
			svmm = ivmm ? ivmm->svmm : NULL;
			inst = buffer->fault[fi]->inst;
			SVM_DBG(svm, "inst %016llx -> svm-%p", inst, svmm);
		}
		buffer->fault[fi]->svmm = svmm;
	}
	mutex_unlock(&svm->mutex);

	/* Process list of faults. */
	args.i.i.version = 0;
	args.i.i.type = NVIF_IOCTL_V0_MTHD;
	args.i.m.version = 0;
	args.i.m.method = NVIF_VMM_V0_PFNMAP;
	args.i.p.version = 0;

	for (fi = 0; fn = fi + 1, fi < buffer->fault_nr; fi = fn) {
		struct svm_notifier notifier;
		struct mm_struct *mm;

		/* Cancel any faults from non-SVM channels. */
		if (!(svmm = buffer->fault[fi]->svmm)) {
			nouveau_svm_fault_cancel_fault(svm, buffer->fault[fi]);
			continue;
		}
		SVMM_DBG(svmm, "addr %016llx", buffer->fault[fi]->addr);

		/* We try and group handling of faults within a small
		 * window into a single update.
		 */
		start = buffer->fault[fi]->addr;
		limit = start + PAGE_SIZE;
		if (start < svmm->unmanaged.limit)
			limit = min_t(u64, limit, svmm->unmanaged.start);

		/*
		 * Prepare the GPU-side update of all pages within the
		 * fault window, determining required pages and access
		 * permissions based on pending faults.
		 */
		args.i.p.addr = start;
		args.i.p.page = PAGE_SHIFT;
		args.i.p.size = PAGE_SIZE;
		/*
		 * Determine required permissions based on GPU fault
		 * access flags.
		 */
		switch (buffer->fault[fi]->access) {
		case 0: /* READ. */
			hmm_flags = HMM_PFN_REQ_FAULT;
			break;
		case 2: /* ATOMIC. */
			atomic = true;
			break;
		case 3: /* PREFETCH. */
			hmm_flags = 0;
			break;
		default:
			hmm_flags = HMM_PFN_REQ_FAULT | HMM_PFN_REQ_WRITE;
			break;
		}

		mm = svmm->notifier.mm;
		if (!mmget_not_zero(mm)) {
			nouveau_svm_fault_cancel_fault(svm, buffer->fault[fi]);
			continue;
		}

		notifier.svmm = svmm;
		if (atomic)
			ret = nouveau_atomic_range_fault(svmm, svm->drm,
							 &args.i, sizeof(args),
							 &notifier);
		else
			ret = nouveau_range_fault(svmm, svm->drm, &args.i,
						  sizeof(args), hmm_flags,
						  &notifier);
		mmput(mm);

		limit = args.i.p.addr + args.i.p.size;
		for (fn = fi; ++fn < buffer->fault_nr; ) {
			/* It's okay to skip over duplicate addresses from the
			 * same SVMM as faults are ordered by access type such
			 * that only the first one needs to be handled.
			 *
			 * ie. WRITE faults appear first, thus any handling of
			 * pending READ faults will already be satisfied.
			 * But if a large page is mapped, make sure subsequent
			 * fault addresses have sufficient access permission.
			 */
			if (buffer->fault[fn]->svmm != svmm ||
			    buffer->fault[fn]->addr >= limit ||
			    (buffer->fault[fi]->access == FAULT_ACCESS_READ &&
			     !(args.phys[0] & NVIF_VMM_PFNMAP_V0_V)) ||
			    (buffer->fault[fi]->access != FAULT_ACCESS_READ &&
			     buffer->fault[fi]->access != FAULT_ACCESS_PREFETCH &&
			     !(args.phys[0] & NVIF_VMM_PFNMAP_V0_W)) ||
			    (buffer->fault[fi]->access != FAULT_ACCESS_READ &&
			     buffer->fault[fi]->access != FAULT_ACCESS_WRITE &&
			     buffer->fault[fi]->access != FAULT_ACCESS_PREFETCH &&
			     !(args.phys[0] & NVIF_VMM_PFNMAP_V0_A)))
				break;
		}

		/* If handling failed completely, cancel all faults. */
		if (ret) {
			while (fi < fn) {
				struct nouveau_svm_fault *fault =
					buffer->fault[fi++];

				nouveau_svm_fault_cancel_fault(svm, fault);
			}
		} else
			replay++;
	}

	/* Issue fault replay to the GPU. */
	if (replay)
		nouveau_svm_fault_replay(svm);
}

static int
nouveau_svm_event(struct nvif_event *event, void *argv, u32 argc)
{
	struct nouveau_svm_fault_buffer *buffer = container_of(event, typeof(*buffer), notify);

	schedule_work(&buffer->work);
	return NVIF_EVENT_KEEP;
}

static struct nouveau_pfnmap_args *
nouveau_pfns_to_args(void *pfns)
{
	return container_of(pfns, struct nouveau_pfnmap_args, p.phys);
}

u64 *
nouveau_pfns_alloc(unsigned long npages)
{
	struct nouveau_pfnmap_args *args;

	args = kzalloc(struct_size(args, p.phys, npages), GFP_KERNEL);
	if (!args)
		return NULL;

	args->i.type = NVIF_IOCTL_V0_MTHD;
	args->m.method = NVIF_VMM_V0_PFNMAP;
	args->p.page = PAGE_SHIFT;

	return args->p.phys;
}

void
nouveau_pfns_free(u64 *pfns)
{
	struct nouveau_pfnmap_args *args = nouveau_pfns_to_args(pfns);

	kfree(args);
}

void
nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm,
		 unsigned long addr, u64 *pfns, unsigned long npages)
{
	struct nouveau_pfnmap_args *args = nouveau_pfns_to_args(pfns);
	int ret;

	args->p.addr = addr;
	args->p.size = npages << PAGE_SHIFT;

	mutex_lock(&svmm->mutex);

	ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args,
				struct_size(args, p.phys, npages), NULL);

	mutex_unlock(&svmm->mutex);
}

static void
nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id)
{
	struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];

	nvif_event_block(&buffer->notify);
	flush_work(&buffer->work);
}

static int
nouveau_svm_fault_buffer_init(struct nouveau_svm *svm, int id)
{
	struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
	struct nvif_object *device = &svm->drm->client.device.object;

	buffer->get = nvif_rd32(device, buffer->getaddr);
	buffer->put = nvif_rd32(device, buffer->putaddr);
	SVM_DBG(svm, "get %08x put %08x (init)", buffer->get, buffer->put);

	return nvif_event_allow(&buffer->notify);
}

static void
nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id)
{
	struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
	int i;

	if (!nvif_object_constructed(&buffer->object))
		return;

	nouveau_svm_fault_buffer_fini(svm, id);

	if (buffer->fault) {
		for (i = 0; buffer->fault[i] && i < buffer->entries; i++)
			kfree(buffer->fault[i]);
		kvfree(buffer->fault);
	}

	nvif_event_dtor(&buffer->notify);
	nvif_object_dtor(&buffer->object);
}

static int
nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
{
	struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
	struct nouveau_drm *drm = svm->drm;
	struct nvif_object *device = &drm->client.device.object;
	struct nvif_clb069_v0 args = {};
	int ret;

	buffer->id = id;

	ret = nvif_object_ctor(device, "svmFaultBuffer", 0, oclass, &args,
			       sizeof(args), &buffer->object);
	if (ret < 0) {
		SVM_ERR(svm, "Fault buffer allocation failed: %d", ret);
		return ret;
	}

	nvif_object_map(&buffer->object, NULL, 0);
	buffer->entries = args.entries;
	buffer->getaddr = args.get;
	buffer->putaddr = args.put;
	INIT_WORK(&buffer->work, nouveau_svm_fault);

	ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
			      &buffer->notify);
	if (ret)
		return ret;

	buffer->fault = kvcalloc(sizeof(*buffer->fault), buffer->entries, GFP_KERNEL);
	if (!buffer->fault)
		return -ENOMEM;

	return nouveau_svm_fault_buffer_init(svm, id);
}

void
nouveau_svm_resume(struct nouveau_drm *drm)
{
	struct nouveau_svm *svm = drm->svm;
	if (svm)
		nouveau_svm_fault_buffer_init(svm, 0);
}

void
nouveau_svm_suspend(struct nouveau_drm *drm)
{
	struct nouveau_svm *svm = drm->svm;
	if (svm)
		nouveau_svm_fault_buffer_fini(svm, 0);
}

void
nouveau_svm_fini(struct nouveau_drm *drm)
{
	struct nouveau_svm *svm = drm->svm;
	if (svm) {
		nouveau_svm_fault_buffer_dtor(svm, 0);
		kfree(drm->svm);
		drm->svm = NULL;
	}
}

void
nouveau_svm_init(struct nouveau_drm *drm)
{
	static const struct nvif_mclass buffers[] = {
		{   VOLTA_FAULT_BUFFER_A, 0 },
		{ MAXWELL_FAULT_BUFFER_A, 0 },
		{}
	};
	struct nouveau_svm *svm;
	int ret;

	/* Disable on Volta and newer until channel recovery is fixed,
	 * otherwise clients will have a trivial way to trash the GPU
	 * for everyone.
	 */
	if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL)
		return;

	if (!(drm->svm = svm = kzalloc(sizeof(*drm->svm), GFP_KERNEL)))
		return;

	drm->svm->drm = drm;
	mutex_init(&drm->svm->mutex);
	INIT_LIST_HEAD(&drm->svm->inst);

	ret = nvif_mclass(&drm->client.device.object, buffers);
	if (ret < 0) {
		SVM_DBG(svm, "No supported fault buffer class");
		nouveau_svm_fini(drm);
		return;
	}

	ret = nouveau_svm_fault_buffer_ctor(svm, buffers[ret].oclass, 0);
	if (ret) {
		nouveau_svm_fini(drm);
		return;
	}

	SVM_DBG(svm, "Initialised");
}
