// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2020 NVIDIA Corporation */

#include <linux/dma-fence-array.h>
#include <linux/dma-mapping.h>
#include <linux/file.h>
#include <linux/host1x.h>
#include <linux/iommu.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/nospec.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/sync_file.h>

#include <drm/drm_drv.h>
#include <drm/drm_file.h>
#include <drm/drm_syncobj.h>

#include "drm.h"
#include "gem.h"
#include "submit.h"
#include "uapi.h"

#define SUBMIT_ERR(context, fmt, ...) \
	dev_err_ratelimited(context->client->base.dev, \
		"%s: job submission failed: " fmt "\n", \
		current->comm, ##__VA_ARGS__)

struct gather_bo {
	struct host1x_bo base;

	struct kref ref;

	struct device *dev;
	u32 *gather_data;
	dma_addr_t gather_data_dma;
	size_t gather_data_words;
};

static struct host1x_bo *gather_bo_get(struct host1x_bo *host_bo)
{
	struct gather_bo *bo = container_of(host_bo, struct gather_bo, base);

	kref_get(&bo->ref);

	return host_bo;
}

static void gather_bo_release(struct kref *ref)
{
	struct gather_bo *bo = container_of(ref, struct gather_bo, ref);

	dma_free_attrs(bo->dev, bo->gather_data_words * 4, bo->gather_data, bo->gather_data_dma,
		       0);
	kfree(bo);
}

static void gather_bo_put(struct host1x_bo *host_bo)
{
	struct gather_bo *bo = container_of(host_bo, struct gather_bo, base);

	kref_put(&bo->ref, gather_bo_release);
}

static struct sg_table *
gather_bo_pin(struct device *dev, struct host1x_bo *host_bo, dma_addr_t *phys)
{
	struct gather_bo *bo = container_of(host_bo, struct gather_bo, base);
	struct sg_table *sgt;
	int err;

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

	err = dma_get_sgtable(bo->dev, sgt, bo->gather_data, bo->gather_data_dma,
			      bo->gather_data_words * 4);
	if (err) {
		kfree(sgt);
		return ERR_PTR(err);
	}

	return sgt;
}

static void gather_bo_unpin(struct device *dev, struct sg_table *sgt)
{
	if (sgt) {
		sg_free_table(sgt);
		kfree(sgt);
	}
}

static void *gather_bo_mmap(struct host1x_bo *host_bo)
{
	struct gather_bo *bo = container_of(host_bo, struct gather_bo, base);

	return bo->gather_data;
}

static void gather_bo_munmap(struct host1x_bo *host_bo, void *addr)
{
}

const struct host1x_bo_ops gather_bo_ops = {
	.get = gather_bo_get,
	.put = gather_bo_put,
	.pin = gather_bo_pin,
	.unpin = gather_bo_unpin,
	.mmap = gather_bo_mmap,
	.munmap = gather_bo_munmap,
};

static struct tegra_drm_mapping *
tegra_drm_mapping_get(struct tegra_drm_context *context, u32 id)
{
	struct tegra_drm_mapping *mapping;

	xa_lock(&context->mappings);

	mapping = xa_load(&context->mappings, id);
	if (mapping)
		kref_get(&mapping->ref);

	xa_unlock(&context->mappings);

	return mapping;
}

static void *alloc_copy_user_array(void __user *from, size_t count, size_t size)
{
	size_t copy_len;
	void *data;

	if (check_mul_overflow(count, size, &copy_len))
		return ERR_PTR(-EINVAL);

	if (copy_len > 0x4000)
		return ERR_PTR(-E2BIG);

	data = kvmalloc(copy_len, GFP_KERNEL);
	if (!data)
		return ERR_PTR(-ENOMEM);

	if (copy_from_user(data, from, copy_len)) {
		kvfree(data);
		return ERR_PTR(-EFAULT);
	}

	return data;
}

static int submit_copy_gather_data(struct gather_bo **pbo, struct device *dev,
				   struct tegra_drm_context *context,
				   struct drm_tegra_channel_submit *args)
{
	struct gather_bo *bo;
	size_t copy_len;

	if (args->gather_data_words == 0) {
		SUBMIT_ERR(context, "gather_data_words cannot be zero");
		return -EINVAL;
	}

	if (check_mul_overflow((size_t)args->gather_data_words, (size_t)4, &copy_len)) {
		SUBMIT_ERR(context, "gather_data_words is too large");
		return -EINVAL;
	}

	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
	if (!bo) {
		SUBMIT_ERR(context, "failed to allocate memory for bo info");
		return -ENOMEM;
	}

	host1x_bo_init(&bo->base, &gather_bo_ops);
	kref_init(&bo->ref);
	bo->dev = dev;

	bo->gather_data = dma_alloc_attrs(dev, copy_len, &bo->gather_data_dma,
					  GFP_KERNEL | __GFP_NOWARN, 0);
	if (!bo->gather_data) {
		SUBMIT_ERR(context, "failed to allocate memory for gather data");
		kfree(bo);
		return -ENOMEM;
	}

	if (copy_from_user(bo->gather_data, u64_to_user_ptr(args->gather_data_ptr), copy_len)) {
		SUBMIT_ERR(context, "failed to copy gather data from userspace");
		dma_free_attrs(dev, copy_len, bo->gather_data, bo->gather_data_dma, 0);
		kfree(bo);
		return -EFAULT;
	}

	bo->gather_data_words = args->gather_data_words;

	*pbo = bo;

	return 0;
}

static int submit_write_reloc(struct tegra_drm_context *context, struct gather_bo *bo,
			      struct drm_tegra_submit_buf *buf, struct tegra_drm_mapping *mapping)
{
	/* TODO check that target_offset is within bounds */
	dma_addr_t iova = mapping->iova + buf->reloc.target_offset;
	u32 written_ptr;

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (buf->flags & DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT)
		iova |= BIT_ULL(39);
#endif

	written_ptr = iova >> buf->reloc.shift;

	if (buf->reloc.gather_offset_words >= bo->gather_data_words) {
		SUBMIT_ERR(context,
			   "relocation has too large gather offset (%u vs gather length %zu)",
			   buf->reloc.gather_offset_words, bo->gather_data_words);
		return -EINVAL;
	}

	buf->reloc.gather_offset_words = array_index_nospec(buf->reloc.gather_offset_words,
							    bo->gather_data_words);

	bo->gather_data[buf->reloc.gather_offset_words] = written_ptr;

	return 0;
}

static int submit_process_bufs(struct tegra_drm_context *context, struct gather_bo *bo,
			       struct drm_tegra_channel_submit *args,
			       struct tegra_drm_submit_data *job_data)
{
	struct tegra_drm_used_mapping *mappings;
	struct drm_tegra_submit_buf *bufs;
	int err;
	u32 i;

	bufs = alloc_copy_user_array(u64_to_user_ptr(args->bufs_ptr), args->num_bufs,
				     sizeof(*bufs));
	if (IS_ERR(bufs)) {
		SUBMIT_ERR(context, "failed to copy bufs array from userspace");
		return PTR_ERR(bufs);
	}

	mappings = kcalloc(args->num_bufs, sizeof(*mappings), GFP_KERNEL);
	if (!mappings) {
		SUBMIT_ERR(context, "failed to allocate memory for mapping info");
		err = -ENOMEM;
		goto done;
	}

	for (i = 0; i < args->num_bufs; i++) {
		struct drm_tegra_submit_buf *buf = &bufs[i];
		struct tegra_drm_mapping *mapping;

		if (buf->flags & ~DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT) {
			SUBMIT_ERR(context, "invalid flag specified for buffer");
			err = -EINVAL;
			goto drop_refs;
		}

		mapping = tegra_drm_mapping_get(context, buf->mapping);
		if (!mapping) {
			SUBMIT_ERR(context, "invalid mapping ID '%u' for buffer", buf->mapping);
			err = -EINVAL;
			goto drop_refs;
		}

		err = submit_write_reloc(context, bo, buf, mapping);
		if (err) {
			tegra_drm_mapping_put(mapping);
			goto drop_refs;
		}

		mappings[i].mapping = mapping;
		mappings[i].flags = buf->flags;
	}

	job_data->used_mappings = mappings;
	job_data->num_used_mappings = i;

	err = 0;

	goto done;

drop_refs:
	while (i--)
		tegra_drm_mapping_put(mappings[i].mapping);

	kfree(mappings);
	job_data->used_mappings = NULL;

done:
	kvfree(bufs);

	return err;
}

static int submit_get_syncpt(struct tegra_drm_context *context, struct host1x_job *job,
			     struct xarray *syncpoints, struct drm_tegra_channel_submit *args)
{
	struct host1x_syncpt *sp;

	if (args->syncpt.flags) {
		SUBMIT_ERR(context, "invalid flag specified for syncpt");
		return -EINVAL;
	}

	/* Syncpt ref will be dropped on job release */
	sp = xa_load(syncpoints, args->syncpt.id);
	if (!sp) {
		SUBMIT_ERR(context, "syncpoint specified in syncpt was not allocated");
		return -EINVAL;
	}

	job->syncpt = host1x_syncpt_get(sp);
	job->syncpt_incrs = args->syncpt.increments;

	return 0;
}

static int submit_job_add_gather(struct host1x_job *job, struct tegra_drm_context *context,
				 struct drm_tegra_submit_cmd_gather_uptr *cmd,
				 struct gather_bo *bo, u32 *offset,
				 struct tegra_drm_submit_data *job_data,
				 u32 *class)
{
	u32 next_offset;

	if (cmd->reserved[0] || cmd->reserved[1] || cmd->reserved[2]) {
		SUBMIT_ERR(context, "non-zero reserved field in GATHER_UPTR command");
		return -EINVAL;
	}

	/* Check for maximum gather size */
	if (cmd->words > 16383) {
		SUBMIT_ERR(context, "too many words in GATHER_UPTR command");
		return -EINVAL;
	}

	if (check_add_overflow(*offset, cmd->words, &next_offset)) {
		SUBMIT_ERR(context, "too many total words in job");
		return -EINVAL;
	}

	if (next_offset > bo->gather_data_words) {
		SUBMIT_ERR(context, "GATHER_UPTR command overflows gather data");
		return -EINVAL;
	}

	if (tegra_drm_fw_validate(context->client, bo->gather_data, *offset,
				  cmd->words, job_data, class)) {
		SUBMIT_ERR(context, "job was rejected by firewall");
		return -EINVAL;
	}

	host1x_job_add_gather(job, &bo->base, cmd->words, *offset * 4);

	*offset = next_offset;

	return 0;
}

static struct host1x_job *
submit_create_job(struct tegra_drm_context *context, struct gather_bo *bo,
		  struct drm_tegra_channel_submit *args, struct tegra_drm_submit_data *job_data,
		  struct xarray *syncpoints)
{
	struct drm_tegra_submit_cmd *cmds;
	u32 i, gather_offset = 0, class;
	struct host1x_job *job;
	int err;

	/* Set initial class for firewall. */
	class = context->client->base.class;

	cmds = alloc_copy_user_array(u64_to_user_ptr(args->cmds_ptr), args->num_cmds,
				     sizeof(*cmds));
	if (IS_ERR(cmds)) {
		SUBMIT_ERR(context, "failed to copy cmds array from userspace");
		return ERR_CAST(cmds);
	}

	job = host1x_job_alloc(context->channel, args->num_cmds, 0, true);
	if (!job) {
		SUBMIT_ERR(context, "failed to allocate memory for job");
		job = ERR_PTR(-ENOMEM);
		goto done;
	}

	err = submit_get_syncpt(context, job, syncpoints, args);
	if (err < 0)
		goto free_job;

	job->client = &context->client->base;
	job->class = context->client->base.class;
	job->serialize = true;

	for (i = 0; i < args->num_cmds; i++) {
		struct drm_tegra_submit_cmd *cmd = &cmds[i];

		if (cmd->flags) {
			SUBMIT_ERR(context, "unknown flags given for cmd");
			err = -EINVAL;
			goto free_job;
		}

		if (cmd->type == DRM_TEGRA_SUBMIT_CMD_GATHER_UPTR) {
			err = submit_job_add_gather(job, context, &cmd->gather_uptr, bo,
						    &gather_offset, job_data, &class);
			if (err)
				goto free_job;
		} else if (cmd->type == DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT) {
			if (cmd->wait_syncpt.reserved[0] || cmd->wait_syncpt.reserved[1]) {
				SUBMIT_ERR(context, "non-zero reserved value");
				err = -EINVAL;
				goto free_job;
			}

			host1x_job_add_wait(job, cmd->wait_syncpt.id, cmd->wait_syncpt.value,
					    false, class);
		} else if (cmd->type == DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT_RELATIVE) {
			if (cmd->wait_syncpt.reserved[0] || cmd->wait_syncpt.reserved[1]) {
				SUBMIT_ERR(context, "non-zero reserved value");
				err = -EINVAL;
				goto free_job;
			}

			if (cmd->wait_syncpt.id != args->syncpt.id) {
				SUBMIT_ERR(context, "syncpoint ID in CMD_WAIT_SYNCPT_RELATIVE is not used by the job");
				err = -EINVAL;
				goto free_job;
			}

			host1x_job_add_wait(job, cmd->wait_syncpt.id, cmd->wait_syncpt.value,
					    true, class);
		} else {
			SUBMIT_ERR(context, "unknown cmd type");
			err = -EINVAL;
			goto free_job;
		}
	}

	if (gather_offset == 0) {
		SUBMIT_ERR(context, "job must have at least one gather");
		err = -EINVAL;
		goto free_job;
	}

	goto done;

free_job:
	host1x_job_put(job);
	job = ERR_PTR(err);

done:
	kvfree(cmds);

	return job;
}

static void release_job(struct host1x_job *job)
{
	struct tegra_drm_client *client = container_of(job->client, struct tegra_drm_client, base);
	struct tegra_drm_submit_data *job_data = job->user_data;
	u32 i;

	for (i = 0; i < job_data->num_used_mappings; i++)
		tegra_drm_mapping_put(job_data->used_mappings[i].mapping);

	kfree(job_data->used_mappings);
	kfree(job_data);

	if (pm_runtime_enabled(client->base.dev))
		pm_runtime_put_autosuspend(client->base.dev);
}

int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
				   struct drm_file *file)
{
	struct tegra_drm_file *fpriv = file->driver_priv;
	struct drm_tegra_channel_submit *args = data;
	struct tegra_drm_submit_data *job_data;
	struct drm_syncobj *syncobj = NULL;
	struct tegra_drm_context *context;
	struct host1x_job *job;
	struct gather_bo *bo;
	u32 i;
	int err;

