/*
 * Copyright (c) 2005 Topspin Communications.  All rights reserved.
 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
 * Copyright (c) 2013 Cisco Systems.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * 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 AUTHORS OR COPYRIGHT HOLDERS
 * 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 <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/sched/signal.h>
#include <linux/sched/mm.h>
#include <linux/hugetlb.h>
#include <linux/iommu.h>
#include <linux/workqueue.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <rdma/ib_verbs.h>

#include "usnic_log.h"
#include "usnic_uiom.h"
#include "usnic_uiom_interval_tree.h"

static struct workqueue_struct *usnic_uiom_wq;

#define USNIC_UIOM_PAGE_CHUNK						\
	((PAGE_SIZE - offsetof(struct usnic_uiom_chunk, page_list))	/\
	((void *) &((struct usnic_uiom_chunk *) 0)->page_list[1] -	\
	(void *) &((struct usnic_uiom_chunk *) 0)->page_list[0]))

static int usnic_uiom_dma_fault(struct iommu_domain *domain,
				struct device *dev,
				unsigned long iova, int flags,
				void *token)
{
	usnic_err("Device %s iommu fault domain 0x%pK va 0x%lx flags 0x%x\n",
		dev_name(dev),
		domain, iova, flags);
	return -ENOSYS;
}

static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
{
	struct usnic_uiom_chunk *chunk, *tmp;
	struct page *page;
	struct scatterlist *sg;
	int i;
	dma_addr_t pa;

	list_for_each_entry_safe(chunk, tmp, chunk_list, list) {
		for_each_sg(chunk->page_list, sg, chunk->nents, i) {
			page = sg_page(sg);
			pa = sg_phys(sg);
			if (!PageDirty(page) && dirty)
				set_page_dirty_lock(page);
			put_page(page);
			usnic_dbg("pa: %pa\n", &pa);
		}
		kfree(chunk);
	}
}

static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
				int dmasync, struct usnic_uiom_reg *uiomr)
{
	struct list_head *chunk_list = &uiomr->chunk_list;
	struct page **page_list;
	struct scatterlist *sg;
	struct usnic_uiom_chunk *chunk;
	unsigned long locked;
	unsigned long lock_limit;
	unsigned long cur_base;
	unsigned long npages;
	int ret;
	int off;
	int i;
	int flags;
	dma_addr_t pa;
	unsigned int gup_flags;
	struct mm_struct *mm;

	/*
	 * If the combination of the addr and size requested for this memory
	 * region causes an integer overflow, return error.
	 */
	if (((addr + size) < addr) || PAGE_ALIGN(addr + size) < (addr + size))
		return -EINVAL;

	if (!size)
		return -EINVAL;

	if (!can_do_mlock())
		return -EPERM;

	INIT_LIST_HEAD(chunk_list);

	page_list = (struct page **) __get_free_page(GFP_KERNEL);
	if (!page_list)
		return -ENOMEM;

	npages = PAGE_ALIGN(size + (addr & ~PAGE_MASK)) >> PAGE_SHIFT;

	uiomr->owning_mm = mm = current->mm;
	down_write(&mm->mmap_sem);

	locked = npages + current->mm->pinned_vm;
	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;

	if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
		ret = -ENOMEM;
		goto out;
	}

	flags = IOMMU_READ | IOMMU_CACHE;
	flags |= (writable) ? IOMMU_WRITE : 0;
	gup_flags = FOLL_WRITE;
	gup_flags |= (writable) ? 0 : FOLL_FORCE;
	cur_base = addr & PAGE_MASK;
	ret = 0;

	while (npages) {
		ret = get_user_pages_longterm(cur_base,
					min_t(unsigned long, npages,
					PAGE_SIZE / sizeof(struct page *)),
					gup_flags, page_list, NULL);

		if (ret < 0)
			goto out;

		npages -= ret;
		off = 0;

		while (ret) {
			chunk = kmalloc(sizeof(*chunk) +
					sizeof(struct scatterlist) *
					min_t(int, ret, USNIC_UIOM_PAGE_CHUNK),
					GFP_KERNEL);
			if (!chunk) {
				ret = -ENOMEM;
				goto out;
			}

			chunk->nents = min_t(int, ret, USNIC_UIOM_PAGE_CHUNK);
			sg_init_table(chunk->page_list, chunk->nents);
			for_each_sg(chunk->page_list, sg, chunk->nents, i) {
				sg_set_page(sg, page_list[i + off],
						PAGE_SIZE, 0);
				pa = sg_phys(sg);
				usnic_dbg("va: 0x%lx pa: %pa\n",
						cur_base + i*PAGE_SIZE, &pa);
			}
			cur_base += chunk->nents * PAGE_SIZE;
			ret -= chunk->nents;
			off += chunk->nents;
			list_add_tail(&chunk->list, chunk_list);
		}

		ret = 0;
	}

