/*
 * Copyright 2014 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/bitmap.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/sched/mm.h>
#include <asm/cputable.h>
#include <asm/current.h>
#include <asm/copro.h>

#include "cxl.h"

/*
 * Allocates space for a CXL context.
 */
struct cxl_context *cxl_context_alloc(void)
{
	return kzalloc(sizeof(struct cxl_context), GFP_KERNEL);
}

/*
 * Initialises a CXL context.
 */
int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
{
	int i;

	ctx->afu = afu;
	ctx->master = master;
	ctx->pid = NULL; /* Set in start work ioctl */
	mutex_init(&ctx->mapping_lock);
	ctx->mapping = NULL;

	if (cxl_is_psl8(afu)) {
		spin_lock_init(&ctx->sste_lock);

		/*
		 * Allocate the segment table before we put it in the IDR so that we
		 * can always access it when dereferenced from IDR. For the same
		 * reason, the segment table is only destroyed after the context is
		 * removed from the IDR.  Access to this in the IOCTL is protected by
		 * Linux filesytem symantics (can't IOCTL until open is complete).
		 */
		i = cxl_alloc_sst(ctx);
		if (i)
			return i;
	}

	INIT_WORK(&ctx->fault_work, cxl_handle_fault);

	init_waitqueue_head(&ctx->wq);
	spin_lock_init(&ctx->lock);

	ctx->irq_bitmap = NULL;
	ctx->pending_irq = false;
	ctx->pending_fault = false;
	ctx->pending_afu_err = false;

	INIT_LIST_HEAD(&ctx->irq_names);
	INIT_LIST_HEAD(&ctx->extra_irq_contexts);

	/*
	 * When we have to destroy all contexts in cxl_context_detach_all() we
	 * end up with afu_release_irqs() called from inside a
	 * idr_for_each_entry(). Hence we need to make sure that anything
	 * dereferenced from this IDR is ok before we allocate the IDR here.
	 * This clears out the IRQ ranges to ensure this.
	 */
	for (i = 0; i < CXL_IRQ_RANGES; i++)
		ctx->irqs.range[i] = 0;

	mutex_init(&ctx->status_mutex);

	ctx->status = OPENED;

	/*
	 * Allocating IDR! We better make sure everything's setup that
	 * dereferences from it.
	 */
	mutex_lock(&afu->contexts_lock);
	idr_preload(GFP_KERNEL);
	i = idr_alloc(&ctx->afu->contexts_idr, ctx, ctx->afu->adapter->min_pe,
		      ctx->afu->num_procs, GFP_NOWAIT);
	idr_preload_end();
	mutex_unlock(&afu->contexts_lock);
	if (i < 0)
		return i;

	ctx->pe = i;
	if (cpu_has_feature(CPU_FTR_HVMODE)) {
		ctx->elem = &ctx->afu->native->spa[i];
		ctx->external_pe = ctx->pe;
	} else {
		ctx->external_pe = -1; /* assigned when attaching */
	}
	ctx->pe_inserted = false;

	/*
	 * take a ref on the afu so that it stays alive at-least till
	 * this context is reclaimed inside reclaim_ctx.
	 */
	cxl_afu_get(afu);
	return 0;
}

void cxl_context_set_mapping(struct cxl_context *ctx,
			struct address_space *mapping)
{
	mutex_lock(&ctx->mapping_lock);
	ctx->mapping = mapping;
	mutex_unlock(&ctx->mapping_lock);
}

static int cxl_mmap_fault(struct vm_fault *vmf)
{
	struct vm_area_struct *vma = vmf->vma;
	struct cxl_context *ctx = vma->vm_file->private_data;
	u64 area, offset;

	offset = vmf->pgoff << PAGE_SHIFT;

	pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n",
			__func__, ctx->pe, vmf->address, offset);

	if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
		area = ctx->afu->psn_phys;
		if (offset >= ctx->afu->adapter->ps_size)
			return VM_FAULT_SIGBUS;
	} else {
		area = ctx->psn_phys;
		if (offset >= ctx->psn_size)
			return VM_FAULT_SIGBUS;
	}

	mutex_lock(&ctx->status_mutex);

	if (ctx->status != STARTED) {
		mutex_unlock(&ctx->status_mutex);
		pr_devel("%s: Context not started, failing problem state access\n", __func__);
		if (ctx->mmio_err_ff) {
			if (!ctx->ff_page) {
				ctx->ff_page = alloc_page(GFP_USER);
				if (!ctx->ff_page)
					return VM_FAULT_OOM;
				memset(page_address(ctx->ff_page), 0xff, PAGE_SIZE);
			}
			get_page(ctx->ff_page);
			vmf->page = ctx->ff_page;
			vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
			return 0;
		}
		return VM_FAULT_SIGBUS;
	}

	vm_insert_pfn(vma, vmf->address, (area + offset) >> PAGE_SHIFT);

	mutex_unlock(&ctx->status_mutex);

	return VM_FAULT_NOPAGE;
}

static const struct vm_operations_struct cxl_mmap_vmops = {
	.fault = cxl_mmap_fault,
};

/*
 * Map a per-context mmio space into the given vma.
 */