	mutex_lock(&fpriv->lock);

	context = xa_load(&fpriv->contexts, args->context);
	if (!context) {
		mutex_unlock(&fpriv->lock);
		pr_err_ratelimited("%s: %s: invalid channel context '%#x'", __func__,
				   current->comm, args->context);
		return -EINVAL;
	}

	if (args->syncobj_in) {
		struct dma_fence *fence;

		err = drm_syncobj_find_fence(file, args->syncobj_in, 0, 0, &fence);
		if (err) {
			SUBMIT_ERR(context, "invalid syncobj_in '%#x'", args->syncobj_in);
			goto unlock;
		}

		err = dma_fence_wait_timeout(fence, true, msecs_to_jiffies(10000));
		dma_fence_put(fence);
		if (err) {
			SUBMIT_ERR(context, "wait for syncobj_in timed out");
			goto unlock;
		}
	}

	if (args->syncobj_out) {
		syncobj = drm_syncobj_find(file, args->syncobj_out);
		if (!syncobj) {
			SUBMIT_ERR(context, "invalid syncobj_out '%#x'", args->syncobj_out);
			err = -ENOENT;
			goto unlock;
		}
	}

	/* Allocate gather BO and copy gather words in. */
	err = submit_copy_gather_data(&bo, drm->dev, context, args);
	if (err)
		goto unlock;

