/*
 * VFIO: IOMMU DMA mapping support for TCE on POWER
 *
 * Copyright (C) 2013 IBM Corp.  All rights reserved.
 *     Author: Alexey Kardashevskiy <aik@ozlabs.ru>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Derived from original vfio_iommu_type1.c:
 * Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
 *     Author: Alex Williamson <alex.williamson@redhat.com>
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/err.h>
#include <linux/vfio.h>
#include <linux/vmalloc.h>
#include <asm/iommu.h>
#include <asm/tce.h>
#include <asm/mmu_context.h>

#define DRIVER_VERSION  "0.1"
#define DRIVER_AUTHOR   "aik@ozlabs.ru"
#define DRIVER_DESC     "VFIO IOMMU SPAPR TCE"

static void tce_iommu_detach_group(void *iommu_data,
		struct iommu_group *iommu_group);

static long try_increment_locked_vm(struct mm_struct *mm, long npages)
{
	long ret = 0, locked, lock_limit;

	if (WARN_ON_ONCE(!mm))
		return -EPERM;

	if (!npages)
		return 0;

	down_write(&mm->mmap_sem);
	locked = mm->locked_vm + npages;
	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
	if (locked > lock_limit && !capable(CAP_IPC_LOCK))
		ret = -ENOMEM;
	else
		mm->locked_vm += npages;

	pr_debug("[%d] RLIMIT_MEMLOCK +%ld %ld/%ld%s\n", current->pid,
			npages << PAGE_SHIFT,
			mm->locked_vm << PAGE_SHIFT,
			rlimit(RLIMIT_MEMLOCK),
			ret ? " - exceeded" : "");

	up_write(&mm->mmap_sem);

	return ret;
}

static void decrement_locked_vm(struct mm_struct *mm, long npages)
{
	if (!mm || !npages)
		return;

	down_write(&mm->mmap_sem);
	if (WARN_ON_ONCE(npages > mm->locked_vm))
		npages = mm->locked_vm;
	mm->locked_vm -= npages;
	pr_debug("[%d] RLIMIT_MEMLOCK -%ld %ld/%ld\n", current->pid,
			npages << PAGE_SHIFT,
			mm->locked_vm << PAGE_SHIFT,
			rlimit(RLIMIT_MEMLOCK));
	up_write(&mm->mmap_sem);
}

/*
 * VFIO IOMMU fd for SPAPR_TCE IOMMU implementation
 *
 * This code handles mapping and unmapping of user data buffers
 * into DMA'ble space using the IOMMU
 */

struct tce_iommu_group {
	struct list_head next;
	struct iommu_group *grp;
};

/*
 * A container needs to remember which preregistered region  it has
 * referenced to do proper cleanup at the userspace process exit.
 */
struct tce_iommu_prereg {
	struct list_head next;
	struct mm_iommu_table_group_mem_t *mem;
};

/*
 * The container descriptor supports only a single group per container.
 * Required by the API as the container is not supplied with the IOMMU group
 * at the moment of initialization.
 */
struct tce_container {
	struct mutex lock;
	bool enabled;
	bool v2;
	bool def_window_pending;
	unsigned long locked_pages;
	struct mm_struct *mm;
	struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES];
	struct list_head group_list;
	struct list_head prereg_list;
};

static long tce_iommu_mm_set(struct tce_container *container)
{
	if (container->mm) {
		if (container->mm == current->mm)
			return 0;
		return -EPERM;
	}
	BUG_ON(!current->mm);
	container->mm = current->mm;
	atomic_inc(&container->mm->mm_count);

	return 0;
}

static long tce_iommu_prereg_free(struct tce_container *container,
		struct tce_iommu_prereg *tcemem)
{
	long ret;

	ret = mm_iommu_put(container->mm, tcemem->mem);
	if (ret)
		return ret;

	list_del(&tcemem->next);
	kfree(tcemem);

	return 0;
}

static long tce_iommu_unregister_pages(struct tce_container *container,
		__u64 vaddr, __u64 size)
{
	struct mm_iommu_table_group_mem_t *mem;
	struct tce_iommu_prereg *tcemem;
	bool found = false;

	if ((vaddr & ~PAGE_MASK) || (size & ~PAGE_MASK))
		return -EINVAL;

	mem = mm_iommu_find(container->mm, vaddr, size >> PAGE_SHIFT);
	if (!mem)
		return -ENOENT;

	list_for_each_entry(tcemem, &container->prereg_list, next) {
		if (tcemem->mem == mem) {
			found = true;
			break;
		}
	}

	if (!found)
		return -ENOENT;

	return tce_iommu_prereg_free(container, tcemem);
}

