/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2015 Intel Corporation.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * Intel SCIF driver.
 *
 */
#include <linux/dma_remapping.h>
#include <linux/pagemap.h>
#include "scif_main.h"
#include "scif_map.h"

/* Used to skip ulimit checks for registrations with SCIF_MAP_KERNEL flag */
#define SCIF_MAP_ULIMIT 0x40

bool scif_ulimit_check = 1;

/**
 * scif_rma_ep_init:
 * @ep: end point
 *
 * Initialize RMA per EP data structures.
 */
void scif_rma_ep_init(struct scif_endpt *ep)
{
	struct scif_endpt_rma_info *rma = &ep->rma_info;

	mutex_init(&rma->rma_lock);
	init_iova_domain(&rma->iovad, PAGE_SIZE, SCIF_IOVA_START_PFN,
			 SCIF_DMA_64BIT_PFN);
	spin_lock_init(&rma->tc_lock);
	mutex_init(&rma->mmn_lock);
	INIT_LIST_HEAD(&rma->reg_list);
	INIT_LIST_HEAD(&rma->remote_reg_list);
	atomic_set(&rma->tw_refcount, 0);
	atomic_set(&rma->tcw_refcount, 0);
	atomic_set(&rma->tcw_total_pages, 0);
	atomic_set(&rma->fence_refcount, 0);

	rma->async_list_del = 0;
	rma->dma_chan = NULL;
	INIT_LIST_HEAD(&rma->mmn_list);
	INIT_LIST_HEAD(&rma->vma_list);
	init_waitqueue_head(&rma->markwq);
}

/**
 * scif_rma_ep_can_uninit:
 * @ep: end point
 *
 * Returns 1 if an endpoint can be uninitialized and 0 otherwise.
 */
int scif_rma_ep_can_uninit(struct scif_endpt *ep)
{
	int ret = 0;

	mutex_lock(&ep->rma_info.rma_lock);
	/* Destroy RMA Info only if both lists are empty */
	if (list_empty(&ep->rma_info.reg_list) &&
	    list_empty(&ep->rma_info.remote_reg_list) &&
	    list_empty(&ep->rma_info.mmn_list) &&
	    !atomic_read(&ep->rma_info.tw_refcount) &&
	    !atomic_read(&ep->rma_info.tcw_refcount) &&
	    !atomic_read(&ep->rma_info.fence_refcount))
		ret = 1;
	mutex_unlock(&ep->rma_info.rma_lock);
	return ret;
}

/**
 * scif_create_pinned_pages:
 * @nr_pages: number of pages in window
 * @prot: read/write protection
 *
 * Allocate and prepare a set of pinned pages.
 */
static struct scif_pinned_pages *
scif_create_pinned_pages(int nr_pages, int prot)
{
	struct scif_pinned_pages *pin;

	might_sleep();
	pin = scif_zalloc(sizeof(*pin));
	if (!pin)
		goto error;

	pin->pages = scif_zalloc(nr_pages * sizeof(*pin->pages));
	if (!pin->pages)
		goto error_free_pinned_pages;

	pin->prot = prot;
	pin->magic = SCIFEP_MAGIC;
	return pin;

error_free_pinned_pages:
	scif_free(pin, sizeof(*pin));
error:
	return NULL;
}

/**
 * scif_destroy_pinned_pages:
 * @pin: A set of pinned pages.
 *
 * Deallocate resources for pinned pages.
 */
static int scif_destroy_pinned_pages(struct scif_pinned_pages *pin)
{
	int j;
	int writeable = pin->prot & SCIF_PROT_WRITE;
	int kernel = SCIF_MAP_KERNEL & pin->map_flags;

	for (j = 0; j < pin->nr_pages; j++) {
		if (pin->pages[j] && !kernel) {
			if (writeable)
				SetPageDirty(pin->pages[j]);
			put_page(pin->pages[j]);
		}
	}

	scif_free(pin->pages,
		  pin->nr_pages * sizeof(*pin->pages));
	scif_free(pin, sizeof(*pin));
	return 0;
}

/*
 * scif_create_window:
 * @ep: end point
 * @nr_pages: number of pages
 * @offset: registration offset
 * @temp: true if a temporary window is being created
 *
 * Allocate and prepare a self registration window.
 */
struct scif_window *scif_create_window(struct scif_endpt *ep, int nr_pages,
				       s64 offset, bool temp)
{
	struct scif_window *window;

	might_sleep();
	window = scif_zalloc(sizeof(*window));
	if (!window)
		goto error;

	window->dma_addr = scif_zalloc(nr_pages * sizeof(*window->dma_addr));
	if (!window->dma_addr)
		goto error_free_window;

	window->num_pages = scif_zalloc(nr_pages * sizeof(*window->num_pages));
	if (!window->num_pages)
		goto error_free_window;

	window->offset = offset;
	window->ep = (u64)ep;
	window->magic = SCIFEP_MAGIC;
	window->reg_state = OP_IDLE;
	init_waitqueue_head(&window->regwq);
	window->unreg_state = OP_IDLE;
	init_waitqueue_head(&window->unregwq);
	INIT_LIST_HEAD(&window->list);
	window->type = SCIF_WINDOW_SELF;
	window->temp = temp;
	return window;

error_free_window:
	scif_free(window->dma_addr,
		  nr_pages * sizeof(*window->dma_addr));
	scif_free(window, sizeof(*window));
error:
	return NULL;
}

/**
 * scif_destroy_incomplete_window:
 * @ep: end point
 * @window: registration window
 *
 * Deallocate resources for self window.
 */
static void scif_destroy_incomplete_window(struct scif_endpt *ep,
					   struct scif_window *window)
{
	int err;
	int nr_pages = window->nr_pages;
	struct scif_allocmsg *alloc = &window->alloc_handle;
	struct scifmsg msg;

retry:
	/* Wait for a SCIF_ALLOC_GNT/REJ message */
	err = wait_event_timeout(alloc->allocwq,
				 alloc->state != OP_IN_PROGRESS,
				 SCIF_NODE_ALIVE_TIMEOUT);
	if (!err && scifdev_alive(ep))
		goto retry;

	mutex_lock(&ep->rma_info.rma_lock);
	if (alloc->state == OP_COMPLETED) {
		msg.uop = SCIF_FREE_VIRT;
		msg.src = ep->port;
		msg.payload[0] = ep->remote_ep;
		msg.payload[1] = window->alloc_handle.vaddr;
		msg.payload[2] = (u64)window;
		msg.payload[3] = SCIF_REGISTER;
		_scif_nodeqp_send(ep->remote_dev, &msg);
	}
	mutex_unlock(&ep->rma_info.rma_lock);

	scif_free_window_offset(ep, window, window->offset);
	scif_free(window->dma_addr, nr_pages * sizeof(*window->dma_addr));
	scif_free(window->num_pages, nr_pages * sizeof(*window->num_pages));
	scif_free(window, sizeof(*window));
}

/**
 * scif_unmap_window:
 * @remote_dev: SCIF remote device
 * @window: registration window
 *
 * Delete any DMA mappings created for a registered self window
 */