	job_data = kzalloc(sizeof(*job_data), GFP_KERNEL);
	if (!job_data) {
		SUBMIT_ERR(context, "failed to allocate memory for job data");
		err = -ENOMEM;
		goto put_bo;
	}

	/* Get data buffer mappings and do relocation patching. */
	err = submit_process_bufs(context, bo, args, job_data);
	if (err)
		goto free_job_data;

	/* Allocate host1x_job and add gathers and waits to it. */
	job = submit_create_job(context, bo, args, job_data, &fpriv->syncpoints);
	if (IS_ERR(job)) {
		err = PTR_ERR(job);
		goto free_job_data;
	}

	/* Map gather data for Host1x. */
	err = host1x_job_pin(job, context->client->base.dev);
	if (err) {
		SUBMIT_ERR(context, "failed to pin job: %d", err);
		goto put_job;
	}

	/* Boot engine. */
	if (pm_runtime_enabled(context->client->base.dev)) {
		err = pm_runtime_resume_and_get(context->client->base.dev);
		if (err < 0) {
			SUBMIT_ERR(context, "could not power up engine: %d", err);
			goto unpin_job;
		}
	}

	job->user_data = job_data;
	job->release = release_job;
	job->timeout = 10000;

	/*
	 * job_data is now part of job reference counting, so don't release
	 * it from here.
	 */
	job_data = NULL;

	/* Submit job to hardware. */
	err = host1x_job_submit(job);
	if (err) {
		SUBMIT_ERR(context, "host1x job submission failed: %d", err);
		goto unpin_job;
	}

	/* Return postfences to userspace and add fences to DMA reservations. */
	args->syncpt.value = job->syncpt_end;

	if (syncobj) {
		struct dma_fence *fence = host1x_fence_create(job->syncpt, job->syncpt_end);
		if (IS_ERR(fence)) {
			err = PTR_ERR(fence);
			SUBMIT_ERR(context, "failed to create postfence: %d", err);
		}

		drm_syncobj_replace_fence(syncobj, fence);
	}

	goto put_job;

unpin_job:
	host1x_job_unpin(job);
put_job:
	host1x_job_put(job);
free_job_data:
	if (job_data && job_data->used_mappings) {
		for (i = 0; i < job_data->num_used_mappings; i++)
			tegra_drm_mapping_put(job_data->used_mappings[i].mapping);

		kfree(job_data->used_mappings);
	}

	if (job_data)
		kfree(job_data);
put_bo:
	gather_bo_put(&bo->base);
unlock:
	if (syncobj)
		drm_syncobj_put(syncobj);

	mutex_unlock(&fpriv->lock);
	return err;
}