static long tce_iommu_register_pages(struct tce_container *container,
		__u64 vaddr, __u64 size)
{
	long ret = 0;
	struct mm_iommu_table_group_mem_t *mem = NULL;
	struct tce_iommu_prereg *tcemem;
	unsigned long entries = size >> PAGE_SHIFT;

	if ((vaddr & ~PAGE_MASK) || (size & ~PAGE_MASK) ||
			((vaddr + size) < vaddr))
		return -EINVAL;

	mem = mm_iommu_find(container->mm, vaddr, entries);
	if (mem) {
		list_for_each_entry(tcemem, &container->prereg_list, next) {
			if (tcemem->mem == mem)
				return -EBUSY;
		}
	}

	ret = mm_iommu_get(container->mm, vaddr, entries, &mem);
	if (ret)
		return ret;

	tcemem = kzalloc(sizeof(*tcemem), GFP_KERNEL);
	if (!tcemem) {
		mm_iommu_put(container->mm, mem);
		return -ENOMEM;
	}

	tcemem->mem = mem;
	list_add(&tcemem->next, &container->prereg_list);

	container->enabled = true;

	return 0;
}

static long tce_iommu_userspace_view_alloc(struct iommu_table *tbl,
		struct mm_struct *mm)
{
	unsigned long cb = _ALIGN_UP(sizeof(tbl->it_userspace[0]) *
			tbl->it_size, PAGE_SIZE);
	unsigned long *uas;
	long ret;

	BUG_ON(tbl->it_userspace);

	ret = try_increment_locked_vm(mm, cb >> PAGE_SHIFT);
	if (ret)
		return ret;

	uas = vzalloc(cb);
	if (!uas) {
		decrement_locked_vm(mm, cb >> PAGE_SHIFT);
		return -ENOMEM;
	}
	tbl->it_userspace = uas;

	return 0;
}

static void tce_iommu_userspace_view_free(struct iommu_table *tbl,
		struct mm_struct *mm)
{
	unsigned long cb = _ALIGN_UP(sizeof(tbl->it_userspace[0]) *
			tbl->it_size, PAGE_SIZE);

	if (!tbl->it_userspace)
		return;

	vfree(tbl->it_userspace);
	tbl->it_userspace = NULL;
	decrement_locked_vm(mm, cb >> PAGE_SHIFT);
}

static bool tce_page_is_contained(struct page *page, unsigned page_shift)
{
	/*
	 * Check that the TCE table granularity is not bigger than the size of
	 * a page we just found. Otherwise the hardware can get access to
	 * a bigger memory chunk that it should.
	 */
	return (PAGE_SHIFT + compound_order(compound_head(page))) >= page_shift;
}

static inline bool tce_groups_attached(struct tce_container *container)
{
	return !list_empty(&container->group_list);
}

static long tce_iommu_find_table(struct tce_container *container,
		phys_addr_t ioba, struct iommu_table **ptbl)
{
	long i;

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		struct iommu_table *tbl = container->tables[i];

		if (tbl) {
			unsigned long entry = ioba >> tbl->it_page_shift;
			unsigned long start = tbl->it_offset;
			unsigned long end = start + tbl->it_size;

			if ((start <= entry) && (entry < end)) {
				*ptbl = tbl;
				return i;
			}
		}
	}

	return -1;
}

static int tce_iommu_find_free_table(struct tce_container *container)
{
	int i;

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		if (!container->tables[i])
			return i;
	}

	return -ENOSPC;
}

static int tce_iommu_enable(struct tce_container *container)
{
	int ret = 0;
	unsigned long locked;
	struct iommu_table_group *table_group;
	struct tce_iommu_group *tcegrp;

	if (container->enabled)
		return -EBUSY;

	/*
	 * When userspace pages are mapped into the IOMMU, they are effectively
	 * locked memory, so, theoretically, we need to update the accounting
	 * of locked pages on each map and unmap.  For powerpc, the map unmap
	 * paths can be very hot, though, and the accounting would kill
	 * performance, especially since it would be difficult to impossible
	 * to handle the accounting in real mode only.
	 *
	 * To address that, rather than precisely accounting every page, we
	 * instead account for a worst case on locked memory when the iommu is
	 * enabled and disabled.  The worst case upper bound on locked memory
	 * is the size of the whole iommu window, which is usually relatively
	 * small (compared to total memory sizes) on POWER hardware.
	 *
	 * Also we don't have a nice way to fail on H_PUT_TCE due to ulimits,
	 * that would effectively kill the guest at random points, much better
	 * enforcing the limit based on the max that the guest can map.
	 *
	 * Unfortunately at the moment it counts whole tables, no matter how
	 * much memory the guest has. I.e. for 4GB guest and 4 IOMMU groups
	 * each with 2GB DMA window, 8GB will be counted here. The reason for
	 * this is that we cannot tell here the amount of RAM used by the guest
	 * as this information is only available from KVM and VFIO is
	 * KVM agnostic.
	 *
	 * So we do not allow enabling a container without a group attached
	 * as there is no way to know how much we should increment
	 * the locked_vm counter.
	 */
	if (!tce_groups_attached(container))
		return -ENODEV;

	tcegrp = list_first_entry(&container->group_list,
			struct tce_iommu_group, next);
	table_group = iommu_group_get_iommudata(tcegrp->grp);
	if (!table_group)
		return -ENODEV;

	if (!table_group->tce32_size)
		return -EPERM;

	ret = tce_iommu_mm_set(container);
	if (ret)
		return ret;

	locked = table_group->tce32_size >> PAGE_SHIFT;
	ret = try_increment_locked_vm(container->mm, locked);
	if (ret)
		return ret;

	container->locked_pages = locked;

	container->enabled = true;

	return ret;
}

