// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2016 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 */

#include "drm/drm_file.h"
#include "drm/msm_drm.h"
#include "linux/file.h"
#include "linux/sync_file.h"

#include "msm_drv.h"
#include "msm_gem.h"
#include "msm_gpu.h"
#include "msm_mmu.h"
#include "msm_syncobj.h"

#define vm_dbg(fmt, ...) pr_debug("%s:%d: "fmt"\n", __func__, __LINE__, ##__VA_ARGS__)

static uint vm_log_shift = 0;
MODULE_PARM_DESC(vm_log_shift, "Length of VM op log");
module_param_named(vm_log_shift, vm_log_shift, uint, 0600);

/**
 * struct msm_vm_map_op - create new pgtable mapping
 */
struct msm_vm_map_op {
	/** @iova: start address for mapping */
	uint64_t iova;
	/** @range: size of the region to map */
	uint64_t range;
	/** @offset: offset into @sgt to map */
	uint64_t offset;
	/** @sgt: pages to map, or NULL for a PRR mapping */
	struct sg_table *sgt;
	/** @prot: the mapping protection flags */
	int prot;

	/**
	 * @queue_id: The id of the submitqueue the operation is performed
	 * on, or zero for (in particular) UNMAP ops triggered outside of
	 * a submitqueue (ie. process cleanup)
	 */
	int queue_id;
};

/**
 * struct msm_vm_unmap_op - unmap a range of pages from pgtable
 */
struct msm_vm_unmap_op {
	/** @iova: start address for unmap */
	uint64_t iova;
	/** @range: size of region to unmap */
	uint64_t range;

	/** @reason: The reason for the unmap */
	const char *reason;

	/**
	 * @queue_id: The id of the submitqueue the operation is performed
	 * on, or zero for (in particular) UNMAP ops triggered outside of
	 * a submitqueue (ie. process cleanup)
	 */
	int queue_id;
};

/**
 * struct msm_vma_op - A MAP or UNMAP operation
 */
struct msm_vm_op {
	/** @op: The operation type */
	enum {
		MSM_VM_OP_MAP = 1,
		MSM_VM_OP_UNMAP,
	} op;
	union {
		/** @map: Parameters used if op == MSM_VMA_OP_MAP */
		struct msm_vm_map_op map;
		/** @unmap: Parameters used if op == MSM_VMA_OP_UNMAP */
		struct msm_vm_unmap_op unmap;
	};
	/** @node: list head in msm_vm_bind_job::vm_ops */
	struct list_head node;

	/**
	 * @obj: backing object for pages to be mapped/unmapped
	 *
	 * Async unmap ops, in particular, must hold a reference to the
	 * original GEM object backing the mapping that will be unmapped.
	 * But the same can be required in the map path, for example if
	 * there is not a corresponding unmap op, such as process exit.
	 *
	 * This ensures that the pages backing the mapping are not freed
	 * before the mapping is torn down.
	 */
	struct drm_gem_object *obj;
};

/**
 * struct msm_vm_bind_job - Tracking for a VM_BIND ioctl
 *
 * A table of userspace requested VM updates (MSM_VM_BIND_OP_UNMAP/MAP/MAP_NULL)
 * gets applied to the vm, generating a list of VM ops (MSM_VM_OP_MAP/UNMAP)
 * which are applied to the pgtables asynchronously.  For example a userspace
 * requested MSM_VM_BIND_OP_MAP could end up generating both an MSM_VM_OP_UNMAP
 * to unmap an existing mapping, and a MSM_VM_OP_MAP to apply the new mapping.
 */
struct msm_vm_bind_job {
	/** @base: base class for drm_sched jobs */
	struct drm_sched_job base;
	/** @vm: The VM being operated on */
	struct drm_gpuvm *vm;
	/** @fence: The fence that is signaled when job completes */
	struct dma_fence *fence;
	/** @queue: The queue that the job runs on */
	struct msm_gpu_submitqueue *queue;
	/** @prealloc: Tracking for pre-allocated MMU pgtable pages */
	struct msm_mmu_prealloc prealloc;
	/** @vm_ops: a list of struct msm_vm_op */
	struct list_head vm_ops;
	/** @bos_pinned: are the GEM objects being bound pinned? */
	bool bos_pinned;
	/** @nr_ops: the number of userspace requested ops */
	unsigned int nr_ops;
	/**
	 * @ops: the userspace requested ops
	 *
	 * The userspace requested ops are copied/parsed and validated
	 * before we start applying the updates to try to do as much up-
	 * front error checking as possible, to avoid the VM being in an
	 * undefined state due to partially executed VM_BIND.
	 *
	 * This table also serves to hold a reference to the backing GEM
	 * objects.
	 */
	struct msm_vm_bind_op {
		uint32_t op;
		uint32_t flags;
		union {
			struct drm_gem_object *obj;
			uint32_t handle;
		};
		uint64_t obj_offset;
		uint64_t iova;
		uint64_t range;
	} ops[];
};

#define job_foreach_bo(obj, _job) \
	for (unsigned i = 0; i < (_job)->nr_ops; i++) \
		if ((obj = (_job)->ops[i].obj))

static inline struct msm_vm_bind_job *to_msm_vm_bind_job(struct drm_sched_job *job)
{
	return container_of(job, struct msm_vm_bind_job, base);
}

static void
msm_gem_vm_free(struct drm_gpuvm *gpuvm)
{
	struct msm_gem_vm *vm = container_of(gpuvm, struct msm_gem_vm, base);

	drm_mm_takedown(&vm->mm);
	if (vm->mmu)
		vm->mmu->funcs->destroy(vm->mmu);
	dma_fence_put(vm->last_fence);
	put_pid(vm->pid);
	kfree(vm->log);
	kfree(vm);
}

/**
 * msm_gem_vm_unusable() - Mark a VM as unusable
 * @gpuvm: the VM to mark unusable
 */