void scif_unmap_window(struct scif_dev *remote_dev, struct scif_window *window)
{
	int j;

	if (scif_is_iommu_enabled() && !scifdev_self(remote_dev)) {
		if (window->st) {
			dma_unmap_sg(&remote_dev->sdev->dev,
				     window->st->sgl, window->st->nents,
				     DMA_BIDIRECTIONAL);
			sg_free_table(window->st);
			kfree(window->st);
			window->st = NULL;
		}
	} else {
		for (j = 0; j < window->nr_contig_chunks; j++) {
			if (window->dma_addr[j]) {
				scif_unmap_single(window->dma_addr[j],
						  remote_dev,
						  window->num_pages[j] <<
						  PAGE_SHIFT);
				window->dma_addr[j] = 0x0;
			}
		}
	}
}

static inline struct mm_struct *__scif_acquire_mm(void)
{
	if (scif_ulimit_check)
		return get_task_mm(current);
	return NULL;
}

static inline void __scif_release_mm(struct mm_struct *mm)
{
	if (mm)
		mmput(mm);
}

static inline int
__scif_dec_pinned_vm_lock(struct mm_struct *mm,
			  int nr_pages, bool try_lock)
{
	if (!mm || !nr_pages || !scif_ulimit_check)
		return 0;
	if (try_lock) {
		if (!down_write_trylock(&mm->mmap_sem)) {
			dev_err(scif_info.mdev.this_device,
				"%s %d err\n", __func__, __LINE__);
			return -1;
		}
	} else {
		down_write(&mm->mmap_sem);
	}
	mm->pinned_vm -= nr_pages;
	up_write(&mm->mmap_sem);
	return 0;
}

static inline int __scif_check_inc_pinned_vm(struct mm_struct *mm,
					     int nr_pages)
{
	unsigned long locked, lock_limit;

	if (!mm || !nr_pages || !scif_ulimit_check)
		return 0;

	locked = nr_pages;
	locked += mm->pinned_vm;
	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
	if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
		dev_err(scif_info.mdev.this_device,
			"locked(%lu) > lock_limit(%lu)\n",
			locked, lock_limit);
		return -ENOMEM;
	}
	mm->pinned_vm = locked;
	return 0;
}

/**
 * scif_destroy_window:
 * @ep: end point
 * @window: registration window
 *
 * Deallocate resources for self window.
 */
int scif_destroy_window(struct scif_endpt *ep, struct scif_window *window)
{
	int j;
	struct scif_pinned_pages *pinned_pages = window->pinned_pages;
	int nr_pages = window->nr_pages;

	might_sleep();
	if (!window->temp && window->mm) {
		__scif_dec_pinned_vm_lock(window->mm, window->nr_pages, 0);
		__scif_release_mm(window->mm);
		window->mm = NULL;
	}

	scif_free_window_offset(ep, window, window->offset);
	scif_unmap_window(ep->remote_dev, window);
	/*
	 * Decrement references for this set of pinned pages from
	 * this window.
	 */
	j = atomic_sub_return(1, &pinned_pages->ref_count);
	if (j < 0)
		dev_err(scif_info.mdev.this_device,
			"%s %d incorrect ref count %d\n",
			__func__, __LINE__, j);
	/*
	 * If the ref count for pinned_pages is zero then someone
	 * has already called scif_unpin_pages() for it and we should
	 * destroy the page cache.
	 */
	if (!j)
		scif_destroy_pinned_pages(window->pinned_pages);
	scif_free(window->dma_addr, nr_pages * sizeof(*window->dma_addr));
	scif_free(window->num_pages, nr_pages * sizeof(*window->num_pages));
	window->magic = 0;
	scif_free(window, sizeof(*window));
	return 0;
}

/**
 * scif_create_remote_lookup:
 * @remote_dev: SCIF remote device
 * @window: remote window
 *
 * Allocate and prepare lookup entries for the remote
 * end to copy over the physical addresses.
 * Returns 0 on success and appropriate errno on failure.
 */
static int scif_create_remote_lookup(struct scif_dev *remote_dev,
				     struct scif_window *window)
{
	int i, j, err = 0;
	int nr_pages = window->nr_pages;
	bool vmalloc_dma_phys, vmalloc_num_pages;

	might_sleep();
	/* Map window */
	err = scif_map_single(&window->mapped_offset,
			      window, remote_dev, sizeof(*window));
	if (err)
		goto error_window;

	/* Compute the number of lookup entries. 21 == 2MB Shift */
	window->nr_lookup = ALIGN(nr_pages * PAGE_SIZE,
					((2) * 1024 * 1024)) >> 21;

	window->dma_addr_lookup.lookup =
		scif_alloc_coherent(&window->dma_addr_lookup.offset,
				    remote_dev, window->nr_lookup *
				    sizeof(*window->dma_addr_lookup.lookup),
				    GFP_KERNEL | __GFP_ZERO);
	if (!window->dma_addr_lookup.lookup) {
		err = -ENOMEM;
		goto error_window;
	}

	window->num_pages_lookup.lookup =
		scif_alloc_coherent(&window->num_pages_lookup.offset,
				    remote_dev, window->nr_lookup *
				    sizeof(*window->num_pages_lookup.lookup),
				    GFP_KERNEL | __GFP_ZERO);
	if (!window->num_pages_lookup.lookup) {
		err = -ENOMEM;
		goto error_window;
	}

	vmalloc_dma_phys = is_vmalloc_addr(&window->dma_addr[0]);
	vmalloc_num_pages = is_vmalloc_addr(&window->num_pages[0]);

	/* Now map each of the pages containing physical addresses */
	for (i = 0, j = 0; i < nr_pages; i += SCIF_NR_ADDR_IN_PAGE, j++) {
		err = scif_map_page(&window->dma_addr_lookup.lookup[j],
				    vmalloc_dma_phys ?
				    vmalloc_to_page(&window->dma_addr[i]) :
				    virt_to_page(&window->dma_addr[i]),
				    remote_dev);
		if (err)
			goto error_window;
		err = scif_map_page(&window->num_pages_lookup.lookup[j],
				    vmalloc_dma_phys ?
				    vmalloc_to_page(&window->num_pages[i]) :
				    virt_to_page(&window->num_pages[i]),
				    remote_dev);
		if (err)
			goto error_window;
	}
	return 0;
error_window:
	return err;
}

/**
 * scif_destroy_remote_lookup:
 * @remote_dev: SCIF remote device
 * @window: remote window
 *
 * Destroy lookup entries used for the remote
 * end to copy over the physical addresses.
 */
static void scif_destroy_remote_lookup(struct scif_dev *remote_dev,
				       struct scif_window *window)
{
	int i, j;

	if (window->nr_lookup) {
		struct scif_rma_lookup *lup = &window->dma_addr_lookup;
		struct scif_rma_lookup *npup = &window->num_pages_lookup;

		for (i = 0, j = 0; i < window->nr_pages;
			i += SCIF_NR_ADDR_IN_PAGE, j++) {
			if (lup->lookup && lup->lookup[j])
				scif_unmap_single(lup->lookup[j],
						  remote_dev,
						  PAGE_SIZE);
			if (npup->lookup && npup->lookup[j])
				scif_unmap_single(npup->lookup[j],
						  remote_dev,
						  PAGE_SIZE);
		}
		if (lup->lookup)
			scif_free_coherent(lup->lookup, lup->offset,
					   remote_dev, window->nr_lookup *
					   sizeof(*lup->lookup));
		if (npup->lookup)
			scif_free_coherent(npup->lookup, npup->offset,
					   remote_dev, window->nr_lookup *
					   sizeof(*npup->lookup));
		if (window->mapped_offset)
			scif_unmap_single(window->mapped_offset,
					  remote_dev, sizeof(*window));
		window->nr_lookup = 0;
	}
}