static void tce_iommu_disable(struct tce_container *container)
{
	if (!container->enabled)
		return;

	container->enabled = false;

	BUG_ON(!container->mm);
	decrement_locked_vm(container->mm, container->locked_pages);
}

static void *tce_iommu_open(unsigned long arg)
{
	struct tce_container *container;

	if ((arg != VFIO_SPAPR_TCE_IOMMU) && (arg != VFIO_SPAPR_TCE_v2_IOMMU)) {
		pr_err("tce_vfio: Wrong IOMMU type\n");
		return ERR_PTR(-EINVAL);
	}

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

	mutex_init(&container->lock);
	INIT_LIST_HEAD_RCU(&container->group_list);
	INIT_LIST_HEAD_RCU(&container->prereg_list);

	container->v2 = arg == VFIO_SPAPR_TCE_v2_IOMMU;

	return container;
}

static int tce_iommu_clear(struct tce_container *container,
		struct iommu_table *tbl,
		unsigned long entry, unsigned long pages);
static void tce_iommu_free_table(struct tce_container *container,
		struct iommu_table *tbl);

static void tce_iommu_release(void *iommu_data)
{
	struct tce_container *container = iommu_data;
	struct tce_iommu_group *tcegrp;
	long i;

	while (tce_groups_attached(container)) {
		tcegrp = list_first_entry(&container->group_list,
				struct tce_iommu_group, next);
		tce_iommu_detach_group(iommu_data, tcegrp->grp);
	}

	/*
	 * If VFIO created a table, it was not disposed
	 * by tce_iommu_detach_group() so do it now.
	 */
	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		struct iommu_table *tbl = container->tables[i];

		if (!tbl)
			continue;

		tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
		tce_iommu_free_table(container, tbl);
	}

	while (!list_empty(&container->prereg_list)) {
		struct tce_iommu_prereg *tcemem;

		tcemem = list_first_entry(&container->prereg_list,
				struct tce_iommu_prereg, next);
		WARN_ON_ONCE(tce_iommu_prereg_free(container, tcemem));
	}

	tce_iommu_disable(container);
	if (container->mm)
		mmdrop(container->mm);
	mutex_destroy(&container->lock);

	kfree(container);
}

static void tce_iommu_unuse_page(struct tce_container *container,
		unsigned long hpa)
{
	struct page *page;

	page = pfn_to_page(hpa >> PAGE_SHIFT);
	put_page(page);
}

static int tce_iommu_prereg_ua_to_hpa(struct tce_container *container,
		unsigned long tce, unsigned long size,
		unsigned long *phpa, struct mm_iommu_table_group_mem_t **pmem)
{
	long ret = 0;
	struct mm_iommu_table_group_mem_t *mem;

	mem = mm_iommu_lookup(container->mm, tce, size);
	if (!mem)
		return -EINVAL;

	ret = mm_iommu_ua_to_hpa(mem, tce, phpa);
	if (ret)
		return -EINVAL;

	*pmem = mem;

	return 0;
}

static void tce_iommu_unuse_page_v2(struct tce_container *container,
		struct iommu_table *tbl, unsigned long entry)
{
	struct mm_iommu_table_group_mem_t *mem = NULL;
	int ret;
	unsigned long hpa = 0;
	unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry);

	if (!pua)
		return;

	ret = tce_iommu_prereg_ua_to_hpa(container, *pua, IOMMU_PAGE_SIZE(tbl),
			&hpa, &mem);
	if (ret)
		pr_debug("%s: tce %lx at #%lx was not cached, ret=%d\n",
				__func__, *pua, entry, ret);
	if (mem)
		mm_iommu_mapped_dec(mem);

	*pua = 0;
}

static int tce_iommu_clear(struct tce_container *container,
		struct iommu_table *tbl,
		unsigned long entry, unsigned long pages)
{
	unsigned long oldhpa;
	long ret;
	enum dma_data_direction direction;

	for ( ; pages; --pages, ++entry) {
		direction = DMA_NONE;
		oldhpa = 0;
		ret = iommu_tce_xchg(tbl, entry, &oldhpa, &direction);
		if (ret)
			continue;

		if (direction == DMA_NONE)
			continue;

		if (container->v2) {
			tce_iommu_unuse_page_v2(container, tbl, entry);
			continue;
		}

		tce_iommu_unuse_page(container, oldhpa);
	}

	return 0;
}