int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
{
	u64 start = vma->vm_pgoff << PAGE_SHIFT;
	u64 len = vma->vm_end - vma->vm_start;

	if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
		if (start + len > ctx->afu->adapter->ps_size)
			return -EINVAL;

		if (cxl_is_psl9(ctx->afu)) {
			/*
			 * Make sure there is a valid problem state
			 * area space for this AFU.
			 */
			if (ctx->master && !ctx->afu->psa) {
				pr_devel("AFU doesn't support mmio space\n");
				return -EINVAL;
			}

			/* Can't mmap until the AFU is enabled */
			if (!ctx->afu->enabled)
				return -EBUSY;
		}
	} else {
		if (start + len > ctx->psn_size)
			return -EINVAL;

		/* Make sure there is a valid per process space for this AFU */
		if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {
			pr_devel("AFU doesn't support mmio space\n");
			return -EINVAL;
		}

		/* Can't mmap until the AFU is enabled */
		if (!ctx->afu->enabled)
			return -EBUSY;
	}

	pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,
		 ctx->psn_phys, ctx->pe , ctx->master);

	vma->vm_flags |= VM_IO | VM_PFNMAP;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	vma->vm_ops = &cxl_mmap_vmops;
	return 0;
}

/*
 * Detach a context from the hardware. This disables interrupts and doesn't
 * return until all outstanding interrupts for this context have completed. The
 * hardware should no longer access *ctx after this has returned.
 */
int __detach_context(struct cxl_context *ctx)
{
	enum cxl_context_status status;

	mutex_lock(&ctx->status_mutex);
	status = ctx->status;
	ctx->status = CLOSED;
	mutex_unlock(&ctx->status_mutex);
	if (status != STARTED)
		return -EBUSY;

	/* Only warn if we detached while the link was OK.
	 * If detach fails when hw is down, we don't care.
	 */
	WARN_ON(cxl_ops->detach_process(ctx) &&
		cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
	flush_work(&ctx->fault_work); /* Only needed for dedicated process */

	/*
	 * Wait until no further interrupts are presented by the PSL
	 * for this context.
	 */
	if (cxl_ops->irq_wait)
		cxl_ops->irq_wait(ctx);

	/* release the reference to the group leader and mm handling pid */
	put_pid(ctx->pid);

	cxl_ctx_put();

	/* Decrease the attached context count on the adapter */
	cxl_adapter_context_put(ctx->afu->adapter);

	/* Decrease the mm count on the context */
	cxl_context_mm_count_put(ctx);
	ctx->mm = NULL;

	return 0;
}

/*
 * Detach the given context from the AFU. This doesn't actually
 * free the context but it should stop the context running in hardware
 * (ie. prevent this context from generating any further interrupts
 * so that it can be freed).
 */
void cxl_context_detach(struct cxl_context *ctx)
{
	int rc;

	rc = __detach_context(ctx);
	if (rc)
		return;

	afu_release_irqs(ctx, ctx);
	wake_up_all(&ctx->wq);
}

/*
 * Detach all contexts on the given AFU.
 */
void cxl_context_detach_all(struct cxl_afu *afu)
{
	struct cxl_context *ctx;
	int tmp;

	mutex_lock(&afu->contexts_lock);
	idr_for_each_entry(&afu->contexts_idr, ctx, tmp) {
		/*
		 * Anything done in here needs to be setup before the IDR is
		 * created and torn down after the IDR removed
		 */
		cxl_context_detach(ctx);

		/*
		 * We are force detaching - remove any active PSA mappings so
		 * userspace cannot interfere with the card if it comes back.
		 * Easiest way to exercise this is to unbind and rebind the
		 * driver via sysfs while it is in use.
		 */
		mutex_lock(&ctx->mapping_lock);
		if (ctx->mapping)
			unmap_mapping_range(ctx->mapping, 0, 0, 1);
		mutex_unlock(&ctx->mapping_lock);
	}
	mutex_unlock(&afu->contexts_lock);
}

static void reclaim_ctx(struct rcu_head *rcu)
{
	struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu);

	if (cxl_is_psl8(ctx->afu))
		free_page((u64)ctx->sstp);
	if (ctx->ff_page)
		__free_page(ctx->ff_page);
	ctx->sstp = NULL;

	kfree(ctx->irq_bitmap);

	/* Drop ref to the afu device taken during cxl_context_init */
	cxl_afu_put(ctx->afu);

	kfree(ctx);
}

void cxl_context_free(struct cxl_context *ctx)
{
	if (ctx->kernelapi && ctx->mapping)
		cxl_release_mapping(ctx);
	mutex_lock(&ctx->afu->contexts_lock);
	idr_remove(&ctx->afu->contexts_idr, ctx->pe);
	mutex_unlock(&ctx->afu->contexts_lock);
	call_rcu(&ctx->rcu, reclaim_ctx);
}

void cxl_context_mm_count_get(struct cxl_context *ctx)
{
	if (ctx->mm)
		atomic_inc(&ctx->mm->mm_count);
}

void cxl_context_mm_count_put(struct cxl_context *ctx)
{
	if (ctx->mm)
		mmdrop(ctx->mm);
}