void
msm_gem_vm_unusable(struct drm_gpuvm *gpuvm)
{
	struct msm_gem_vm *vm = to_msm_vm(gpuvm);
	uint32_t vm_log_len = (1 << vm->log_shift);
	uint32_t vm_log_mask = vm_log_len - 1;
	uint32_t nr_vm_logs;
	int first;

	vm->unusable = true;

	/* Bail if no log, or empty log: */
	if (!vm->log || !vm->log[0].op)
		return;

	mutex_lock(&vm->mmu_lock);

	/*
	 * log_idx is the next entry to overwrite, meaning it is the oldest, or
	 * first, entry (other than the special case handled below where the
	 * log hasn't wrapped around yet)
	 */
	first = vm->log_idx;

	if (!vm->log[first].op) {
		/*
		 * If the next log entry has not been written yet, then only
		 * entries 0 to idx-1 are valid (ie. we haven't wrapped around
		 * yet)
		 */
		nr_vm_logs = MAX(0, first - 1);
		first = 0;
	} else {
		nr_vm_logs = vm_log_len;
	}

	pr_err("vm-log:\n");
	for (int i = 0; i < nr_vm_logs; i++) {
		int idx = (i + first) & vm_log_mask;
		struct msm_gem_vm_log_entry *e = &vm->log[idx];
		pr_err("  - %s:%d: 0x%016llx-0x%016llx\n",
		       e->op, e->queue_id, e->iova,
		       e->iova + e->range);
	}

	mutex_unlock(&vm->mmu_lock);
}

static void
vm_log(struct msm_gem_vm *vm, const char *op, uint64_t iova, uint64_t range, int queue_id)
{
	int idx;

	if (!vm->managed)
		lockdep_assert_held(&vm->mmu_lock);

	vm_dbg("%s:%p:%d: %016llx %016llx", op, vm, queue_id, iova, iova + range);

	if (!vm->log)
		return;

	idx = vm->log_idx;
	vm->log[idx].op = op;
	vm->log[idx].iova = iova;
	vm->log[idx].range = range;
	vm->log[idx].queue_id = queue_id;
	vm->log_idx = (vm->log_idx + 1) & ((1 << vm->log_shift) - 1);
}

static void
vm_unmap_op(struct msm_gem_vm *vm, const struct msm_vm_unmap_op *op)
{
	const char *reason = op->reason;

	if (!reason)
		reason = "unmap";

	vm_log(vm, reason, op->iova, op->range, op->queue_id);

	vm->mmu->funcs->unmap(vm->mmu, op->iova, op->range);
}

static int
vm_map_op(struct msm_gem_vm *vm, const struct msm_vm_map_op *op)
{
	vm_log(vm, "map", op->iova, op->range, op->queue_id);

	return vm->mmu->funcs->map(vm->mmu, op->iova, op->sgt, op->offset,
				   op->range, op->prot);
}

/* Actually unmap memory for the vma */
void msm_gem_vma_unmap(struct drm_gpuva *vma, const char *reason)
{
	struct msm_gem_vm *vm = to_msm_vm(vma->vm);
	struct msm_gem_vma *msm_vma = to_msm_vma(vma);

	/* Don't do anything if the memory isn't mapped */
	if (!msm_vma->mapped)
		return;

	/*
	 * The mmu_lock is only needed when preallocation is used.  But
	 * in that case we don't need to worry about recursion into
	 * shrinker
	 */
	if (!vm->managed)
		 mutex_lock(&vm->mmu_lock);

	vm_unmap_op(vm, &(struct msm_vm_unmap_op){
		.iova = vma->va.addr,
		.range = vma->va.range,
		.reason = reason,
	});

	if (!vm->managed)
		mutex_unlock(&vm->mmu_lock);

	msm_vma->mapped = false;
}

/* Map and pin vma: */
int
msm_gem_vma_map(struct drm_gpuva *vma, int prot, struct sg_table *sgt)
{
	struct msm_gem_vm *vm = to_msm_vm(vma->vm);
	struct msm_gem_vma *msm_vma = to_msm_vma(vma);
	int ret;

	if (GEM_WARN_ON(!vma->va.addr))
		return -EINVAL;

	if (msm_vma->mapped)
		return 0;

	msm_vma->mapped = true;

	/*
	 * The mmu_lock is only needed when preallocation is used.  But
	 * in that case we don't need to worry about recursion into
	 * shrinker
	 */
	if (!vm->managed)
		mutex_lock(&vm->mmu_lock);

	/*
	 * NOTE: iommu/io-pgtable can allocate pages, so we cannot hold
	 * a lock across map/unmap which is also used in the job_run()
	 * path, as this can cause deadlock in job_run() vs shrinker/
	 * reclaim.
	 *
	 * Revisit this if we can come up with a scheme to pre-alloc pages
	 * for the pgtable in map/unmap ops.
	 */
	ret = vm_map_op(vm, &(struct msm_vm_map_op){
		.iova = vma->va.addr,
		.range = vma->va.range,
		.offset = vma->gem.offset,
		.sgt = sgt,
		.prot = prot,
	});

	if (!vm->managed)
		mutex_unlock(&vm->mmu_lock);

	if (ret)
		msm_vma->mapped = false;

	return ret;
}

/* Close an iova.  Warn if it is still in use */
void msm_gem_vma_close(struct drm_gpuva *vma)
{
	struct msm_gem_vm *vm = to_msm_vm(vma->vm);
	struct msm_gem_vma *msm_vma = to_msm_vma(vma);

	GEM_WARN_ON(msm_vma->mapped);

	drm_gpuvm_resv_assert_held(&vm->base);

	if (vma->gem.obj)
		msm_gem_assert_locked(vma->gem.obj);

	if (vma->va.addr && vm->managed)
		drm_mm_remove_node(&msm_vma->node);

	drm_gpuva_remove(vma);
	drm_gpuva_unlink(vma);

	kfree(vma);
}