static int tce_iommu_use_page(unsigned long tce, unsigned long *hpa)
{
	struct page *page = NULL;
	enum dma_data_direction direction = iommu_tce_direction(tce);

	if (get_user_pages_fast(tce & PAGE_MASK, 1,
			direction != DMA_TO_DEVICE, &page) != 1)
		return -EFAULT;

	*hpa = __pa((unsigned long) page_address(page));

	return 0;
}

static long tce_iommu_build(struct tce_container *container,
		struct iommu_table *tbl,
		unsigned long entry, unsigned long tce, unsigned long pages,
		enum dma_data_direction direction)
{
	long i, ret = 0;
	struct page *page;
	unsigned long hpa;
	enum dma_data_direction dirtmp;

	for (i = 0; i < pages; ++i) {
		unsigned long offset = tce & IOMMU_PAGE_MASK(tbl) & ~PAGE_MASK;

		ret = tce_iommu_use_page(tce, &hpa);
		if (ret)
			break;

		page = pfn_to_page(hpa >> PAGE_SHIFT);
		if (!tce_page_is_contained(page, tbl->it_page_shift)) {
			ret = -EPERM;
			break;
		}

		hpa |= offset;
		dirtmp = direction;
		ret = iommu_tce_xchg(tbl, entry + i, &hpa, &dirtmp);
		if (ret) {
			tce_iommu_unuse_page(container, hpa);
			pr_err("iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%ld\n",
					__func__, entry << tbl->it_page_shift,
					tce, ret);
			break;
		}

		if (dirtmp != DMA_NONE)
			tce_iommu_unuse_page(container, hpa);

		tce += IOMMU_PAGE_SIZE(tbl);
	}

	if (ret)
		tce_iommu_clear(container, tbl, entry, i);

	return ret;
}

static long tce_iommu_build_v2(struct tce_container *container,
		struct iommu_table *tbl,
		unsigned long entry, unsigned long tce, unsigned long pages,
		enum dma_data_direction direction)
{
	long i, ret = 0;
	struct page *page;
	unsigned long hpa;
	enum dma_data_direction dirtmp;

	if (!tbl->it_userspace) {
		ret = tce_iommu_userspace_view_alloc(tbl, container->mm);
		if (ret)
			return ret;
	}

	for (i = 0; i < pages; ++i) {
		struct mm_iommu_table_group_mem_t *mem = NULL;
		unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl,
				entry + i);

		ret = tce_iommu_prereg_ua_to_hpa(container,
				tce, IOMMU_PAGE_SIZE(tbl), &hpa, &mem);
		if (ret)
			break;

		page = pfn_to_page(hpa >> PAGE_SHIFT);
		if (!tce_page_is_contained(page, tbl->it_page_shift)) {
			ret = -EPERM;
			break;
		}

		/* Preserve offset within IOMMU page */
		hpa |= tce & IOMMU_PAGE_MASK(tbl) & ~PAGE_MASK;
		dirtmp = direction;

		/* The registered region is being unregistered */
		if (mm_iommu_mapped_inc(mem))
			break;

		ret = iommu_tce_xchg(tbl, entry + i, &hpa, &dirtmp);
		if (ret) {
			/* dirtmp cannot be DMA_NONE here */
			tce_iommu_unuse_page_v2(container, tbl, entry + i);
			pr_err("iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%ld\n",
					__func__, entry << tbl->it_page_shift,
					tce, ret);
			break;
		}

		if (dirtmp != DMA_NONE)
			tce_iommu_unuse_page_v2(container, tbl, entry + i);

		*pua = tce;

		tce += IOMMU_PAGE_SIZE(tbl);
	}

	if (ret)
		tce_iommu_clear(container, tbl, entry, i);

	return ret;
}

static long tce_iommu_create_table(struct tce_container *container,
			struct iommu_table_group *table_group,
			int num,
			__u32 page_shift,
			__u64 window_size,
			__u32 levels,
			struct iommu_table **ptbl)
{
	long ret, table_size;

	table_size = table_group->ops->get_table_size(page_shift, window_size,
			levels);
	if (!table_size)
		return -EINVAL;

	ret = try_increment_locked_vm(container->mm, table_size >> PAGE_SHIFT);
	if (ret)
		return ret;

	ret = table_group->ops->create_table(table_group, num,
			page_shift, window_size, levels, ptbl);

	WARN_ON(!ret && !(*ptbl)->it_ops->free);
	WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size));

	return ret;
}

static void tce_iommu_free_table(struct tce_container *container,
		struct iommu_table *tbl)
{
	unsigned long pages = tbl->it_allocated_size >> PAGE_SHIFT;

	tce_iommu_userspace_view_free(tbl, container->mm);
	tbl->it_ops->free(tbl);
	decrement_locked_vm(container->mm, pages);
}