/**
 * scif_create_remote_window:
 * @ep: end point
 * @nr_pages: number of pages in window
 *
 * Allocate and prepare a remote registration window.
 */
static struct scif_window *
scif_create_remote_window(struct scif_dev *scifdev, int nr_pages)
{
	struct scif_window *window;

	might_sleep();
	window = scif_zalloc(sizeof(*window));
	if (!window)
		goto error_ret;

	window->magic = SCIFEP_MAGIC;
	window->nr_pages = nr_pages;

	window->dma_addr = scif_zalloc(nr_pages * sizeof(*window->dma_addr));
	if (!window->dma_addr)
		goto error_window;

	window->num_pages = scif_zalloc(nr_pages *
					sizeof(*window->num_pages));
	if (!window->num_pages)
		goto error_window;

	if (scif_create_remote_lookup(scifdev, window))
		goto error_window;

	window->type = SCIF_WINDOW_PEER;
	window->unreg_state = OP_IDLE;
	INIT_LIST_HEAD(&window->list);
	return window;
error_window:
	scif_destroy_remote_window(window);
error_ret:
	return NULL;
}

/**
 * scif_destroy_remote_window:
 * @ep: end point
 * @window: remote registration window
 *
 * Deallocate resources for remote window.
 */
void
scif_destroy_remote_window(struct scif_window *window)
{
	scif_free(window->dma_addr, window->nr_pages *
		  sizeof(*window->dma_addr));
	scif_free(window->num_pages, window->nr_pages *
		  sizeof(*window->num_pages));
	window->magic = 0;
	scif_free(window, sizeof(*window));
}

/**
 * scif_iommu_map: create DMA mappings if the IOMMU is enabled
 * @remote_dev: SCIF remote device
 * @window: remote registration window
 *
 * Map the physical pages using dma_map_sg(..) and then detect the number
 * of contiguous DMA mappings allocated
 */
static int scif_iommu_map(struct scif_dev *remote_dev,
			  struct scif_window *window)
{
	struct scatterlist *sg;
	int i, err;
	scif_pinned_pages_t pin = window->pinned_pages;

	window->st = kzalloc(sizeof(*window->st), GFP_KERNEL);
	if (!window->st)
		return -ENOMEM;

	err = sg_alloc_table(window->st, window->nr_pages, GFP_KERNEL);
	if (err)
		return err;

	for_each_sg(window->st->sgl, sg, window->st->nents, i)
		sg_set_page(sg, pin->pages[i], PAGE_SIZE, 0x0);

	err = dma_map_sg(&remote_dev->sdev->dev, window->st->sgl,
			 window->st->nents, DMA_BIDIRECTIONAL);
	if (!err)
		return -ENOMEM;
	/* Detect contiguous ranges of DMA mappings */
	sg = window->st->sgl;
	for (i = 0; sg; i++) {
		dma_addr_t last_da;

		window->dma_addr[i] = sg_dma_address(sg);
		window->num_pages[i] = sg_dma_len(sg) >> PAGE_SHIFT;
		last_da = sg_dma_address(sg) + sg_dma_len(sg);
		while ((sg = sg_next(sg)) && sg_dma_address(sg) == last_da) {
			window->num_pages[i] +=
				(sg_dma_len(sg) >> PAGE_SHIFT);
			last_da = window->dma_addr[i] +
				sg_dma_len(sg);
		}
		window->nr_contig_chunks++;
	}
	return 0;
}

/**
 * scif_map_window:
 * @remote_dev: SCIF remote device
 * @window: self registration window
 *
 * Map pages of a window into the aperture/PCI.
 * Also determine addresses required for DMA.
 */
int
scif_map_window(struct scif_dev *remote_dev, struct scif_window *window)
{
	int i, j, k, err = 0, nr_contig_pages;
	scif_pinned_pages_t pin;
	phys_addr_t phys_prev, phys_curr;

	might_sleep();

	pin = window->pinned_pages;

	if (intel_iommu_enabled && !scifdev_self(remote_dev))
		return scif_iommu_map(remote_dev, window);

	for (i = 0, j = 0; i < window->nr_pages; i += nr_contig_pages, j++) {
		phys_prev = page_to_phys(pin->pages[i]);
		nr_contig_pages = 1;

		/* Detect physically contiguous chunks */
		for (k = i + 1; k < window->nr_pages; k++) {
			phys_curr = page_to_phys(pin->pages[k]);
			if (phys_curr != (phys_prev + PAGE_SIZE))
				break;
			phys_prev = phys_curr;
			nr_contig_pages++;
		}
		window->num_pages[j] = nr_contig_pages;
		window->nr_contig_chunks++;
		if (scif_is_mgmt_node()) {
			/*
			 * Management node has to deal with SMPT on X100 and
			 * hence the DMA mapping is required
			 */
			err = scif_map_single(&window->dma_addr[j],
					      phys_to_virt(page_to_phys(
							   pin->pages[i])),
					      remote_dev,
					      nr_contig_pages << PAGE_SHIFT);
			if (err)
				return err;
		} else {
			window->dma_addr[j] = page_to_phys(pin->pages[i]);
		}
	}
	return err;
}

/**
 * scif_send_scif_unregister:
 * @ep: end point
 * @window: self registration window
 *
 * Send a SCIF_UNREGISTER message.
 */
static int scif_send_scif_unregister(struct scif_endpt *ep,
				     struct scif_window *window)
{
	struct scifmsg msg;

	msg.uop = SCIF_UNREGISTER;
	msg.src = ep->port;
	msg.payload[0] = window->alloc_handle.vaddr;
	msg.payload[1] = (u64)window;
	return scif_nodeqp_send(ep->remote_dev, &msg);
}

/**
 * scif_unregister_window:
 * @window: self registration window
 *
 * Send an unregistration request and wait for a response.
 */