/* Create a new vma and allocate an iova for it */
struct drm_gpuva *
msm_gem_vma_new(struct drm_gpuvm *gpuvm, struct drm_gem_object *obj,
		u64 offset, u64 range_start, u64 range_end)
{
	struct msm_gem_vm *vm = to_msm_vm(gpuvm);
	struct drm_gpuvm_bo *vm_bo;
	struct msm_gem_vma *vma;
	int ret;

	drm_gpuvm_resv_assert_held(&vm->base);

	vma = kzalloc(sizeof(*vma), GFP_KERNEL);
	if (!vma)
		return ERR_PTR(-ENOMEM);

	if (vm->managed) {
		BUG_ON(offset != 0);
		BUG_ON(!obj);  /* NULL mappings not valid for kernel managed VM */
		ret = drm_mm_insert_node_in_range(&vm->mm, &vma->node,
						obj->size, PAGE_SIZE, 0,
						range_start, range_end, 0);

		if (ret)
			goto err_free_vma;

		range_start = vma->node.start;
		range_end   = range_start + obj->size;
	}

	if (obj)
		GEM_WARN_ON((range_end - range_start) > obj->size);

	drm_gpuva_init(&vma->base, range_start, range_end - range_start, obj, offset);
	vma->mapped = false;

	ret = drm_gpuva_insert(&vm->base, &vma->base);
	if (ret)
		goto err_free_range;

	if (!obj)
		return &vma->base;

	vm_bo = drm_gpuvm_bo_obtain(&vm->base, obj);
	if (IS_ERR(vm_bo)) {
		ret = PTR_ERR(vm_bo);
		goto err_va_remove;
	}

	drm_gpuvm_bo_extobj_add(vm_bo);
	drm_gpuva_link(&vma->base, vm_bo);
	GEM_WARN_ON(drm_gpuvm_bo_put(vm_bo));

	return &vma->base;

err_va_remove:
	drm_gpuva_remove(&vma->base);
err_free_range:
	if (vm->managed)
		drm_mm_remove_node(&vma->node);
err_free_vma:
	kfree(vma);
	return ERR_PTR(ret);
}

static int
msm_gem_vm_bo_validate(struct drm_gpuvm_bo *vm_bo, struct drm_exec *exec)
{
	struct drm_gem_object *obj = vm_bo->obj;
	struct drm_gpuva *vma;
	int ret;

	vm_dbg("validate: %p", obj);

	msm_gem_assert_locked(obj);

	drm_gpuvm_bo_for_each_va (vma, vm_bo) {
		ret = msm_gem_pin_vma_locked(obj, vma);
		if (ret)
			return ret;
	}

	return 0;
}

struct op_arg {
	unsigned flags;
	struct msm_vm_bind_job *job;
};

static void
vm_op_enqueue(struct op_arg *arg, struct msm_vm_op _op)
{
	struct msm_vm_op *op = kmalloc(sizeof(*op), GFP_KERNEL);
	*op = _op;
	list_add_tail(&op->node, &arg->job->vm_ops);

	if (op->obj)
		drm_gem_object_get(op->obj);
}

static struct drm_gpuva *
vma_from_op(struct op_arg *arg, struct drm_gpuva_op_map *op)
{
	return msm_gem_vma_new(arg->job->vm, op->gem.obj, op->gem.offset,
			       op->va.addr, op->va.addr + op->va.range);
}

static int
msm_gem_vm_sm_step_map(struct drm_gpuva_op *op, void *arg)
{
	struct msm_vm_bind_job *job = ((struct op_arg *)arg)->job;
	struct drm_gem_object *obj = op->map.gem.obj;
	struct drm_gpuva *vma;
	struct sg_table *sgt;
	unsigned prot;

	vma = vma_from_op(arg, &op->map);
	if (WARN_ON(IS_ERR(vma)))
		return PTR_ERR(vma);

	vm_dbg("%p:%p:%p: %016llx %016llx", vma->vm, vma, vma->gem.obj,
	       vma->va.addr, vma->va.range);

	vma->flags = ((struct op_arg *)arg)->flags;

	if (obj) {
		sgt = to_msm_bo(obj)->sgt;
		prot = msm_gem_prot(obj);
	} else {
		sgt = NULL;
		prot = IOMMU_READ | IOMMU_WRITE;
	}

	vm_op_enqueue(arg, (struct msm_vm_op){
		.op = MSM_VM_OP_MAP,
		.map = {
			.sgt = sgt,
			.iova = vma->va.addr,
			.range = vma->va.range,
			.offset = vma->gem.offset,
			.prot = prot,
			.queue_id = job->queue->id,
		},
		.obj = vma->gem.obj,
	});

	to_msm_vma(vma)->mapped = true;

	return 0;
}

static int
msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void *arg)
{
	struct msm_vm_bind_job *job = ((struct op_arg *)arg)->job;
	struct drm_gpuvm *vm = job->vm;
	struct drm_gpuva *orig_vma = op->remap.unmap->va;
	struct drm_gpuva *prev_vma = NULL, *next_vma = NULL;
	struct drm_gpuvm_bo *vm_bo = orig_vma->vm_bo;
	bool mapped = to_msm_vma(orig_vma)->mapped;
	unsigned flags;

	vm_dbg("orig_vma: %p:%p:%p: %016llx %016llx", vm, orig_vma,
	       orig_vma->gem.obj, orig_vma->va.addr, orig_vma->va.range);

	if (mapped) {
		uint64_t unmap_start, unmap_range;

		drm_gpuva_op_remap_to_unmap_range(&op->remap, &unmap_start, &unmap_range);

		vm_op_enqueue(arg, (struct msm_vm_op){
			.op = MSM_VM_OP_UNMAP,
			.unmap = {
				.iova = unmap_start,
				.range = unmap_range,
				.queue_id = job->queue->id,
			},
			.obj = orig_vma->gem.obj,
		});

		/*
		 * Part of this GEM obj is still mapped, but we're going to kill the
		 * existing VMA and replace it with one or two new ones (ie. two if
		 * the unmapped range is in the middle of the existing (unmap) VMA).
		 * So just set the state to unmapped:
		 */
		to_msm_vma(orig_vma)->mapped = false;
	}

	/*
	 * Hold a ref to the vm_bo between the msm_gem_vma_close() and the
	 * creation of the new prev/next vma's, in case the vm_bo is tracked
	 * in the VM's evict list:
	 */
	if (vm_bo)
		drm_gpuvm_bo_get(vm_bo);

	/*
	 * The prev_vma and/or next_vma are replacing the unmapped vma, and
	 * therefore should preserve it's flags:
	 */
	flags = orig_vma->flags;

	msm_gem_vma_close(orig_vma);

	if (op->remap.prev) {
		prev_vma = vma_from_op(arg, op->remap.prev);
		if (WARN_ON(IS_ERR(prev_vma)))
			return PTR_ERR(prev_vma);

		vm_dbg("prev_vma: %p:%p: %016llx %016llx", vm, prev_vma, prev_vma->va.addr, prev_vma->va.range);
		to_msm_vma(prev_vma)->mapped = mapped;
		prev_vma->flags = flags;
	}

	if (op->remap.next) {
		next_vma = vma_from_op(arg, op->remap.next);
		if (WARN_ON(IS_ERR(next_vma)))
			return PTR_ERR(next_vma);

		vm_dbg("next_vma: %p:%p: %016llx %016llx", vm, next_vma, next_vma->va.addr, next_vma->va.range);
		to_msm_vma(next_vma)->mapped = mapped;
		next_vma->flags = flags;
	}

	if (!mapped)
		drm_gpuvm_bo_evict(vm_bo, true);

	/* Drop the previous ref: */
	drm_gpuvm_bo_put(vm_bo);

	return 0;
}