static long tce_iommu_create_window(struct tce_container *container,
		__u32 page_shift, __u64 window_size, __u32 levels,
		__u64 *start_addr)
{
	struct tce_iommu_group *tcegrp;
	struct iommu_table_group *table_group;
	struct iommu_table *tbl = NULL;
	long ret, num;

	num = tce_iommu_find_free_table(container);
	if (num < 0)
		return num;

	/* Get the first group for ops::create_table */
	tcegrp = list_first_entry(&container->group_list,
			struct tce_iommu_group, next);
	table_group = iommu_group_get_iommudata(tcegrp->grp);
	if (!table_group)
		return -EFAULT;

	if (!(table_group->pgsizes & (1ULL << page_shift)))
		return -EINVAL;

	if (!table_group->ops->set_window || !table_group->ops->unset_window ||
			!table_group->ops->get_table_size ||
			!table_group->ops->create_table)
		return -EPERM;

	/* Create TCE table */
	ret = tce_iommu_create_table(container, table_group, num,
			page_shift, window_size, levels, &tbl);
	if (ret)
		return ret;

	BUG_ON(!tbl->it_ops->free);

	/*
	 * Program the table to every group.
	 * Groups have been tested for compatibility at the attach time.
	 */
	list_for_each_entry(tcegrp, &container->group_list, next) {
		table_group = iommu_group_get_iommudata(tcegrp->grp);

		ret = table_group->ops->set_window(table_group, num, tbl);
		if (ret)
			goto unset_exit;
	}

	container->tables[num] = tbl;

	/* Return start address assigned by platform in create_table() */
	*start_addr = tbl->it_offset << tbl->it_page_shift;

	return 0;

unset_exit:
	list_for_each_entry(tcegrp, &container->group_list, next) {
		table_group = iommu_group_get_iommudata(tcegrp->grp);
		table_group->ops->unset_window(table_group, num);
	}
	tce_iommu_free_table(container, tbl);

	return ret;
}

static long tce_iommu_remove_window(struct tce_container *container,
		__u64 start_addr)
{
	struct iommu_table_group *table_group = NULL;
	struct iommu_table *tbl;
	struct tce_iommu_group *tcegrp;
	int num;

	num = tce_iommu_find_table(container, start_addr, &tbl);
	if (num < 0)
		return -EINVAL;

	BUG_ON(!tbl->it_size);

	/* Detach groups from IOMMUs */
	list_for_each_entry(tcegrp, &container->group_list, next) {
		table_group = iommu_group_get_iommudata(tcegrp->grp);

		/*
		 * SPAPR TCE IOMMU exposes the default DMA window to
		 * the guest via dma32_window_start/size of
		 * VFIO_IOMMU_SPAPR_TCE_GET_INFO. Some platforms allow
		 * the userspace to remove this window, some do not so
		 * here we check for the platform capability.
		 */
		if (!table_group->ops || !table_group->ops->unset_window)
			return -EPERM;

		table_group->ops->unset_window(table_group, num);
	}

	/* Free table */
	tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
	tce_iommu_free_table(container, tbl);
	container->tables[num] = NULL;

	return 0;
}

static long tce_iommu_create_default_window(struct tce_container *container)
{
	long ret;
	__u64 start_addr = 0;
	struct tce_iommu_group *tcegrp;
	struct iommu_table_group *table_group;

	if (!container->def_window_pending)
		return 0;

	if (!tce_groups_attached(container))
		return -ENODEV;

	tcegrp = list_first_entry(&container->group_list,
			struct tce_iommu_group, next);
	table_group = iommu_group_get_iommudata(tcegrp->grp);
	if (!table_group)
		return -ENODEV;

	ret = tce_iommu_create_window(container, IOMMU_PAGE_SHIFT_4K,
			table_group->tce32_size, 1, &start_addr);
	WARN_ON_ONCE(!ret && start_addr);

	if (!ret)
		container->def_window_pending = false;

	return ret;
}