int scif_unregister_window(struct scif_window *window)
{
	int err = 0;
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;
	bool send_msg = false;

	might_sleep();
	switch (window->unreg_state) {
	case OP_IDLE:
	{
		window->unreg_state = OP_IN_PROGRESS;
		send_msg = true;
		/* fall through */
	}
	case OP_IN_PROGRESS:
	{
		scif_get_window(window, 1);
		mutex_unlock(&ep->rma_info.rma_lock);
		if (send_msg) {
			err = scif_send_scif_unregister(ep, window);
			if (err) {
				window->unreg_state = OP_COMPLETED;
				goto done;
			}
		} else {
			/* Return ENXIO since unregistration is in progress */
			mutex_lock(&ep->rma_info.rma_lock);
			return -ENXIO;
		}
retry:
		/* Wait for a SCIF_UNREGISTER_(N)ACK message */
		err = wait_event_timeout(window->unregwq,
					 window->unreg_state != OP_IN_PROGRESS,
					 SCIF_NODE_ALIVE_TIMEOUT);
		if (!err && scifdev_alive(ep))
			goto retry;
		if (!err) {
			err = -ENODEV;
			window->unreg_state = OP_COMPLETED;
			dev_err(scif_info.mdev.this_device,
				"%s %d err %d\n", __func__, __LINE__, err);
		}
		if (err > 0)
			err = 0;
done:
		mutex_lock(&ep->rma_info.rma_lock);
		scif_put_window(window, 1);
		break;
	}
	case OP_FAILED:
	{
		if (!scifdev_alive(ep)) {
			err = -ENODEV;
			window->unreg_state = OP_COMPLETED;
		}
		break;
	}
	case OP_COMPLETED:
		break;
	default:
		err = -ENODEV;
	}

	if (window->unreg_state == OP_COMPLETED && window->ref_count)
		scif_put_window(window, window->nr_pages);

	if (!window->ref_count) {
		atomic_inc(&ep->rma_info.tw_refcount);
		list_del_init(&window->list);
		scif_free_window_offset(ep, window, window->offset);
		mutex_unlock(&ep->rma_info.rma_lock);
		if ((!!(window->pinned_pages->map_flags & SCIF_MAP_KERNEL)) &&
		    scifdev_alive(ep)) {
			scif_drain_dma_intr(ep->remote_dev->sdev,
					    ep->rma_info.dma_chan);
		} else {
			if (!__scif_dec_pinned_vm_lock(window->mm,
						       window->nr_pages, 1)) {
				__scif_release_mm(window->mm);
				window->mm = NULL;
			}
		}
		scif_queue_for_cleanup(window, &scif_info.rma);
		mutex_lock(&ep->rma_info.rma_lock);
	}
	return err;
}

/**
 * scif_send_alloc_request:
 * @ep: end point
 * @window: self registration window
 *
 * Send a remote window allocation request
 */
static int scif_send_alloc_request(struct scif_endpt *ep,
				   struct scif_window *window)
{
	struct scifmsg msg;
	struct scif_allocmsg *alloc = &window->alloc_handle;

	/* Set up the Alloc Handle */
	alloc->state = OP_IN_PROGRESS;
	init_waitqueue_head(&alloc->allocwq);

	/* Send out an allocation request */
	msg.uop = SCIF_ALLOC_REQ;
	msg.payload[1] = window->nr_pages;
	msg.payload[2] = (u64)&window->alloc_handle;
	return _scif_nodeqp_send(ep->remote_dev, &msg);
}

/**
 * scif_prep_remote_window:
 * @ep: end point
 * @window: self registration window
 *
 * Send a remote window allocation request, wait for an allocation response,
 * and prepares the remote window by copying over the page lists
 */
static int scif_prep_remote_window(struct scif_endpt *ep,
				   struct scif_window *window)
{
	struct scifmsg msg;
	struct scif_window *remote_window;
	struct scif_allocmsg *alloc = &window->alloc_handle;
	dma_addr_t *dma_phys_lookup, *tmp, *num_pages_lookup, *tmp1;
	int i = 0, j = 0;
	int nr_contig_chunks, loop_nr_contig_chunks;
	int remaining_nr_contig_chunks, nr_lookup;
	int err, map_err;

	map_err = scif_map_window(ep->remote_dev, window);
	if (map_err)
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d map_err %d\n", __func__, __LINE__, map_err);
	remaining_nr_contig_chunks = window->nr_contig_chunks;
	nr_contig_chunks = window->nr_contig_chunks;
retry:
	/* Wait for a SCIF_ALLOC_GNT/REJ message */
	err = wait_event_timeout(alloc->allocwq,
				 alloc->state != OP_IN_PROGRESS,
				 SCIF_NODE_ALIVE_TIMEOUT);
	mutex_lock(&ep->rma_info.rma_lock);
	/* Synchronize with the thread waking up allocwq */
	mutex_unlock(&ep->rma_info.rma_lock);
	if (!err && scifdev_alive(ep))
		goto retry;

	if (!err)
		err = -ENODEV;

	if (err > 0)
		err = 0;
	else
		return err;

	/* Bail out. The remote end rejected this request */
	if (alloc->state == OP_FAILED)
		return -ENOMEM;

	if (map_err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, map_err);
		msg.uop = SCIF_FREE_VIRT;
		msg.src = ep->port;
		msg.payload[0] = ep->remote_ep;
		msg.payload[1] = window->alloc_handle.vaddr;
		msg.payload[2] = (u64)window;
		msg.payload[3] = SCIF_REGISTER;
		spin_lock(&ep->lock);
		if (ep->state == SCIFEP_CONNECTED)
			err = _scif_nodeqp_send(ep->remote_dev, &msg);
		else
			err = -ENOTCONN;
		spin_unlock(&ep->lock);
		return err;
	}

	remote_window = scif_ioremap(alloc->phys_addr, sizeof(*window),
				     ep->remote_dev);

	/* Compute the number of lookup entries. 21 == 2MB Shift */
	nr_lookup = ALIGN(nr_contig_chunks, SCIF_NR_ADDR_IN_PAGE)
			  >> ilog2(SCIF_NR_ADDR_IN_PAGE);

	dma_phys_lookup =
		scif_ioremap(remote_window->dma_addr_lookup.offset,
			     nr_lookup *
			     sizeof(*remote_window->dma_addr_lookup.lookup),
			     ep->remote_dev);
	num_pages_lookup =
		scif_ioremap(remote_window->num_pages_lookup.offset,
			     nr_lookup *
			     sizeof(*remote_window->num_pages_lookup.lookup),
			     ep->remote_dev);

	while (remaining_nr_contig_chunks) {
		loop_nr_contig_chunks = min_t(int, remaining_nr_contig_chunks,
					      (int)SCIF_NR_ADDR_IN_PAGE);
		/* #1/2 - Copy  physical addresses over to the remote side */

		/* #2/2 - Copy DMA addresses (addresses that are fed into the
		 * DMA engine) We transfer bus addresses which are then
		 * converted into a MIC physical address on the remote
		 * side if it is a MIC, if the remote node is a mgmt node we
		 * transfer the MIC physical address
		 */
		tmp = scif_ioremap(dma_phys_lookup[j],
				   loop_nr_contig_chunks *
				   sizeof(*window->dma_addr),
				   ep->remote_dev);
		tmp1 = scif_ioremap(num_pages_lookup[j],
				    loop_nr_contig_chunks *
				    sizeof(*window->num_pages),
				    ep->remote_dev);
		if (scif_is_mgmt_node()) {
			memcpy_toio((void __force __iomem *)tmp,
				    &window->dma_addr[i], loop_nr_contig_chunks
				    * sizeof(*window->dma_addr));
			memcpy_toio((void __force __iomem *)tmp1,
				    &window->num_pages[i], loop_nr_contig_chunks
				    * sizeof(*window->num_pages));
		} else {
			if (scifdev_is_p2p(ep->remote_dev)) {
				/*
				 * add remote node's base address for this node
				 * to convert it into a MIC address
				 */
				int m;
				dma_addr_t dma_addr;

				for (m = 0; m < loop_nr_contig_chunks; m++) {
					dma_addr = window->dma_addr[i + m] +
						ep->remote_dev->base_addr;
					writeq(dma_addr,
					       (void __force __iomem *)&tmp[m]);
				}
				memcpy_toio((void __force __iomem *)tmp1,
					    &window->num_pages[i],
					    loop_nr_contig_chunks
					    * sizeof(*window->num_pages));
			} else {
				/* Mgmt node or loopback - transfer DMA
				 * addresses as is, this is the same as a
				 * MIC physical address (we use the dma_addr
				 * and not the phys_addr array since the
				 * phys_addr is only setup if there is a mmap()
				 * request from the mgmt node)
				 */
				memcpy_toio((void __force __iomem *)tmp,
					    &window->dma_addr[i],
					    loop_nr_contig_chunks *
					    sizeof(*window->dma_addr));
				memcpy_toio((void __force __iomem *)tmp1,
					    &window->num_pages[i],
					    loop_nr_contig_chunks *
					    sizeof(*window->num_pages));
			}
		}
		remaining_nr_contig_chunks -= loop_nr_contig_chunks;
		i += loop_nr_contig_chunks;
		j++;
		scif_iounmap(tmp, loop_nr_contig_chunks *
			     sizeof(*window->dma_addr), ep->remote_dev);
		scif_iounmap(tmp1, loop_nr_contig_chunks *
			     sizeof(*window->num_pages), ep->remote_dev);
	}

	/* Prepare the remote window for the peer */
	remote_window->peer_window = (u64)window;
	remote_window->offset = window->offset;
	remote_window->prot = window->prot;
	remote_window->nr_contig_chunks = nr_contig_chunks;
	remote_window->ep = ep->remote_ep;
	scif_iounmap(num_pages_lookup,
		     nr_lookup *
		     sizeof(*remote_window->num_pages_lookup.lookup),
		     ep->remote_dev);
	scif_iounmap(dma_phys_lookup,
		     nr_lookup *
		     sizeof(*remote_window->dma_addr_lookup.lookup),
		     ep->remote_dev);
	scif_iounmap(remote_window, sizeof(*remote_window), ep->remote_dev);
	window->peer_window = alloc->vaddr;
	return err;
}