static int
msm_gem_vm_sm_step_unmap(struct drm_gpuva_op *op, void *arg)
{
	struct msm_vm_bind_job *job = ((struct op_arg *)arg)->job;
	struct drm_gpuva *vma = op->unmap.va;
	struct msm_gem_vma *msm_vma = to_msm_vma(vma);

	vm_dbg("%p:%p:%p: %016llx %016llx", vma->vm, vma, vma->gem.obj,
	       vma->va.addr, vma->va.range);

	if (!msm_vma->mapped)
		goto out_close;

	vm_op_enqueue(arg, (struct msm_vm_op){
		.op = MSM_VM_OP_UNMAP,
		.unmap = {
			.iova = vma->va.addr,
			.range = vma->va.range,
			.queue_id = job->queue->id,
		},
		.obj = vma->gem.obj,
	});

	msm_vma->mapped = false;

out_close:
	msm_gem_vma_close(vma);

	return 0;
}

static const struct drm_gpuvm_ops msm_gpuvm_ops = {
	.vm_free = msm_gem_vm_free,
	.vm_bo_validate = msm_gem_vm_bo_validate,
	.sm_step_map = msm_gem_vm_sm_step_map,
	.sm_step_remap = msm_gem_vm_sm_step_remap,
	.sm_step_unmap = msm_gem_vm_sm_step_unmap,
};

static struct dma_fence *
msm_vma_job_run(struct drm_sched_job *_job)
{
	struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
	struct msm_gem_vm *vm = to_msm_vm(job->vm);
	struct drm_gem_object *obj;
	int ret = vm->unusable ? -EINVAL : 0;

	vm_dbg("");

	mutex_lock(&vm->mmu_lock);
	vm->mmu->prealloc = &job->prealloc;

	while (!list_empty(&job->vm_ops)) {
		struct msm_vm_op *op =
			list_first_entry(&job->vm_ops, struct msm_vm_op, node);

		switch (op->op) {
		case MSM_VM_OP_MAP:
			/*
			 * On error, stop trying to map new things.. but we
			 * still want to process the unmaps (or in particular,
			 * the drm_gem_object_put()s)
			 */
			if (!ret)
				ret = vm_map_op(vm, &op->map);
			break;
		case MSM_VM_OP_UNMAP:
			vm_unmap_op(vm, &op->unmap);
			break;
		}
		drm_gem_object_put(op->obj);
		list_del(&op->node);
		kfree(op);
	}

	vm->mmu->prealloc = NULL;
	mutex_unlock(&vm->mmu_lock);

	/*
	 * We failed to perform at least _some_ of the pgtable updates, so
	 * now the VM is in an undefined state.  Game over!
	 */
	if (ret)
		msm_gem_vm_unusable(job->vm);

	job_foreach_bo (obj, job) {
		msm_gem_lock(obj);
		msm_gem_unpin_locked(obj);
		msm_gem_unlock(obj);
	}

	/* VM_BIND ops are synchronous, so no fence to wait on: */
	return NULL;
}

static void
msm_vma_job_free(struct drm_sched_job *_job)
{
	struct msm_vm_bind_job *job = to_msm_vm_bind_job(_job);
	struct msm_gem_vm *vm = to_msm_vm(job->vm);
	struct drm_gem_object *obj;

	vm->mmu->funcs->prealloc_cleanup(vm->mmu, &job->prealloc);

	atomic_sub(job->prealloc.count, &vm->prealloc_throttle.in_flight);

	drm_sched_job_cleanup(_job);

	job_foreach_bo (obj, job)
		drm_gem_object_put(obj);

	msm_submitqueue_put(job->queue);
	dma_fence_put(job->fence);

	/* In error paths, we could have unexecuted ops: */
	while (!list_empty(&job->vm_ops)) {
		struct msm_vm_op *op =
			list_first_entry(&job->vm_ops, struct msm_vm_op, node);
		list_del(&op->node);
		kfree(op);
	}

	wake_up(&vm->prealloc_throttle.wait);

	kfree(job);
}

static const struct drm_sched_backend_ops msm_vm_bind_ops = {
	.run_job = msm_vma_job_run,
	.free_job = msm_vma_job_free
};

/**
 * msm_gem_vm_create() - Create and initialize a &msm_gem_vm
 * @drm: the drm device
 * @mmu: the backing MMU objects handling mapping/unmapping
 * @name: the name of the VM
 * @va_start: the start offset of the VA space
 * @va_size: the size of the VA space
 * @managed: is it a kernel managed VM?
 *
 * In a kernel managed VM, the kernel handles address allocation, and only
 * synchronous operations are supported.  In a user managed VM, userspace
 * handles virtual address allocation, and both async and sync operations
 * are supported.
 */