static long tce_iommu_ioctl(void *iommu_data,
				 unsigned int cmd, unsigned long arg)
{
	struct tce_container *container = iommu_data;
	unsigned long minsz, ddwsz;
	long ret;

	switch (cmd) {
	case VFIO_CHECK_EXTENSION:
		switch (arg) {
		case VFIO_SPAPR_TCE_IOMMU:
		case VFIO_SPAPR_TCE_v2_IOMMU:
			ret = 1;
			break;
		default:
			ret = vfio_spapr_iommu_eeh_ioctl(NULL, cmd, arg);
			break;
		}

		return (ret < 0) ? 0 : ret;
	}

	/*
	 * Sanity check to prevent one userspace from manipulating
	 * another userspace mm.
	 */
	BUG_ON(!container);
	if (container->mm && container->mm != current->mm)
		return -EPERM;

	switch (cmd) {
	case VFIO_IOMMU_SPAPR_TCE_GET_INFO: {
		struct vfio_iommu_spapr_tce_info info;
		struct tce_iommu_group *tcegrp;
		struct iommu_table_group *table_group;

		if (!tce_groups_attached(container))
			return -ENXIO;

		tcegrp = list_first_entry(&container->group_list,
				struct tce_iommu_group, next);
		table_group = iommu_group_get_iommudata(tcegrp->grp);

		if (!table_group)
			return -ENXIO;

		minsz = offsetofend(struct vfio_iommu_spapr_tce_info,
				dma32_window_size);

		if (copy_from_user(&info, (void __user *)arg, minsz))
			return -EFAULT;

		if (info.argsz < minsz)
			return -EINVAL;

		info.dma32_window_start = table_group->tce32_start;
		info.dma32_window_size = table_group->tce32_size;
		info.flags = 0;
		memset(&info.ddw, 0, sizeof(info.ddw));

		if (table_group->max_dynamic_windows_supported &&
				container->v2) {
			info.flags |= VFIO_IOMMU_SPAPR_INFO_DDW;
			info.ddw.pgsizes = table_group->pgsizes;
			info.ddw.max_dynamic_windows_supported =
				table_group->max_dynamic_windows_supported;
			info.ddw.levels = table_group->max_levels;
		}

		ddwsz = offsetofend(struct vfio_iommu_spapr_tce_info, ddw);

		if (info.argsz >= ddwsz)
			minsz = ddwsz;

		if (copy_to_user((void __user *)arg, &info, minsz))
			return -EFAULT;

		return 0;
	}
	case VFIO_IOMMU_MAP_DMA: {
		struct vfio_iommu_type1_dma_map param;
		struct iommu_table *tbl = NULL;
		long num;
		enum dma_data_direction direction;

		if (!container->enabled)
			return -EPERM;

		minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);

		if (copy_from_user(&param, (void __user *)arg, minsz))
			return -EFAULT;

		if (param.argsz < minsz)
			return -EINVAL;

		if (param.flags & ~(VFIO_DMA_MAP_FLAG_READ |
				VFIO_DMA_MAP_FLAG_WRITE))
			return -EINVAL;

		ret = tce_iommu_create_default_window(container);
		if (ret)
			return ret;

		num = tce_iommu_find_table(container, param.iova, &tbl);
		if (num < 0)
			return -ENXIO;

		if ((param.size & ~IOMMU_PAGE_MASK(tbl)) ||
				(param.vaddr & ~IOMMU_PAGE_MASK(tbl)))
			return -EINVAL;

		/* iova is checked by the IOMMU API */
		if (param.flags & VFIO_DMA_MAP_FLAG_READ) {
			if (param.flags & VFIO_DMA_MAP_FLAG_WRITE)
				direction = DMA_BIDIRECTIONAL;
			else
				direction = DMA_TO_DEVICE;
		} else {
			if (param.flags & VFIO_DMA_MAP_FLAG_WRITE)
				direction = DMA_FROM_DEVICE;
			else
				return -EINVAL;
		}

		ret = iommu_tce_put_param_check(tbl, param.iova, param.vaddr);
		if (ret)
			return ret;

		if (container->v2)
			ret = tce_iommu_build_v2(container, tbl,
					param.iova >> tbl->it_page_shift,
					param.vaddr,
					param.size >> tbl->it_page_shift,
					direction);
		else
			ret = tce_iommu_build(container, tbl,
					param.iova >> tbl->it_page_shift,
					param.vaddr,
					param.size >> tbl->it_page_shift,
					direction);

		iommu_flush_tce(tbl);

		return ret;
	}
	case VFIO_IOMMU_UNMAP_DMA: {
		struct vfio_iommu_type1_dma_unmap param;
		struct iommu_table *tbl = NULL;
		long num;

		if (!container->enabled)
			return -EPERM;

		minsz = offsetofend(struct vfio_iommu_type1_dma_unmap,
				size);

		if (copy_from_user(&param, (void __user *)arg, minsz))
			return -EFAULT;

		if (param.argsz < minsz)
			return -EINVAL;

		/* No flag is supported now */
		if (param.flags)
			return -EINVAL;

		ret = tce_iommu_create_default_window(container);
		if (ret)
			return ret;

		num = tce_iommu_find_table(container, param.iova, &tbl);
		if (num < 0)
			return -ENXIO;

		if (param.size & ~IOMMU_PAGE_MASK(tbl))
			return -EINVAL;

		ret = iommu_tce_clear_param_check(tbl, param.iova, 0,
				param.size >> tbl->it_page_shift);
		if (ret)
			return ret;

		ret = tce_iommu_clear(container, tbl,
				param.iova >> tbl->it_page_shift,
				param.size >> tbl->it_page_shift);
		iommu_flush_tce(tbl);

		return ret;
	}
	case VFIO_IOMMU_SPAPR_REGISTER_MEMORY: {
		struct vfio_iommu_spapr_register_memory param;

		if (!container->v2)
			break;

		minsz = offsetofend(struct vfio_iommu_spapr_register_memory,
				size);

		ret = tce_iommu_mm_set(container);
		if (ret)
			return ret;

		if (copy_from_user(&param, (void __user *)arg, minsz))
			return -EFAULT;

		if (param.argsz < minsz)
			return -EINVAL;

		/* No flag is supported now */
		if (param.flags)
			return -EINVAL;

		mutex_lock(&container->lock);
		ret = tce_iommu_register_pages(container, param.vaddr,
				param.size);
		mutex_unlock(&container->lock);

		return ret;
	}
	case VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY: {
		struct vfio_iommu_spapr_register_memory param;

		if (!container->v2)
			break;

		if (!container->mm)
			return -EPERM;

		minsz = offsetofend(struct vfio_iommu_spapr_register_memory,
				size);

		if (copy_from_user(&param, (void __user *)arg, minsz))
			return -EFAULT;

		if (param.argsz < minsz)
			return -EINVAL;

		/* No flag is supported now */
		if (param.flags)
			return -EINVAL;

		mutex_lock(&container->lock);
		ret = tce_iommu_unregister_pages(container, param.vaddr,
				param.size);
		mutex_unlock(&container->lock);

		return ret;
	}
	case VFIO_IOMMU_ENABLE:
		if (container->v2)
			break;

		mutex_lock(&container->lock);
		ret = tce_iommu_enable(container);
		mutex_unlock(&container->lock);
		return ret;


	case VFIO_IOMMU_DISABLE:
		if (container->v2)
			break;

		mutex_lock(&container->lock);
		tce_iommu_disable(container);
		mutex_unlock(&container->lock);
		return 0;

	case VFIO_EEH_PE_OP: {
		struct tce_iommu_group *tcegrp;

		ret = 0;
		list_for_each_entry(tcegrp, &container->group_list, next) {
			ret = vfio_spapr_iommu_eeh_ioctl(tcegrp->grp,
					cmd, arg);
			if (ret)
				return ret;
		}
		return ret;
	}

	case VFIO_IOMMU_SPAPR_TCE_CREATE: {
		struct vfio_iommu_spapr_tce_create create;

		if (!container->v2)
			break;

		ret = tce_iommu_mm_set(container);
		if (ret)
			return ret;

		if (!tce_groups_attached(container))
			return -ENXIO;

		minsz = offsetofend(struct vfio_iommu_spapr_tce_create,
				start_addr);

		if (copy_from_user(&create, (void __user *)arg, minsz))
			return -EFAULT;

		if (create.argsz < minsz)
			return -EINVAL;

		if (create.flags)
			return -EINVAL;

		mutex_lock(&container->lock);

		ret = tce_iommu_create_default_window(container);
		if (!ret)
			ret = tce_iommu_create_window(container,
					create.page_shift,
					create.window_size, create.levels,
					&create.start_addr);

		mutex_unlock(&container->lock);

		if (!ret && copy_to_user((void __user *)arg, &create, minsz))
			ret = -EFAULT;

		return ret;
	}
	case VFIO_IOMMU_SPAPR_TCE_REMOVE: {
		struct vfio_iommu_spapr_tce_remove remove;

		if (!container->v2)
			break;

		ret = tce_iommu_mm_set(container);
		if (ret)
			return ret;

		if (!tce_groups_attached(container))
			return -ENXIO;

		minsz = offsetofend(struct vfio_iommu_spapr_tce_remove,
				start_addr);

		if (copy_from_user(&remove, (void __user *)arg, minsz))
			return -EFAULT;

		if (remove.argsz < minsz)
			return -EINVAL;

		if (remove.flags)
			return -EINVAL;

		if (container->def_window_pending && !remove.start_addr) {
			container->def_window_pending = false;
			return 0;
		}

		mutex_lock(&container->lock);

		ret = tce_iommu_remove_window(container, remove.start_addr);

		mutex_unlock(&container->lock);

		return ret;
	}
	}

	return -ENOTTY;
}