/**
 * scif_send_scif_register:
 * @ep: end point
 * @window: self registration window
 *
 * Send a SCIF_REGISTER message if EP is connected and wait for a
 * SCIF_REGISTER_(N)ACK message else send a SCIF_FREE_VIRT
 * message so that the peer can free its remote window allocated earlier.
 */
static int scif_send_scif_register(struct scif_endpt *ep,
				   struct scif_window *window)
{
	int err = 0;
	struct scifmsg msg;

	msg.src = ep->port;
	msg.payload[0] = ep->remote_ep;
	msg.payload[1] = window->alloc_handle.vaddr;
	msg.payload[2] = (u64)window;
	spin_lock(&ep->lock);
	if (ep->state == SCIFEP_CONNECTED) {
		msg.uop = SCIF_REGISTER;
		window->reg_state = OP_IN_PROGRESS;
		err = _scif_nodeqp_send(ep->remote_dev, &msg);
		spin_unlock(&ep->lock);
		if (!err) {
retry:
			/* Wait for a SCIF_REGISTER_(N)ACK message */
			err = wait_event_timeout(window->regwq,
						 window->reg_state !=
						 OP_IN_PROGRESS,
						 SCIF_NODE_ALIVE_TIMEOUT);
			if (!err && scifdev_alive(ep))
				goto retry;
			err = !err ? -ENODEV : 0;
			if (window->reg_state == OP_FAILED)
				err = -ENOTCONN;
		}
	} else {
		msg.uop = SCIF_FREE_VIRT;
		msg.payload[3] = SCIF_REGISTER;
		err = _scif_nodeqp_send(ep->remote_dev, &msg);
		spin_unlock(&ep->lock);
		if (!err)
			err = -ENOTCONN;
	}
	return err;
}

/**
 * scif_get_window_offset:
 * @ep: end point descriptor
 * @flags: flags
 * @offset: offset hint
 * @num_pages: number of pages
 * @out_offset: computed offset returned by reference.
 *
 * Compute/Claim a new offset for this EP.
 */
int scif_get_window_offset(struct scif_endpt *ep, int flags, s64 offset,
			   int num_pages, s64 *out_offset)
{
	s64 page_index;
	struct iova *iova_ptr;
	int err = 0;

	if (flags & SCIF_MAP_FIXED) {
		page_index = SCIF_IOVA_PFN(offset);
		iova_ptr = reserve_iova(&ep->rma_info.iovad, page_index,
					page_index + num_pages - 1);
		if (!iova_ptr)
			err = -EADDRINUSE;
	} else {
		iova_ptr = alloc_iova(&ep->rma_info.iovad, num_pages,
				      SCIF_DMA_63BIT_PFN - 1, 0);
		if (!iova_ptr)
			err = -ENOMEM;
	}
	if (!err)
		*out_offset = (iova_ptr->pfn_lo) << PAGE_SHIFT;
	return err;
}

/**
 * scif_free_window_offset:
 * @ep: end point descriptor
 * @window: registration window
 * @offset: Offset to be freed
 *
 * Free offset for this EP. The callee is supposed to grab
 * the RMA mutex before calling this API.
 */
void scif_free_window_offset(struct scif_endpt *ep,
			     struct scif_window *window, s64 offset)
{
	if ((window && !window->offset_freed) || !window) {
		free_iova(&ep->rma_info.iovad, offset >> PAGE_SHIFT);
		if (window)
			window->offset_freed = true;
	}
}

/**
 * scif_alloc_req: Respond to SCIF_ALLOC_REQ interrupt message
 * @msg:        Interrupt message
 *
 * Remote side is requesting a memory allocation.
 */
void scif_alloc_req(struct scif_dev *scifdev, struct scifmsg *msg)
{
	int err;
	struct scif_window *window = NULL;
	int nr_pages = msg->payload[1];

	window = scif_create_remote_window(scifdev, nr_pages);
	if (!window) {
		err = -ENOMEM;
		goto error;
	}

	/* The peer's allocation request is granted */
	msg->uop = SCIF_ALLOC_GNT;
	msg->payload[0] = (u64)window;
	msg->payload[1] = window->mapped_offset;
	err = scif_nodeqp_send(scifdev, msg);
	if (err)
		scif_destroy_remote_window(window);
	return;
error:
	/* The peer's allocation request is rejected */
	dev_err(&scifdev->sdev->dev,
		"%s %d error %d alloc_ptr %p nr_pages 0x%x\n",
		__func__, __LINE__, err, window, nr_pages);
	msg->uop = SCIF_ALLOC_REJ;
	scif_nodeqp_send(scifdev, msg);
}

/**
 * scif_alloc_gnt_rej: Respond to SCIF_ALLOC_GNT/REJ interrupt message
 * @msg:        Interrupt message
 *
 * Remote side responded to a memory allocation.
 */