struct drm_gpuvm *
msm_gem_vm_create(struct drm_device *drm, struct msm_mmu *mmu, const char *name,
		  u64 va_start, u64 va_size, bool managed)
{
	/*
	 * We mostly want to use DRM_GPUVM_RESV_PROTECTED, except that
	 * makes drm_gpuvm_bo_evict() a no-op for extobjs (ie. we loose
	 * tracking that an extobj is evicted) :facepalm:
	 */
	enum drm_gpuvm_flags flags = 0;
	struct msm_gem_vm *vm;
	struct drm_gem_object *dummy_gem;
	int ret = 0;

	if (IS_ERR(mmu))
		return ERR_CAST(mmu);

	vm = kzalloc(sizeof(*vm), GFP_KERNEL);
	if (!vm)
		return ERR_PTR(-ENOMEM);

	dummy_gem = drm_gpuvm_resv_object_alloc(drm);
	if (!dummy_gem) {
		ret = -ENOMEM;
		goto err_free_vm;
	}

	if (!managed) {
		struct drm_sched_init_args args = {
			.ops = &msm_vm_bind_ops,
			.num_rqs = 1,
			.credit_limit = 1,
			.timeout = MAX_SCHEDULE_TIMEOUT,
			.name = "msm-vm-bind",
			.dev = drm->dev,
		};

		ret = drm_sched_init(&vm->sched, &args);
		if (ret)
			goto err_free_dummy;

		init_waitqueue_head(&vm->prealloc_throttle.wait);
	}

	drm_gpuvm_init(&vm->base, name, flags, drm, dummy_gem,
		       va_start, va_size, 0, 0, &msm_gpuvm_ops);
	drm_gem_object_put(dummy_gem);

	vm->mmu = mmu;
	mutex_init(&vm->mmu_lock);
	vm->managed = managed;

	drm_mm_init(&vm->mm, va_start, va_size);

	/*
	 * We don't really need vm log for kernel managed VMs, as the kernel
	 * is responsible for ensuring that GEM objs are mapped if they are
	 * used by a submit.  Furthermore we piggyback on mmu_lock to serialize
	 * access to the log.
	 *
	 * Limit the max log_shift to 8 to prevent userspace from asking us
	 * for an unreasonable log size.
	 */
	if (!managed)
		vm->log_shift = MIN(vm_log_shift, 8);

	if (vm->log_shift) {
		vm->log = kmalloc_array(1 << vm->log_shift, sizeof(vm->log[0]),
					GFP_KERNEL | __GFP_ZERO);
	}

	return &vm->base;

err_free_dummy:
	drm_gem_object_put(dummy_gem);

err_free_vm:
	kfree(vm);
	return ERR_PTR(ret);
}

/**
 * msm_gem_vm_close() - Close a VM
 * @gpuvm: The VM to close
 *
 * Called when the drm device file is closed, to tear down VM related resources
 * (which will drop refcounts to GEM objects that were still mapped into the
 * VM at the time).
 */
void
msm_gem_vm_close(struct drm_gpuvm *gpuvm)
{
	struct msm_gem_vm *vm = to_msm_vm(gpuvm);
	struct drm_gpuva *vma, *tmp;
	struct drm_exec exec;

	/*
	 * For kernel managed VMs, the VMAs are torn down when the handle is
	 * closed, so nothing more to do.
	 */
	if (vm->managed)
		return;

	if (vm->last_fence)
		dma_fence_wait(vm->last_fence, false);

	/* Kill the scheduler now, so we aren't racing with it for cleanup: */
	drm_sched_stop(&vm->sched, NULL);
	drm_sched_fini(&vm->sched);

	/* Tear down any remaining mappings: */
	drm_exec_init(&exec, 0, 2);
	drm_exec_until_all_locked (&exec) {
		drm_exec_lock_obj(&exec, drm_gpuvm_resv_obj(gpuvm));
		drm_exec_retry_on_contention(&exec);

		drm_gpuvm_for_each_va_safe (vma, tmp, gpuvm) {
			struct drm_gem_object *obj = vma->gem.obj;

			/*
			 * MSM_BO_NO_SHARE objects share the same resv as the
			 * VM, in which case the obj is already locked:
			 */
			if (obj && (obj->resv == drm_gpuvm_resv(gpuvm)))
				obj = NULL;

			if (obj) {
				drm_exec_lock_obj(&exec, obj);
				drm_exec_retry_on_contention(&exec);
			}

			msm_gem_vma_unmap(vma, "close");
			msm_gem_vma_close(vma);

			if (obj) {
				drm_exec_unlock_obj(&exec, obj);
			}
		}
	}
	drm_exec_fini(&exec);
}


static struct msm_vm_bind_job *
vm_bind_job_create(struct drm_device *dev, struct drm_file *file,
		   struct msm_gpu_submitqueue *queue, uint32_t nr_ops)
{
	struct msm_vm_bind_job *job;
	uint64_t sz;
	int ret;

	sz = struct_size(job, ops, nr_ops);

	if (sz > SIZE_MAX)
		return ERR_PTR(-ENOMEM);

	job = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
	if (!job)
		return ERR_PTR(-ENOMEM);

	ret = drm_sched_job_init(&job->base, queue->entity, 1, queue,
				 file->client_id);
	if (ret) {
		kfree(job);
		return ERR_PTR(ret);
	}

	job->vm = msm_context_vm(dev, queue->ctx);
	job->queue = queue;
	INIT_LIST_HEAD(&job->vm_ops);

	return job;
}

static bool invalid_alignment(uint64_t addr)
{
	/*
	 * Technically this is about GPU alignment, not CPU alignment.  But
	 * I've not seen any qcom SoC where the SMMU does not support the
	 * CPU's smallest page size.
	 */
	return !PAGE_ALIGNED(addr);
}