static void tce_iommu_release_ownership(struct tce_container *container,
		struct iommu_table_group *table_group)
{
	int i;

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		struct iommu_table *tbl = container->tables[i];

		if (!tbl)
			continue;

		tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
		tce_iommu_userspace_view_free(tbl, container->mm);
		if (tbl->it_map)
			iommu_release_ownership(tbl);

		container->tables[i] = NULL;
	}
}

static int tce_iommu_take_ownership(struct tce_container *container,
		struct iommu_table_group *table_group)
{
	int i, j, rc = 0;

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		struct iommu_table *tbl = table_group->tables[i];

		if (!tbl || !tbl->it_map)
			continue;

		rc = iommu_take_ownership(tbl);
		if (rc) {
			for (j = 0; j < i; ++j)
				iommu_release_ownership(
						table_group->tables[j]);

			return rc;
		}
	}

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
		container->tables[i] = table_group->tables[i];

	return 0;
}

static void tce_iommu_release_ownership_ddw(struct tce_container *container,
		struct iommu_table_group *table_group)
{
	long i;

	if (!table_group->ops->unset_window) {
		WARN_ON_ONCE(1);
		return;
	}

	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
		table_group->ops->unset_window(table_group, i);

	table_group->ops->release_ownership(table_group);
}

static long tce_iommu_take_ownership_ddw(struct tce_container *container,
		struct iommu_table_group *table_group)
{
	long i, ret = 0;