out:
	if (ret < 0)
		usnic_uiom_put_pages(chunk_list, 0);
	else {
		mm->pinned_vm = locked;
		mmgrab(uiomr->owning_mm);
	}

	up_write(&mm->mmap_sem);
	free_page((unsigned long) page_list);
	return ret;
}

static void usnic_uiom_unmap_sorted_intervals(struct list_head *intervals,
						struct usnic_uiom_pd *pd)
{
	struct usnic_uiom_interval_node *interval, *tmp;
	long unsigned va, size;

	list_for_each_entry_safe(interval, tmp, intervals, link) {
		va = interval->start << PAGE_SHIFT;
		size = ((interval->last - interval->start) + 1) << PAGE_SHIFT;
		while (size > 0) {
			/* Workaround for RH 970401 */
			usnic_dbg("va 0x%lx size 0x%lx", va, PAGE_SIZE);
			iommu_unmap(pd->domain, va, PAGE_SIZE);
			va += PAGE_SIZE;
			size -= PAGE_SIZE;
		}
	}
}

static void __usnic_uiom_reg_release(struct usnic_uiom_pd *pd,
					struct usnic_uiom_reg *uiomr,
					int dirty)
{
	int npages;
	unsigned long vpn_start, vpn_last;
	struct usnic_uiom_interval_node *interval, *tmp;
	int writable = 0;
	LIST_HEAD(rm_intervals);

	npages = PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
	vpn_start = (uiomr->va & PAGE_MASK) >> PAGE_SHIFT;
	vpn_last = vpn_start + npages - 1;

	spin_lock(&pd->lock);
	usnic_uiom_remove_interval(&pd->root, vpn_start,
					vpn_last, &rm_intervals);
	usnic_uiom_unmap_sorted_intervals(&rm_intervals, pd);

	list_for_each_entry_safe(interval, tmp, &rm_intervals, link) {
		if (interval->flags & IOMMU_WRITE)
			writable = 1;
		list_del(&interval->link);
		kfree(interval);
	}

	usnic_uiom_put_pages(&uiomr->chunk_list, dirty & writable);
	spin_unlock(&pd->lock);
}

static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
						struct usnic_uiom_reg *uiomr)
{
	int i, err;
	size_t size;
	struct usnic_uiom_chunk *chunk;
	struct usnic_uiom_interval_node *interval_node;
	dma_addr_t pa;
	dma_addr_t pa_start = 0;
	dma_addr_t pa_end = 0;
	long int va_start = -EINVAL;
	struct usnic_uiom_pd *pd = uiomr->pd;
	long int va = uiomr->va & PAGE_MASK;
	int flags = IOMMU_READ | IOMMU_CACHE;

	flags |= (uiomr->writable) ? IOMMU_WRITE : 0;
	chunk = list_first_entry(&uiomr->chunk_list, struct usnic_uiom_chunk,
									list);
	list_for_each_entry(interval_node, intervals, link) {
iter_chunk:
		for (i = 0; i < chunk->nents; i++, va += PAGE_SIZE) {
			pa = sg_phys(&chunk->page_list[i]);
			if ((va >> PAGE_SHIFT) < interval_node->start)
				continue;

			if ((va >> PAGE_SHIFT) == interval_node->start) {
				/* First page of the interval */
				va_start = va;
				pa_start = pa;
				pa_end = pa;
			}

			WARN_ON(va_start == -EINVAL);

			if ((pa_end + PAGE_SIZE != pa) &&
					(pa != pa_start)) {
				/* PAs are not contiguous */
				size = pa_end - pa_start + PAGE_SIZE;
				usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
					va_start, &pa_start, size, flags);
				err = iommu_map(pd->domain, va_start, pa_start,
							size, flags);
				if (err) {
					usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
						va_start, &pa_start, size, err);
					goto err_out;
				}
				va_start = va;
				pa_start = pa;
				pa_end = pa;
			}

			if ((va >> PAGE_SHIFT) == interval_node->last) {
				/* Last page of the interval */
				size = pa - pa_start + PAGE_SIZE;
				usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
					va_start, &pa_start, size, flags);
				err = iommu_map(pd->domain, va_start, pa_start,
						size, flags);
				if (err) {
					usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
						va_start, &pa_start, size, err);
					goto err_out;
				}
				break;
			}

			if (pa != pa_start)
				pa_end += PAGE_SIZE;
		}

		if (i == chunk->nents) {
			/*
			 * Hit last entry of the chunk,
			 * hence advance to next chunk
			 */
			chunk = list_first_entry(&chunk->list,
							struct usnic_uiom_chunk,
							list);
			goto iter_chunk;
		}
	}

	return 0;