void scif_alloc_gnt_rej(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_allocmsg *handle = (struct scif_allocmsg *)msg->payload[2];
	struct scif_window *window = container_of(handle, struct scif_window,
						  alloc_handle);
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;

	mutex_lock(&ep->rma_info.rma_lock);
	handle->vaddr = msg->payload[0];
	handle->phys_addr = msg->payload[1];
	if (msg->uop == SCIF_ALLOC_GNT)
		handle->state = OP_COMPLETED;
	else
		handle->state = OP_FAILED;
	wake_up(&handle->allocwq);
	mutex_unlock(&ep->rma_info.rma_lock);
}

/**
 * scif_free_virt: Respond to SCIF_FREE_VIRT interrupt message
 * @msg:        Interrupt message
 *
 * Free up memory kmalloc'd earlier.
 */
void scif_free_virt(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_window *window = (struct scif_window *)msg->payload[1];

	scif_destroy_remote_window(window);
}

static void
scif_fixup_aper_base(struct scif_dev *dev, struct scif_window *window)
{
	int j;
	struct scif_hw_dev *sdev = dev->sdev;
	phys_addr_t apt_base = 0;

	/*
	 * Add the aperture base if the DMA address is not card relative
	 * since the DMA addresses need to be an offset into the bar
	 */
	if (!scifdev_self(dev) && window->type == SCIF_WINDOW_PEER &&
	    sdev->aper && !sdev->card_rel_da)
		apt_base = sdev->aper->pa;
	else
		return;

	for (j = 0; j < window->nr_contig_chunks; j++) {
		if (window->num_pages[j])
			window->dma_addr[j] += apt_base;
		else
			break;
	}
}

/**
 * scif_recv_reg: Respond to SCIF_REGISTER interrupt message
 * @msg:        Interrupt message
 *
 * Update remote window list with a new registered window.
 */
void scif_recv_reg(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
	struct scif_window *window =
		(struct scif_window *)msg->payload[1];

	mutex_lock(&ep->rma_info.rma_lock);
	spin_lock(&ep->lock);
	if (ep->state == SCIFEP_CONNECTED) {
		msg->uop = SCIF_REGISTER_ACK;
		scif_nodeqp_send(ep->remote_dev, msg);
		scif_fixup_aper_base(ep->remote_dev, window);
		/* No further failures expected. Insert new window */
		scif_insert_window(window, &ep->rma_info.remote_reg_list);
	} else {
		msg->uop = SCIF_REGISTER_NACK;
		scif_nodeqp_send(ep->remote_dev, msg);
	}
	spin_unlock(&ep->lock);
	mutex_unlock(&ep->rma_info.rma_lock);
	/* free up any lookup resources now that page lists are transferred */
	scif_destroy_remote_lookup(ep->remote_dev, window);
	/*
	 * We could not insert the window but we need to
	 * destroy the window.
	 */
	if (msg->uop == SCIF_REGISTER_NACK)
		scif_destroy_remote_window(window);
}

/**
 * scif_recv_unreg: Respond to SCIF_UNREGISTER interrupt message
 * @msg:        Interrupt message
 *
 * Remove window from remote registration list;
 */
void scif_recv_unreg(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_rma_req req;
	struct scif_window *window = NULL;
	struct scif_window *recv_window =
		(struct scif_window *)msg->payload[0];
	struct scif_endpt *ep;
	int del_window = 0;

	ep = (struct scif_endpt *)recv_window->ep;
	req.out_window = &window;
	req.offset = recv_window->offset;
	req.prot = 0;
	req.nr_bytes = recv_window->nr_pages << PAGE_SHIFT;
	req.type = SCIF_WINDOW_FULL;
	req.head = &ep->rma_info.remote_reg_list;
	msg->payload[0] = ep->remote_ep;

	mutex_lock(&ep->rma_info.rma_lock);
	/* Does a valid window exist? */
	if (scif_query_window(&req)) {
		dev_err(&scifdev->sdev->dev,
			"%s %d -ENXIO\n", __func__, __LINE__);
		msg->uop = SCIF_UNREGISTER_ACK;
		goto error;
	}
	if (window) {
		if (window->ref_count)
			scif_put_window(window, window->nr_pages);
		else
			dev_err(&scifdev->sdev->dev,
				"%s %d ref count should be +ve\n",
				__func__, __LINE__);
		window->unreg_state = OP_COMPLETED;
		if (!window->ref_count) {
			msg->uop = SCIF_UNREGISTER_ACK;
			atomic_inc(&ep->rma_info.tw_refcount);
			ep->rma_info.async_list_del = 1;
			list_del_init(&window->list);
			del_window = 1;
		} else {
			/* NACK! There are valid references to this window */
			msg->uop = SCIF_UNREGISTER_NACK;
		}
	} else {
		/* The window did not make its way to the list at all. ACK */
		msg->uop = SCIF_UNREGISTER_ACK;
		scif_destroy_remote_window(recv_window);
	}
error:
	mutex_unlock(&ep->rma_info.rma_lock);
	if (del_window)
		scif_drain_dma_intr(ep->remote_dev->sdev,
				    ep->rma_info.dma_chan);
	scif_nodeqp_send(ep->remote_dev, msg);
	if (del_window)
		scif_queue_for_cleanup(window, &scif_info.rma);
}

/**
 * scif_recv_reg_ack: Respond to SCIF_REGISTER_ACK interrupt message
 * @msg:        Interrupt message
 *
 * Wake up the window waiting to complete registration.
 */
void scif_recv_reg_ack(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_window *window =
		(struct scif_window *)msg->payload[2];
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;

	mutex_lock(&ep->rma_info.rma_lock);
	window->reg_state = OP_COMPLETED;
	wake_up(&window->regwq);
	mutex_unlock(&ep->rma_info.rma_lock);
}

/**
 * scif_recv_reg_nack: Respond to SCIF_REGISTER_NACK interrupt message
 * @msg:        Interrupt message
 *
 * Wake up the window waiting to inform it that registration
 * cannot be completed.
 */
void scif_recv_reg_nack(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_window *window =
		(struct scif_window *)msg->payload[2];
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;

	mutex_lock(&ep->rma_info.rma_lock);
	window->reg_state = OP_FAILED;
	wake_up(&window->regwq);
	mutex_unlock(&ep->rma_info.rma_lock);
}

/**
 * scif_recv_unreg_ack: Respond to SCIF_UNREGISTER_ACK interrupt message
 * @msg:        Interrupt message
 *
 * Wake up the window waiting to complete unregistration.
 */
void scif_recv_unreg_ack(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_window *window =
		(struct scif_window *)msg->payload[1];
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;

	mutex_lock(&ep->rma_info.rma_lock);
	window->unreg_state = OP_COMPLETED;
	wake_up(&window->unregwq);
	mutex_unlock(&ep->rma_info.rma_lock);
}

/**
 * scif_recv_unreg_nack: Respond to SCIF_UNREGISTER_NACK interrupt message
 * @msg:        Interrupt message
 *
 * Wake up the window waiting to inform it that unregistration
 * cannot be completed immediately.
 */
void scif_recv_unreg_nack(struct scif_dev *scifdev, struct scifmsg *msg)
{
	struct scif_window *window =
		(struct scif_window *)msg->payload[1];
	struct scif_endpt *ep = (struct scif_endpt *)window->ep;

	mutex_lock(&ep->rma_info.rma_lock);
	window->unreg_state = OP_FAILED;
	wake_up(&window->unregwq);
	mutex_unlock(&ep->rma_info.rma_lock);
}