	if (!table_group->ops->create_table || !table_group->ops->set_window ||
			!table_group->ops->release_ownership) {
		WARN_ON_ONCE(1);
		return -EFAULT;
	}

	table_group->ops->take_ownership(table_group);

	/* Set all windows to the new group */
	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
		struct iommu_table *tbl = container->tables[i];

		if (!tbl)
			continue;

		ret = table_group->ops->set_window(table_group, i, tbl);
		if (ret)
			goto release_exit;
	}

	return 0;

release_exit:
	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
		table_group->ops->unset_window(table_group, i);

	table_group->ops->release_ownership(table_group);

	return ret;
}

static int tce_iommu_attach_group(void *iommu_data,
		struct iommu_group *iommu_group)
{
	int ret;
	struct tce_container *container = iommu_data;
	struct iommu_table_group *table_group;
	struct tce_iommu_group *tcegrp = NULL;

	mutex_lock(&container->lock);

	/* pr_debug("tce_vfio: Attaching group #%u to iommu %p\n",
			iommu_group_id(iommu_group), iommu_group); */
	table_group = iommu_group_get_iommudata(iommu_group);
	if (!table_group) {
		ret = -ENODEV;
		goto unlock_exit;
	}

	if (tce_groups_attached(container) && (!table_group->ops ||
			!table_group->ops->take_ownership ||
			!table_group->ops->release_ownership)) {
		ret = -EBUSY;
		goto unlock_exit;
	}

	/* Check if new group has the same iommu_ops (i.e. compatible) */
	list_for_each_entry(tcegrp, &container->group_list, next) {
		struct iommu_table_group *table_group_tmp;

		if (tcegrp->grp == iommu_group) {
			pr_warn("tce_vfio: Group %d is already attached\n",
					iommu_group_id(iommu_group));
			ret = -EBUSY;
			goto unlock_exit;
		}
		table_group_tmp = iommu_group_get_iommudata(tcegrp->grp);
		if (table_group_tmp->ops->create_table !=
				table_group->ops->create_table) {
			pr_warn("tce_vfio: Group %d is incompatible with group %d\n",
					iommu_group_id(iommu_group),
					iommu_group_id(tcegrp->grp));
			ret = -EPERM;
			goto unlock_exit;
		}
	}

	tcegrp = kzalloc(sizeof(*tcegrp), GFP_KERNEL);
	if (!tcegrp) {
		ret = -ENOMEM;
		goto unlock_exit;
	}

	if (!table_group->ops || !table_group->ops->take_ownership ||
			!table_group->ops->release_ownership) {
		if (container->v2) {
			ret = -EPERM;
			goto unlock_exit;
		}
		ret = tce_iommu_take_ownership(container, table_group);
	} else {
		if (!container->v2) {
			ret = -EPERM;
			goto unlock_exit;
		}
		ret = tce_iommu_take_ownership_ddw(container, table_group);
		if (!tce_groups_attached(container) && !container->tables[0])
			container->def_window_pending = true;
	}

	if (!ret) {
		tcegrp->grp = iommu_group;
		list_add(&tcegrp->next, &container->group_list);
	}

unlock_exit:
	if (ret && tcegrp)
		kfree(tcegrp);

	mutex_unlock(&container->lock);

	return ret;
}

static void tce_iommu_detach_group(void *iommu_data,
		struct iommu_group *iommu_group)
{
	struct tce_container *container = iommu_data;
	struct iommu_table_group *table_group;
	bool found = false;
	struct tce_iommu_group *tcegrp;

	mutex_lock(&container->lock);

	list_for_each_entry(tcegrp, &container->group_list, next) {
		if (tcegrp->grp == iommu_group) {
			found = true;
			break;
		}
	}

	if (!found) {
		pr_warn("tce_vfio: detaching unattached group #%u\n",
				iommu_group_id(iommu_group));
		goto unlock_exit;
	}

	list_del(&tcegrp->next);
	kfree(tcegrp);

	table_group = iommu_group_get_iommudata(iommu_group);
	BUG_ON(!table_group);

	if (!table_group->ops || !table_group->ops->release_ownership)
		tce_iommu_release_ownership(container, table_group);
	else
		tce_iommu_release_ownership_ddw(container, table_group);

unlock_exit:
	mutex_unlock(&container->lock);
}

const struct vfio_iommu_driver_ops tce_iommu_driver_ops = {
	.name		= "iommu-vfio-powerpc",
	.owner		= THIS_MODULE,
	.open		= tce_iommu_open,
	.release	= tce_iommu_release,
	.ioctl		= tce_iommu_ioctl,
	.attach_group	= tce_iommu_attach_group,
	.detach_group	= tce_iommu_detach_group,
};

static int __init tce_iommu_init(void)
{
	return vfio_register_iommu_driver(&tce_iommu_driver_ops);
}

static void __exit tce_iommu_cleanup(void)
{
	vfio_unregister_iommu_driver(&tce_iommu_driver_ops);
}

module_init(tce_iommu_init);
module_exit(tce_iommu_cleanup);

MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