err_out:
	usnic_uiom_unmap_sorted_intervals(intervals, pd);
	return err;
}

struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd,
						unsigned long addr, size_t size,
						int writable, int dmasync)
{
	struct usnic_uiom_reg *uiomr;
	unsigned long va_base, vpn_start, vpn_last;
	unsigned long npages;
	int offset, err;
	LIST_HEAD(sorted_diff_intervals);

	/*
	 * Intel IOMMU map throws an error if a translation entry is
	 * changed from read to write.  This module may not unmap
	 * and then remap the entry after fixing the permission
	 * b/c this open up a small windows where hw DMA may page fault
	 * Hence, make all entries to be writable.
	 */
	writable = 1;

	va_base = addr & PAGE_MASK;
	offset = addr & ~PAGE_MASK;
	npages = PAGE_ALIGN(size + offset) >> PAGE_SHIFT;
	vpn_start = (addr & PAGE_MASK) >> PAGE_SHIFT;
	vpn_last = vpn_start + npages - 1;

	uiomr = kmalloc(sizeof(*uiomr), GFP_KERNEL);
	if (!uiomr)
		return ERR_PTR(-ENOMEM);

	uiomr->va = va_base;
	uiomr->offset = offset;
	uiomr->length = size;
	uiomr->writable = writable;
	uiomr->pd = pd;

	err = usnic_uiom_get_pages(addr, size, writable, dmasync,
				   uiomr);
	if (err) {
		usnic_err("Failed get_pages vpn [0x%lx,0x%lx] err %d\n",
				vpn_start, vpn_last, err);
		goto out_free_uiomr;
	}

	spin_lock(&pd->lock);
	err = usnic_uiom_get_intervals_diff(vpn_start, vpn_last,
						(writable) ? IOMMU_WRITE : 0,
						IOMMU_WRITE,
						&pd->root,
						&sorted_diff_intervals);
	if (err) {
		usnic_err("Failed disjoint interval vpn [0x%lx,0x%lx] err %d\n",
						vpn_start, vpn_last, err);
		goto out_put_pages;
	}

	err = usnic_uiom_map_sorted_intervals(&sorted_diff_intervals, uiomr);
	if (err) {
		usnic_err("Failed map interval vpn [0x%lx,0x%lx] err %d\n",
						vpn_start, vpn_last, err);
		goto out_put_intervals;

	}

	err = usnic_uiom_insert_interval(&pd->root, vpn_start, vpn_last,
					(writable) ? IOMMU_WRITE : 0);
	if (err) {
		usnic_err("Failed insert interval vpn [0x%lx,0x%lx] err %d\n",
						vpn_start, vpn_last, err);
		goto out_unmap_intervals;
	}

	usnic_uiom_put_interval_set(&sorted_diff_intervals);
	spin_unlock(&pd->lock);

	return uiomr;

out_unmap_intervals:
	usnic_uiom_unmap_sorted_intervals(&sorted_diff_intervals, pd);
out_put_intervals:
	usnic_uiom_put_interval_set(&sorted_diff_intervals);
out_put_pages:
	usnic_uiom_put_pages(&uiomr->chunk_list, 0);
	spin_unlock(&pd->lock);
	mmdrop(uiomr->owning_mm);
out_free_uiomr:
	kfree(uiomr);
	return ERR_PTR(err);
}

static void __usnic_uiom_release_tail(struct usnic_uiom_reg *uiomr)
{
	mmdrop(uiomr->owning_mm);
	kfree(uiomr);
}

static inline size_t usnic_uiom_num_pages(struct usnic_uiom_reg *uiomr)
{
	return PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
}

static void usnic_uiom_release_defer(struct work_struct *work)
{
	struct usnic_uiom_reg *uiomr =
		container_of(work, struct usnic_uiom_reg, work);

	down_write(&uiomr->owning_mm->mmap_sem);
	uiomr->owning_mm->pinned_vm -= usnic_uiom_num_pages(uiomr);
	up_write(&uiomr->owning_mm->mmap_sem);

	__usnic_uiom_release_tail(uiomr);
}

void usnic_uiom_reg_release(struct usnic_uiom_reg *uiomr,
			    struct ib_ucontext *context)
{
	__usnic_uiom_reg_release(uiomr->pd, uiomr, 1);