int __scif_pin_pages(void *addr, size_t len, int *out_prot,
		     int map_flags, scif_pinned_pages_t *pages)
{
	struct scif_pinned_pages *pinned_pages;
	int nr_pages, err = 0, i;
	bool vmalloc_addr = false;
	bool try_upgrade = false;
	int prot = *out_prot;
	int ulimit = 0;
	struct mm_struct *mm = NULL;

	/* Unsupported flags */
	if (map_flags & ~(SCIF_MAP_KERNEL | SCIF_MAP_ULIMIT))
		return -EINVAL;
	ulimit = !!(map_flags & SCIF_MAP_ULIMIT);

	/* Unsupported protection requested */
	if (prot & ~(SCIF_PROT_READ | SCIF_PROT_WRITE))
		return -EINVAL;

	/* addr/len must be page aligned. len should be non zero */
	if (!len ||
	    (ALIGN((u64)addr, PAGE_SIZE) != (u64)addr) ||
	    (ALIGN((u64)len, PAGE_SIZE) != (u64)len))
		return -EINVAL;

	might_sleep();

	nr_pages = len >> PAGE_SHIFT;

	/* Allocate a set of pinned pages */
	pinned_pages = scif_create_pinned_pages(nr_pages, prot);
	if (!pinned_pages)
		return -ENOMEM;

	if (map_flags & SCIF_MAP_KERNEL) {
		if (is_vmalloc_addr(addr))
			vmalloc_addr = true;

		for (i = 0; i < nr_pages; i++) {
			if (vmalloc_addr)
				pinned_pages->pages[i] =
					vmalloc_to_page(addr + (i * PAGE_SIZE));
			else
				pinned_pages->pages[i] =
					virt_to_page(addr + (i * PAGE_SIZE));
		}
		pinned_pages->nr_pages = nr_pages;
		pinned_pages->map_flags = SCIF_MAP_KERNEL;
	} else {
		/*
		 * SCIF supports registration caching. If a registration has
		 * been requested with read only permissions, then we try
		 * to pin the pages with RW permissions so that a subsequent
		 * transfer with RW permission can hit the cache instead of
		 * invalidating it. If the upgrade fails with RW then we
		 * revert back to R permission and retry
		 */
		if (prot == SCIF_PROT_READ)
			try_upgrade = true;
		prot |= SCIF_PROT_WRITE;
retry:
		mm = current->mm;
		down_write(&mm->mmap_sem);
		if (ulimit) {
			err = __scif_check_inc_pinned_vm(mm, nr_pages);
			if (err) {
				up_write(&mm->mmap_sem);
				pinned_pages->nr_pages = 0;
				goto error_unmap;
			}
		}

		pinned_pages->nr_pages = get_user_pages(
				(u64)addr,
				nr_pages,
				(prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0,
				pinned_pages->pages,
				NULL);
		up_write(&mm->mmap_sem);
		if (nr_pages != pinned_pages->nr_pages) {
			if (try_upgrade) {
				if (ulimit)
					__scif_dec_pinned_vm_lock(mm,
								  nr_pages, 0);
				/* Roll back any pinned pages */
				for (i = 0; i < pinned_pages->nr_pages; i++) {
					if (pinned_pages->pages[i])
						put_page(
						pinned_pages->pages[i]);
				}
				prot &= ~SCIF_PROT_WRITE;
				try_upgrade = false;
				goto retry;
			}
		}
		pinned_pages->map_flags = 0;
	}

	if (pinned_pages->nr_pages < nr_pages) {
		err = -EFAULT;
		pinned_pages->nr_pages = nr_pages;
		goto dec_pinned;
	}

	*out_prot = prot;
	atomic_set(&pinned_pages->ref_count, 1);
	*pages = pinned_pages;
	return err;
dec_pinned:
	if (ulimit)
		__scif_dec_pinned_vm_lock(mm, nr_pages, 0);
	/* Something went wrong! Rollback */
error_unmap:
	pinned_pages->nr_pages = nr_pages;
	scif_destroy_pinned_pages(pinned_pages);
	*pages = NULL;
	dev_dbg(scif_info.mdev.this_device,
		"%s %d err %d len 0x%lx\n", __func__, __LINE__, err, len);
	return err;
}

int scif_pin_pages(void *addr, size_t len, int prot,
		   int map_flags, scif_pinned_pages_t *pages)
{
	return __scif_pin_pages(addr, len, &prot, map_flags, pages);
}
EXPORT_SYMBOL_GPL(scif_pin_pages);

int scif_unpin_pages(scif_pinned_pages_t pinned_pages)
{
	int err = 0, ret;

	if (!pinned_pages || SCIFEP_MAGIC != pinned_pages->magic)
		return -EINVAL;

	ret = atomic_sub_return(1, &pinned_pages->ref_count);
	if (ret < 0) {
		dev_err(scif_info.mdev.this_device,
			"%s %d scif_unpin_pages called without pinning? rc %d\n",
			__func__, __LINE__, ret);
		return -EINVAL;
	}
	/*
	 * Destroy the window if the ref count for this set of pinned
	 * pages has dropped to zero. If it is positive then there is
	 * a valid registered window which is backed by these pages and
	 * it will be destroyed once all such windows are unregistered.
	 */
	if (!ret)
		err = scif_destroy_pinned_pages(pinned_pages);

	return err;
}
EXPORT_SYMBOL_GPL(scif_unpin_pages);

static inline void
scif_insert_local_window(struct scif_window *window, struct scif_endpt *ep)
{
	mutex_lock(&ep->rma_info.rma_lock);
	scif_insert_window(window, &ep->rma_info.reg_list);
	mutex_unlock(&ep->rma_info.rma_lock);
}

off_t scif_register_pinned_pages(scif_epd_t epd,
				 scif_pinned_pages_t pinned_pages,
				 off_t offset, int map_flags)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	s64 computed_offset;
	struct scif_window *window;
	int err;
	size_t len;
	struct device *spdev;

	/* Unsupported flags */
	if (map_flags & ~SCIF_MAP_FIXED)
		return -EINVAL;

	len = pinned_pages->nr_pages << PAGE_SHIFT;

	/*
	 * Offset is not page aligned/negative or offset+len
	 * wraps around with SCIF_MAP_FIXED.
	 */
	if ((map_flags & SCIF_MAP_FIXED) &&
	    ((ALIGN(offset, PAGE_SIZE) != offset) ||
	    (offset < 0) ||
	    (len > LONG_MAX - offset)))
		return -EINVAL;

	might_sleep();

	err = scif_verify_epd(ep);
	if (err)
		return err;
	/*
	 * It is an error to pass pinned_pages to scif_register_pinned_pages()
	 * after calling scif_unpin_pages().
	 */
	if (!atomic_add_unless(&pinned_pages->ref_count, 1, 0))
		return -EINVAL;

	/* Compute the offset for this registration */
	err = scif_get_window_offset(ep, map_flags, offset,
				     len, &computed_offset);
	if (err) {
		atomic_sub(1, &pinned_pages->ref_count);
		return err;
	}

	/* Allocate and prepare self registration window */
	window = scif_create_window(ep, pinned_pages->nr_pages,
				    computed_offset, false);
	if (!window) {
		atomic_sub(1, &pinned_pages->ref_count);
		scif_free_window_offset(ep, NULL, computed_offset);
		return -ENOMEM;
	}

	window->pinned_pages = pinned_pages;
	window->nr_pages = pinned_pages->nr_pages;
	window->prot = pinned_pages->prot;

	spdev = scif_get_peer_dev(ep->remote_dev);
	if (IS_ERR(spdev)) {
		err = PTR_ERR(spdev);
		scif_destroy_window(ep, window);
		return err;
	}
	err = scif_send_alloc_request(ep, window);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto error_unmap;
	}

	/* Prepare the remote registration window */
	err = scif_prep_remote_window(ep, window);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto error_unmap;
	}

	/* Tell the peer about the new window */
	err = scif_send_scif_register(ep, window);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto error_unmap;
	}

	scif_put_peer_dev(spdev);
	/* No further failures expected. Insert new window */
	scif_insert_local_window(window, ep);
	return computed_offset;