static int
lookup_op(struct msm_vm_bind_job *job, const struct drm_msm_vm_bind_op *op)
{
	struct drm_device *dev = job->vm->drm;
	int i = job->nr_ops++;
	int ret = 0;

	job->ops[i].op = op->op;
	job->ops[i].handle = op->handle;
	job->ops[i].obj_offset = op->obj_offset;
	job->ops[i].iova = op->iova;
	job->ops[i].range = op->range;
	job->ops[i].flags = op->flags;

	if (op->flags & ~MSM_VM_BIND_OP_FLAGS)
		ret = UERR(EINVAL, dev, "invalid flags: %x\n", op->flags);

	if (invalid_alignment(op->iova))
		ret = UERR(EINVAL, dev, "invalid address: %016llx\n", op->iova);

	if (invalid_alignment(op->obj_offset))
		ret = UERR(EINVAL, dev, "invalid bo_offset: %016llx\n", op->obj_offset);

	if (invalid_alignment(op->range))
		ret = UERR(EINVAL, dev, "invalid range: %016llx\n", op->range);

	if (!drm_gpuvm_range_valid(job->vm, op->iova, op->range))
		ret = UERR(EINVAL, dev, "invalid range: %016llx, %016llx\n", op->iova, op->range);

	/*
	 * MAP must specify a valid handle.  But the handle MBZ for
	 * UNMAP or MAP_NULL.
	 */
	if (op->op == MSM_VM_BIND_OP_MAP) {
		if (!op->handle)
			ret = UERR(EINVAL, dev, "invalid handle\n");
	} else if (op->handle) {
		ret = UERR(EINVAL, dev, "handle must be zero\n");
	}

	switch (op->op) {
	case MSM_VM_BIND_OP_MAP:
	case MSM_VM_BIND_OP_MAP_NULL:
	case MSM_VM_BIND_OP_UNMAP:
		break;
	default:
		ret = UERR(EINVAL, dev, "invalid op: %u\n", op->op);
		break;
	}

	return ret;
}

/*
 * ioctl parsing, parameter validation, and GEM handle lookup
 */
static int
vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, struct drm_msm_vm_bind *args,
		       struct drm_file *file, int *nr_bos)
{
	struct drm_device *dev = job->vm->drm;
	int ret = 0;
	int cnt = 0;

	if (args->nr_ops == 1) {
		/* Single op case, the op is inlined: */
		ret = lookup_op(job, &args->op);
	} else {
		for (unsigned i = 0; i < args->nr_ops; i++) {
			struct drm_msm_vm_bind_op op;
			void __user *userptr =
				u64_to_user_ptr(args->ops + (i * sizeof(op)));

			/* make sure we don't have garbage flags, in case we hit
			 * error path before flags is initialized:
			 */
			job->ops[i].flags = 0;

			if (copy_from_user(&op, userptr, sizeof(op))) {
				ret = -EFAULT;
				break;
			}

			ret = lookup_op(job, &op);
			if (ret)
				break;
		}
	}

	if (ret) {
		job->nr_ops = 0;
		goto out;
	}

	spin_lock(&file->table_lock);

	for (unsigned i = 0; i < args->nr_ops; i++) {
		struct drm_gem_object *obj;

		if (!job->ops[i].handle) {
			job->ops[i].obj = NULL;
			continue;
		}

		/*
		 * normally use drm_gem_object_lookup(), but for bulk lookup
		 * all under single table_lock just hit object_idr directly:
		 */
		obj = idr_find(&file->object_idr, job->ops[i].handle);
		if (!obj) {
			ret = UERR(EINVAL, dev, "invalid handle %u at index %u\n", job->ops[i].handle, i);
			goto out_unlock;
		}

		drm_gem_object_get(obj);

		job->ops[i].obj = obj;
		cnt++;
	}

	*nr_bos = cnt;

out_unlock:
	spin_unlock(&file->table_lock);

out:
	return ret;
}

static void
prealloc_count(struct msm_vm_bind_job *job,
	       struct msm_vm_bind_op *first,
	       struct msm_vm_bind_op *last)
{
	struct msm_mmu *mmu = to_msm_vm(job->vm)->mmu;

	if (!first)
		return;

	uint64_t start_iova = first->iova;
	uint64_t end_iova = last->iova + last->range;

	mmu->funcs->prealloc_count(mmu, &job->prealloc, start_iova, end_iova - start_iova);
}

static bool
ops_are_same_pte(struct msm_vm_bind_op *first, struct msm_vm_bind_op *next)
{
	/*
	 * Last level pte covers 2MB.. so we should merge two ops, from
	 * the PoV of figuring out how much pgtable pages to pre-allocate
	 * if they land in the same 2MB range:
	 */
	uint64_t pte_mask = ~(SZ_2M - 1);
	return ((first->iova + first->range) & pte_mask) == (next->iova & pte_mask);
}

/*
 * Determine the amount of memory to prealloc for pgtables.  For sparse images,
 * in particular, userspace plays some tricks with the order of page mappings
 * to get the desired swizzle pattern, resulting in a large # of tiny MAP ops.
 * So detect when multiple MAP operations are physically contiguous, and count
 * them as a single mapping.  Otherwise the prealloc_count() will not realize
 * they can share pagetable pages and vastly overcount.
 */
static int
vm_bind_prealloc_count(struct msm_vm_bind_job *job)
{
	struct msm_vm_bind_op *first = NULL, *last = NULL;
	struct msm_gem_vm *vm = to_msm_vm(job->vm);
	int ret;

	for (int i = 0; i < job->nr_ops; i++) {
		struct msm_vm_bind_op *op = &job->ops[i];

		/* We only care about MAP/MAP_NULL: */
		if (op->op == MSM_VM_BIND_OP_UNMAP)
			continue;

		/*
		 * If op is contiguous with last in the current range, then
		 * it becomes the new last in the range and we continue
		 * looping:
		 */
		if (last && ops_are_same_pte(last, op)) {
			last = op;
			continue;
		}

		/*
		 * If op is not contiguous with the current range, flush
		 * the current range and start anew:
		 */
		prealloc_count(job, first, last);
		first = last = op;
	}

	/* Flush the remaining range: */
	prealloc_count(job, first, last);

	/*
	 * Now that we know the needed amount to pre-alloc, throttle on pending
	 * VM_BIND jobs if we already have too much pre-alloc memory in flight
	 */
	ret = wait_event_interruptible(
			vm->prealloc_throttle.wait,
			atomic_read(&vm->prealloc_throttle.in_flight) <= 1024);
	if (ret)
		return ret;

	atomic_add(job->prealloc.count, &vm->prealloc_throttle.in_flight);

	return 0;
}

