// 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_mark_last_busy(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;
}