error_unmap:
	scif_destroy_window(ep, window);
	scif_put_peer_dev(spdev);
	dev_err(&ep->remote_dev->sdev->dev,
		"%s %d err %d\n", __func__, __LINE__, err);
	return err;
}
EXPORT_SYMBOL_GPL(scif_register_pinned_pages);

off_t scif_register(scif_epd_t epd, void *addr, size_t len, off_t offset,
		    int prot, int map_flags)
{
	scif_pinned_pages_t pinned_pages;
	off_t err;
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	s64 computed_offset;
	struct scif_window *window;
	struct mm_struct *mm = NULL;
	struct device *spdev;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI register: ep %p addr %p len 0x%lx offset 0x%lx prot 0x%x map_flags 0x%x\n",
		epd, addr, len, offset, prot, map_flags);
	/* Unsupported flags */
	if (map_flags & ~(SCIF_MAP_FIXED | SCIF_MAP_KERNEL))
		return -EINVAL;

	/*
	 * Offset is not page aligned/negative or offset+len
	 * wraps around with SCIF_MAP_FIXED.
	 */
	if ((map_flags & SCIF_MAP_FIXED) &&
	    ((ALIGN(offset, PAGE_SIZE) != offset) ||
	    (offset < 0) ||
	    (len > LONG_MAX - offset)))
		return -EINVAL;

	/* Unsupported protection requested */
	if (prot & ~(SCIF_PROT_READ | SCIF_PROT_WRITE))
		return -EINVAL;

	/* addr/len must be page aligned. len should be non zero */
	if (!len || (ALIGN((u64)addr, PAGE_SIZE) != (u64)addr) ||
	    (ALIGN(len, PAGE_SIZE) != len))
		return -EINVAL;

	might_sleep();

	err = scif_verify_epd(ep);
	if (err)
		return err;

	/* Compute the offset for this registration */
	err = scif_get_window_offset(ep, map_flags, offset,
				     len >> PAGE_SHIFT, &computed_offset);
	if (err)
		return err;

	spdev = scif_get_peer_dev(ep->remote_dev);
	if (IS_ERR(spdev)) {
		err = PTR_ERR(spdev);
		scif_free_window_offset(ep, NULL, computed_offset);
		return err;
	}
	/* Allocate and prepare self registration window */
	window = scif_create_window(ep, len >> PAGE_SHIFT,
				    computed_offset, false);
	if (!window) {
		scif_free_window_offset(ep, NULL, computed_offset);
		scif_put_peer_dev(spdev);
		return -ENOMEM;
	}

	window->nr_pages = len >> PAGE_SHIFT;

	err = scif_send_alloc_request(ep, window);
	if (err) {
		scif_destroy_incomplete_window(ep, window);
		scif_put_peer_dev(spdev);
		return err;
	}

	if (!(map_flags & SCIF_MAP_KERNEL)) {
		mm = __scif_acquire_mm();
		map_flags |= SCIF_MAP_ULIMIT;
	}
	/* Pin down the pages */
	err = __scif_pin_pages(addr, len, &prot,
			       map_flags & (SCIF_MAP_KERNEL | SCIF_MAP_ULIMIT),
			       &pinned_pages);
	if (err) {
		scif_destroy_incomplete_window(ep, window);
		__scif_release_mm(mm);
		goto error;
	}

	window->pinned_pages = pinned_pages;
	window->prot = pinned_pages->prot;
	window->mm = mm;

	/* Prepare the remote registration window */
	err = scif_prep_remote_window(ep, window);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %ld\n", __func__, __LINE__, err);
		goto error_unmap;
	}

	/* Tell the peer about the new window */
	err = scif_send_scif_register(ep, window);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %ld\n", __func__, __LINE__, err);
		goto error_unmap;
	}

	scif_put_peer_dev(spdev);
	/* No further failures expected. Insert new window */
	scif_insert_local_window(window, ep);
	dev_dbg(&ep->remote_dev->sdev->dev,
		"SCIFAPI register: ep %p addr %p len 0x%lx computed_offset 0x%llx\n",
		epd, addr, len, computed_offset);
	return computed_offset;
error_unmap:
	scif_destroy_window(ep, window);
error:
	scif_put_peer_dev(spdev);
	dev_err(&ep->remote_dev->sdev->dev,
		"%s %d err %ld\n", __func__, __LINE__, err);
	return err;
}
EXPORT_SYMBOL_GPL(scif_register);

int
scif_unregister(scif_epd_t epd, off_t offset, size_t len)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	struct scif_window *window = NULL;
	struct scif_rma_req req;
	int nr_pages, err;
	struct device *spdev;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI unregister: ep %p offset 0x%lx len 0x%lx\n",
		ep, offset, len);
	/* len must be page aligned. len should be non zero */
	if (!len ||
	    (ALIGN((u64)len, PAGE_SIZE) != (u64)len))
		return -EINVAL;

	/* Offset is not page aligned or offset+len wraps around */
	if ((ALIGN(offset, PAGE_SIZE) != offset) ||
	    (offset < 0) ||
	    (len > LONG_MAX - offset))
		return -EINVAL;

	err = scif_verify_epd(ep);
	if (err)
		return err;

	might_sleep();
	nr_pages = len >> PAGE_SHIFT;

	req.out_window = &window;
	req.offset = offset;
	req.prot = 0;
	req.nr_bytes = len;
	req.type = SCIF_WINDOW_FULL;
	req.head = &ep->rma_info.reg_list;

	spdev = scif_get_peer_dev(ep->remote_dev);
	if (IS_ERR(spdev)) {
		err = PTR_ERR(spdev);
		return err;
	}
	mutex_lock(&ep->rma_info.rma_lock);
	/* Does a valid window exist? */
	err = scif_query_window(&req);
	if (err) {
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
		goto error;
	}
	/* Unregister all the windows in this range */
	err = scif_rma_list_unregister(window, offset, nr_pages);
	if (err)
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
error:
	mutex_unlock(&ep->rma_info.rma_lock);
	scif_put_peer_dev(spdev);
	return err;
}
EXPORT_SYMBOL_GPL(scif_unregister);