/*
 * Lock VM and GEM objects
 */
static int
vm_bind_job_lock_objects(struct msm_vm_bind_job *job, struct drm_exec *exec)
{
	int ret;

	/* Lock VM and objects: */
	drm_exec_until_all_locked (exec) {
		ret = drm_exec_lock_obj(exec, drm_gpuvm_resv_obj(job->vm));
		drm_exec_retry_on_contention(exec);
		if (ret)
			return ret;

		for (unsigned i = 0; i < job->nr_ops; i++) {
			const struct msm_vm_bind_op *op = &job->ops[i];

			switch (op->op) {
			case MSM_VM_BIND_OP_UNMAP:
				ret = drm_gpuvm_sm_unmap_exec_lock(job->vm, exec,
							      op->iova,
							      op->obj_offset);
				break;
			case MSM_VM_BIND_OP_MAP:
			case MSM_VM_BIND_OP_MAP_NULL:
				ret = drm_gpuvm_sm_map_exec_lock(job->vm, exec, 1,
							    op->iova, op->range,
							    op->obj, op->obj_offset);
				break;
			default:
				/*
				 * lookup_op() should have already thrown an error for
				 * invalid ops
				 */
				WARN_ON("unreachable");
			}

			drm_exec_retry_on_contention(exec);
			if (ret)
				return ret;
		}
	}

	return 0;
}

/*
 * Pin GEM objects, ensuring that we have backing pages.  Pinning will move
 * the object to the pinned LRU so that the shrinker knows to first consider
 * other objects for evicting.
 */
static int
vm_bind_job_pin_objects(struct msm_vm_bind_job *job)
{
	struct drm_gem_object *obj;

	/*
	 * First loop, before holding the LRU lock, avoids holding the
	 * LRU lock while calling msm_gem_pin_vma_locked (which could
	 * trigger get_pages())
	 */
	job_foreach_bo (obj, job) {
		struct page **pages;

		pages = msm_gem_get_pages_locked(obj, MSM_MADV_WILLNEED);
		if (IS_ERR(pages))
			return PTR_ERR(pages);
	}

	struct msm_drm_private *priv = job->vm->drm->dev_private;

	/*
	 * A second loop while holding the LRU lock (a) avoids acquiring/dropping
	 * the LRU lock for each individual bo, while (b) avoiding holding the
	 * LRU lock while calling msm_gem_pin_vma_locked() (which could trigger
	 * get_pages() which could trigger reclaim.. and if we held the LRU lock
	 * could trigger deadlock with the shrinker).
	 */
	mutex_lock(&priv->lru.lock);
	job_foreach_bo (obj, job)
		msm_gem_pin_obj_locked(obj);
	mutex_unlock(&priv->lru.lock);

	job->bos_pinned = true;

	return 0;
}

/*
 * Unpin GEM objects.  Normally this is done after the bind job is run.
 */
static void
vm_bind_job_unpin_objects(struct msm_vm_bind_job *job)
{
	struct drm_gem_object *obj;

	if (!job->bos_pinned)
		return;

	job_foreach_bo (obj, job)
		msm_gem_unpin_locked(obj);

	job->bos_pinned = false;
}

/*
 * Pre-allocate pgtable memory, and translate the VM bind requests into a
 * sequence of pgtable updates to be applied asynchronously.
 */
static int
vm_bind_job_prepare(struct msm_vm_bind_job *job)
{
	struct msm_gem_vm *vm = to_msm_vm(job->vm);
	struct msm_mmu *mmu = vm->mmu;
	int ret;

	ret = mmu->funcs->prealloc_allocate(mmu, &job->prealloc);
	if (ret)
		return ret;

	for (unsigned i = 0; i < job->nr_ops; i++) {
		const struct msm_vm_bind_op *op = &job->ops[i];
		struct op_arg arg = {
			.job = job,
		};

		switch (op->op) {
		case MSM_VM_BIND_OP_UNMAP:
			ret = drm_gpuvm_sm_unmap(job->vm, &arg, op->iova,
						 op->range);
			break;
		case MSM_VM_BIND_OP_MAP:
			if (op->flags & MSM_VM_BIND_OP_DUMP)
				arg.flags |= MSM_VMA_DUMP;
			fallthrough;
		case MSM_VM_BIND_OP_MAP_NULL:
			ret = drm_gpuvm_sm_map(job->vm, &arg, op->iova,
					       op->range, op->obj, op->obj_offset);
			break;
		default:
			/*
			 * lookup_op() should have already thrown an error for
			 * invalid ops
			 */
			BUG_ON("unreachable");
		}

		if (ret) {
			/*
			 * If we've already started modifying the vm, we can't
			 * adequetly describe to userspace the intermediate
			 * state the vm is in.  So throw up our hands!
			 */
			if (i > 0)
				msm_gem_vm_unusable(job->vm);
			return ret;
		}
	}

	return 0;
}

/*
 * Attach fences to the GEM objects being bound.  This will signify to
 * the shrinker that they are busy even after dropping the locks (ie.
 * drm_exec_fini())
 */
static void
vm_bind_job_attach_fences(struct msm_vm_bind_job *job)
{
	for (unsigned i = 0; i < job->nr_ops; i++) {
		struct drm_gem_object *obj = job->ops[i].obj;

		if (!obj)
			continue;

		dma_resv_add_fence(obj->resv, job->fence,
				   DMA_RESV_USAGE_KERNEL);
	}
}