	/*
	 * We may be called with the mm's mmap_sem already held.  This
	 * can happen when a userspace munmap() is the call that drops
	 * the last reference to our file and calls our release
	 * method.  If there are memory regions to destroy, we'll end
	 * up here and not be able to take the mmap_sem.  In that case
	 * we defer the vm_locked accounting to a workqueue.
	 */
	if (context->closing) {
		if (!down_write_trylock(&uiomr->owning_mm->mmap_sem)) {
			INIT_WORK(&uiomr->work, usnic_uiom_release_defer);
			queue_work(usnic_uiom_wq, &uiomr->work);
			return;
		}
	} else {
		down_write(&uiomr->owning_mm->mmap_sem);
	}
	uiomr->owning_mm->pinned_vm -= usnic_uiom_num_pages(uiomr);
	up_write(&uiomr->owning_mm->mmap_sem);

	__usnic_uiom_release_tail(uiomr);
}

struct usnic_uiom_pd *usnic_uiom_alloc_pd(void)
{
	struct usnic_uiom_pd *pd;
	void *domain;

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

	pd->domain = domain = iommu_domain_alloc(&pci_bus_type);
	if (!domain) {
		usnic_err("Failed to allocate IOMMU domain");
		kfree(pd);
		return ERR_PTR(-ENOMEM);
	}

	iommu_set_fault_handler(pd->domain, usnic_uiom_dma_fault, NULL);

	spin_lock_init(&pd->lock);
	INIT_LIST_HEAD(&pd->devs);

	return pd;
}

void usnic_uiom_dealloc_pd(struct usnic_uiom_pd *pd)
{
	iommu_domain_free(pd->domain);
	kfree(pd);
}

int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev)
{
	struct usnic_uiom_dev *uiom_dev;
	int err;

	uiom_dev = kzalloc(sizeof(*uiom_dev), GFP_ATOMIC);
	if (!uiom_dev)
		return -ENOMEM;
	uiom_dev->dev = dev;

	err = iommu_attach_device(pd->domain, dev);
	if (err)
		goto out_free_dev;

	if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) {
		usnic_err("IOMMU of %s does not support cache coherency\n",
				dev_name(dev));
		err = -EINVAL;
		goto out_detach_device;
	}

	spin_lock(&pd->lock);
	list_add_tail(&uiom_dev->link, &pd->devs);
	pd->dev_cnt++;
	spin_unlock(&pd->lock);

	return 0;

out_detach_device:
	iommu_detach_device(pd->domain, dev);
out_free_dev:
	kfree(uiom_dev);
	return err;
}

void usnic_uiom_detach_dev_from_pd(struct usnic_uiom_pd *pd, struct device *dev)
{
	struct usnic_uiom_dev *uiom_dev;
	int found = 0;

	spin_lock(&pd->lock);
	list_for_each_entry(uiom_dev, &pd->devs, link) {
		if (uiom_dev->dev == dev) {
			found = 1;
			break;
		}
	}

	if (!found) {
		usnic_err("Unable to free dev %s - not found\n",
				dev_name(dev));
		spin_unlock(&pd->lock);
		return;
	}

	list_del(&uiom_dev->link);
	pd->dev_cnt--;
	spin_unlock(&pd->lock);

	return iommu_detach_device(pd->domain, dev);
}

struct device **usnic_uiom_get_dev_list(struct usnic_uiom_pd *pd)
{
	struct usnic_uiom_dev *uiom_dev;
	struct device **devs;
	int i = 0;

	spin_lock(&pd->lock);
	devs = kcalloc(pd->dev_cnt + 1, sizeof(*devs), GFP_ATOMIC);
	if (!devs) {
		devs = ERR_PTR(-ENOMEM);
		goto out;
	}

	list_for_each_entry(uiom_dev, &pd->devs, link) {
		devs[i++] = uiom_dev->dev;
	}
out:
	spin_unlock(&pd->lock);
	return devs;
}

void usnic_uiom_free_dev_list(struct device **devs)
{
	kfree(devs);
}

int usnic_uiom_init(char *drv_name)
{
	if (!iommu_present(&pci_bus_type)) {
		usnic_err("IOMMU required but not present or enabled.  USNIC QPs will not function w/o enabling IOMMU\n");
		return -EPERM;
	}

	usnic_uiom_wq = create_workqueue(drv_name);
	if (!usnic_uiom_wq) {
		usnic_err("Unable to alloc wq for drv %s\n", drv_name);
		return -ENOMEM;
	}

	return 0;
}

void usnic_uiom_fini(void)
{
	flush_workqueue(usnic_uiom_wq);
	destroy_workqueue(usnic_uiom_wq);
}