int
msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct msm_drm_private *priv = dev->dev_private;
	struct drm_msm_vm_bind *args = data;
	struct msm_context *ctx = file->driver_priv;
	struct msm_vm_bind_job *job = NULL;
	struct msm_gpu *gpu = priv->gpu;
	struct msm_gpu_submitqueue *queue;
	struct msm_syncobj_post_dep *post_deps = NULL;
	struct drm_syncobj **syncobjs_to_reset = NULL;
	struct sync_file *sync_file = NULL;
	struct dma_fence *fence;
	int out_fence_fd = -1;
	int ret, nr_bos = 0;
	unsigned i;

	if (!gpu)
		return -ENXIO;

	/*
	 * Maybe we could allow just UNMAP ops?  OTOH userspace should just
	 * immediately close the device file and all will be torn down.
	 */
	if (to_msm_vm(ctx->vm)->unusable)
		return UERR(EPIPE, dev, "context is unusable");

	/*
	 * Technically, you cannot create a VM_BIND submitqueue in the first
	 * place, if you haven't opted in to VM_BIND context.  But it is
	 * cleaner / less confusing, to check this case directly.
	 */
	if (!msm_context_is_vmbind(ctx))
		return UERR(EINVAL, dev, "context does not support vmbind");

	if (args->flags & ~MSM_VM_BIND_FLAGS)
		return UERR(EINVAL, dev, "invalid flags");

	queue = msm_submitqueue_get(ctx, args->queue_id);
	if (!queue)
		return -ENOENT;

	if (!(queue->flags & MSM_SUBMITQUEUE_VM_BIND)) {
		ret = UERR(EINVAL, dev, "Invalid queue type");
		goto out_post_unlock;
	}

	if (args->flags & MSM_VM_BIND_FENCE_FD_OUT) {
		out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
		if (out_fence_fd < 0) {
			ret = out_fence_fd;
			goto out_post_unlock;
		}
	}

	job = vm_bind_job_create(dev, file, queue, args->nr_ops);
	if (IS_ERR(job)) {
		ret = PTR_ERR(job);
		goto out_post_unlock;
	}

	ret = mutex_lock_interruptible(&queue->lock);
	if (ret)
		goto out_post_unlock;

	if (args->flags & MSM_VM_BIND_FENCE_FD_IN) {
		struct dma_fence *in_fence;

		in_fence = sync_file_get_fence(args->fence_fd);

		if (!in_fence) {
			ret = UERR(EINVAL, dev, "invalid in-fence");
			goto out_unlock;
		}

		ret = drm_sched_job_add_dependency(&job->base, in_fence);
		if (ret)
			goto out_unlock;
	}

	if (args->in_syncobjs > 0) {
		syncobjs_to_reset = msm_syncobj_parse_deps(dev, &job->base,
							   file, args->in_syncobjs,
							   args->nr_in_syncobjs,
							   args->syncobj_stride);
		if (IS_ERR(syncobjs_to_reset)) {
			ret = PTR_ERR(syncobjs_to_reset);
			goto out_unlock;
		}
	}

	if (args->out_syncobjs > 0) {
		post_deps = msm_syncobj_parse_post_deps(dev, file,
							args->out_syncobjs,
							args->nr_out_syncobjs,
							args->syncobj_stride);
		if (IS_ERR(post_deps)) {
			ret = PTR_ERR(post_deps);
			goto out_unlock;
		}
	}

	ret = vm_bind_job_lookup_ops(job, args, file, &nr_bos);
	if (ret)
		goto out_unlock;

	ret = vm_bind_prealloc_count(job);
	if (ret)
		goto out_unlock;

	struct drm_exec exec;
	unsigned flags = DRM_EXEC_IGNORE_DUPLICATES | DRM_EXEC_INTERRUPTIBLE_WAIT;
	drm_exec_init(&exec, flags, nr_bos + 1);

	ret = vm_bind_job_lock_objects(job, &exec);
	if (ret)
		goto out;

	ret = vm_bind_job_pin_objects(job);
	if (ret)
		goto out;

	ret = vm_bind_job_prepare(job);
	if (ret)
		goto out;

	drm_sched_job_arm(&job->base);

	job->fence = dma_fence_get(&job->base.s_fence->finished);

	if (args->flags & MSM_VM_BIND_FENCE_FD_OUT) {
		sync_file = sync_file_create(job->fence);
		if (!sync_file) {
			ret = -ENOMEM;
		} else {
			fd_install(out_fence_fd, sync_file->file);
			args->fence_fd = out_fence_fd;
		}
	}

	if (ret)
		goto out;

	vm_bind_job_attach_fences(job);

	/*
	 * The job can be free'd (and fence unref'd) at any point after
	 * drm_sched_entity_push_job(), so we need to hold our own ref
	 */
	fence = dma_fence_get(job->fence);

	drm_sched_entity_push_job(&job->base);

	msm_syncobj_reset(syncobjs_to_reset, args->nr_in_syncobjs);
	msm_syncobj_process_post_deps(post_deps, args->nr_out_syncobjs, fence);

	dma_fence_put(fence);

out:
	if (ret)
		vm_bind_job_unpin_objects(job);

	drm_exec_fini(&exec);
out_unlock:
	mutex_unlock(&queue->lock);
out_post_unlock:
	if (ret && (out_fence_fd >= 0)) {
		put_unused_fd(out_fence_fd);
		if (sync_file)
			fput(sync_file->file);
	}

	if (!IS_ERR_OR_NULL(job)) {
		if (ret)
			msm_vma_job_free(&job->base);
	} else {
		/*
		 * If the submit hasn't yet taken ownership of the queue
		 * then we need to drop the reference ourself:
		 */
		msm_submitqueue_put(queue);
	}

	if (!IS_ERR_OR_NULL(post_deps)) {
		for (i = 0; i < args->nr_out_syncobjs; ++i) {
			kfree(post_deps[i].chain);
			drm_syncobj_put(post_deps[i].syncobj);
		}
		kfree(post_deps);
	}

	if (!IS_ERR_OR_NULL(syncobjs_to_reset)) {
		for (i = 0; i < args->nr_in_syncobjs; ++i) {
			if (syncobjs_to_reset[i])
				drm_syncobj_put(syncobjs_to_reset[i]);
		}
		kfree(syncobjs_to_reset);
	}

	return ret;
}
