// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2020-21 IBM Corp.
 */

#define pr_fmt(fmt) "vas: " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <asm/machdep.h>
#include <asm/hvcall.h>
#include <asm/plpar_wrappers.h>
#include <asm/firmware.h>
#include <asm/vas.h>
#include "vas.h"

#define VAS_INVALID_WIN_ADDRESS	0xFFFFFFFFFFFFFFFFul
#define VAS_DEFAULT_DOMAIN_ID	0xFFFFFFFFFFFFFFFFul
/* The hypervisor allows one credit per window right now */
#define DEF_WIN_CREDS		1

static struct vas_all_caps caps_all;
static bool copypaste_feat;
static struct hv_vas_cop_feat_caps hv_cop_caps;

static struct vas_caps vascaps[VAS_MAX_FEAT_TYPE];
static DEFINE_MUTEX(vas_pseries_mutex);
static bool migration_in_progress;

static long hcall_return_busy_check(long rc)
{
	/* Check if we are stalled for some time */
	if (H_IS_LONG_BUSY(rc)) {
		msleep(get_longbusy_msecs(rc));
		rc = H_BUSY;
	} else if (rc == H_BUSY) {
		cond_resched();
	}

	return rc;
}

/*
 * Allocate VAS window hcall
 */
static int h_allocate_vas_window(struct pseries_vas_window *win, u64 *domain,
				     u8 wintype, u16 credits)
{
	long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
	long rc;

	do {
		rc = plpar_hcall9(H_ALLOCATE_VAS_WINDOW, retbuf, wintype,
				  credits, domain[0], domain[1], domain[2],
				  domain[3], domain[4], domain[5]);

		rc = hcall_return_busy_check(rc);
	} while (rc == H_BUSY);

	if (rc == H_SUCCESS) {
		if (win->win_addr == VAS_INVALID_WIN_ADDRESS) {
			pr_err("H_ALLOCATE_VAS_WINDOW: COPY/PASTE is not supported\n");
			return -ENOTSUPP;
		}
		win->vas_win.winid = retbuf[0];
		win->win_addr = retbuf[1];
		win->complete_irq = retbuf[2];
		win->fault_irq = retbuf[3];
		return 0;
	}

	pr_err("H_ALLOCATE_VAS_WINDOW error: %ld, wintype: %u, credits: %u\n",
		rc, wintype, credits);

	return -EIO;
}

/*
 * Deallocate VAS window hcall.
 */
static int h_deallocate_vas_window(u64 winid)
{
	long rc;

	do {
		rc = plpar_hcall_norets(H_DEALLOCATE_VAS_WINDOW, winid);

		rc = hcall_return_busy_check(rc);
	} while (rc == H_BUSY);

	if (rc == H_SUCCESS)
		return 0;

	pr_err("H_DEALLOCATE_VAS_WINDOW error: %ld, winid: %llu\n",
		rc, winid);
	return -EIO;
}

/*
 * Modify VAS window.
 * After the window is opened with allocate window hcall, configure it
 * with flags and LPAR PID before using.
 */
static int h_modify_vas_window(struct pseries_vas_window *win)
{
	long rc;

	/*
	 * AMR value is not supported in Linux VAS implementation.
	 * The hypervisor ignores it if 0 is passed.
	 */
	do {
		rc = plpar_hcall_norets(H_MODIFY_VAS_WINDOW,
					win->vas_win.winid, win->pid, 0,
					VAS_MOD_WIN_FLAGS, 0);

		rc = hcall_return_busy_check(rc);
	} while (rc == H_BUSY);

	if (rc == H_SUCCESS)
		return 0;

	pr_err("H_MODIFY_VAS_WINDOW error: %ld, winid %u pid %u\n",
			rc, win->vas_win.winid, win->pid);
	return -EIO;
}

/*
 * This hcall is used to determine the capabilities from the hypervisor.
 * @hcall: H_QUERY_VAS_CAPABILITIES or H_QUERY_NX_CAPABILITIES
 * @query_type: If 0 is passed, the hypervisor returns the overall
 *		capabilities which provides all feature(s) that are
 *		available. Then query the hypervisor to get the
 *		corresponding capabilities for the specific feature.
 *		Example: H_QUERY_VAS_CAPABILITIES provides VAS GZIP QoS
 *			and VAS GZIP Default capabilities.
 *			H_QUERY_NX_CAPABILITIES provides NX GZIP
 *			capabilities.
 * @result: Return buffer to save capabilities.
 */
int h_query_vas_capabilities(const u64 hcall, u8 query_type, u64 result)
{
	long rc;

	rc = plpar_hcall_norets(hcall, query_type, result);

	if (rc == H_SUCCESS)
		return 0;

	/* H_FUNCTION means HV does not support VAS so don't print an error */
	if (rc != H_FUNCTION) {
		pr_err("%s error %ld, query_type %u, result buffer 0x%llx\n",
			(hcall == H_QUERY_VAS_CAPABILITIES) ?
				"H_QUERY_VAS_CAPABILITIES" :
				"H_QUERY_NX_CAPABILITIES",
			rc, query_type, result);
	}

	return -EIO;
}
EXPORT_SYMBOL_GPL(h_query_vas_capabilities);

/*
 * hcall to get fault CRB from the hypervisor.
 */
static int h_get_nx_fault(u32 winid, u64 buffer)
{
	long rc;

	rc = plpar_hcall_norets(H_GET_NX_FAULT, winid, buffer);

	if (rc == H_SUCCESS)
		return 0;

	pr_err("H_GET_NX_FAULT error: %ld, winid %u, buffer 0x%llx\n",
		rc, winid, buffer);
	return -EIO;

}

/*
 * Handle the fault interrupt.
 * When the fault interrupt is received for each window, query the
 * hypervisor to get the fault CRB on the specific fault. Then
 * process the CRB by updating CSB or send signal if the user space
 * CSB is invalid.
 * Note: The hypervisor forwards an interrupt for each fault request.
 *	So one fault CRB to process for each H_GET_NX_FAULT hcall.
 */
static irqreturn_t pseries_vas_fault_thread_fn(int irq, void *data)
{
	struct pseries_vas_window *txwin = data;
	struct coprocessor_request_block crb;
	struct vas_user_win_ref *tsk_ref;
	int rc;

	rc = h_get_nx_fault(txwin->vas_win.winid, (u64)virt_to_phys(&crb));
	if (!rc) {
		tsk_ref = &txwin->vas_win.task_ref;
		vas_dump_crb(&crb);
		vas_update_csb(&crb, tsk_ref);
	}

	return IRQ_HANDLED;
}

/*
 * Allocate window and setup IRQ mapping.
 */
static int allocate_setup_window(struct pseries_vas_window *txwin,
				 u64 *domain, u8 wintype)
{
	int rc;

	rc = h_allocate_vas_window(txwin, domain, wintype, DEF_WIN_CREDS);
	if (rc)
		return rc;
	/*
	 * On PowerVM, the hypervisor setup and forwards the fault
	 * interrupt per window. So the IRQ setup and fault handling
	 * will be done for each open window separately.
	 */
	txwin->fault_virq = irq_create_mapping(NULL, txwin->fault_irq);
	if (!txwin->fault_virq) {
		pr_err("Failed irq mapping %d\n", txwin->fault_irq);
		rc = -EINVAL;
		goto out_win;
	}

	txwin->name = kasprintf(GFP_KERNEL, "vas-win-%d",
				txwin->vas_win.winid);
	if (!txwin->name) {
		rc = -ENOMEM;
		goto out_irq;
	}

	rc = request_threaded_irq(txwin->fault_virq, NULL,
				  pseries_vas_fault_thread_fn, IRQF_ONESHOT,
				  txwin->name, txwin);
	if (rc) {
		pr_err("VAS-Window[%d]: Request IRQ(%u) failed with %d\n",
		       txwin->vas_win.winid, txwin->fault_virq, rc);
		goto out_free;
	}

	txwin->vas_win.wcreds_max = DEF_WIN_CREDS;

	return 0;
out_free:
	kfree(txwin->name);
out_irq:
	irq_dispose_mapping(txwin->fault_virq);
out_win:
	h_deallocate_vas_window(txwin->vas_win.winid);
	return rc;
}

static inline void free_irq_setup(struct pseries_vas_window *txwin)
{
	free_irq(txwin->fault_virq, txwin);
	kfree(txwin->name);
	irq_dispose_mapping(txwin->fault_virq);
}

static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
					      enum vas_cop_type cop_type)
{
	long domain[PLPAR_HCALL9_BUFSIZE] = {VAS_DEFAULT_DOMAIN_ID};
	struct vas_cop_feat_caps *cop_feat_caps;
	struct vas_caps *caps;
	struct pseries_vas_window *txwin;
	int rc;

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

	/*
	 * A VAS window can have many credits which means that many
	 * requests can be issued simultaneously. But the hypervisor
	 * restricts one credit per window.
	 * The hypervisor introduces 2 different types of credits:
	 * Default credit type (Uses normal priority FIFO):
	 *	A limited number of credits are assigned to partitions
	 *	based on processor entitlement. But these credits may be
	 *	over-committed on a system depends on whether the CPUs
	 *	are in shared or dedicated modes - that is, more requests
	 *	may be issued across the system than NX can service at
	 *	once which can result in paste command failure (RMA_busy).
	 *	Then the process has to resend requests or fall-back to
	 *	SW compression.
	 * Quality of Service (QoS) credit type (Uses high priority FIFO):
	 *	To avoid NX HW contention, the system admins can assign
	 *	QoS credits for each LPAR so that this partition is
	 *	guaranteed access to NX resources. These credits are
	 *	assigned to partitions via the HMC.
	 *	Refer PAPR for more information.
	 *
	 * Allocate window with QoS credits if user requested. Otherwise
	 * default credits are used.
	 */
	if (flags & VAS_TX_WIN_FLAG_QOS_CREDIT)
		caps = &vascaps[VAS_GZIP_QOS_FEAT_TYPE];
	else
		caps = &vascaps[VAS_GZIP_DEF_FEAT_TYPE];

	cop_feat_caps = &caps->caps;

	if (atomic_inc_return(&cop_feat_caps->nr_used_credits) >
			atomic_read(&cop_feat_caps->nr_total_credits)) {
		pr_err("Credits are not available to allocate window\n");
		rc = -EINVAL;
		goto out;
	}

	if (vas_id == -1) {
		/*
		 * The user space is requesting to allocate a window on
		 * a VAS instance where the process is executing.
		 * On PowerVM, domain values are passed to the hypervisor
		 * to select VAS instance. Useful if the process is
		 * affinity to NUMA node.
		 * The hypervisor selects VAS instance if
		 * VAS_DEFAULT_DOMAIN_ID (-1) is passed for domain values.
		 * The h_allocate_vas_window hcall is defined to take a
		 * domain values as specified by h_home_node_associativity,
		 * So no unpacking needs to be done.
		 */
		rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, domain,
				  VPHN_FLAG_VCPU, hard_smp_processor_id());
		if (rc != H_SUCCESS) {
			pr_err("H_HOME_NODE_ASSOCIATIVITY error: %d\n", rc);
			goto out;
		}
	}

	txwin->pid = mfspr(SPRN_PID);

	/*
	 * Allocate / Deallocate window hcalls and setup / free IRQs
	 * have to be protected with mutex.
	 * Open VAS window: Allocate window hcall and setup IRQ
	 * Close VAS window: Deallocate window hcall and free IRQ
	 *	The hypervisor waits until all NX requests are
	 *	completed before closing the window. So expects OS
	 *	to handle NX faults, means IRQ can be freed only
	 *	after the deallocate window hcall is returned.
	 * So once the window is closed with deallocate hcall before
	 * the IRQ is freed, it can be assigned to new allocate
	 * hcall with the same fault IRQ by the hypervisor. It can
	 * result in setup IRQ fail for the new window since the
	 * same fault IRQ is not freed by the OS before.
	 */
	mutex_lock(&vas_pseries_mutex);
	if (migration_in_progress)
		rc = -EBUSY;
	else
		rc = allocate_setup_window(txwin, (u64 *)&domain[0],
				   cop_feat_caps->win_type);
	mutex_unlock(&vas_pseries_mutex);
	if (rc)
		goto out;

	/*
	 * Modify window and it is ready to use.
	 */
	rc = h_modify_vas_window(txwin);
	if (!rc)
		rc = get_vas_user_win_ref(&txwin->vas_win.task_ref);
	if (rc)
		goto out_free;

	txwin->win_type = cop_feat_caps->win_type;
	mutex_lock(&vas_pseries_mutex);
	/*
	 * Possible to lose the acquired credit with DLPAR core
	 * removal after the window is opened. So if there are any
	 * closed windows (means with lost credits), do not give new
	 * window to user space. New windows will be opened only
	 * after the existing windows are reopened when credits are
	 * available.
	 */
	if (!caps->nr_close_wins) {
		list_add(&txwin->win_list, &caps->list);
		caps->nr_open_windows++;
		mutex_unlock(&vas_pseries_mutex);
		vas_user_win_add_mm_context(&txwin->vas_win.task_ref);
		return &txwin->vas_win;
	}
	mutex_unlock(&vas_pseries_mutex);

	put_vas_user_win_ref(&txwin->vas_win.task_ref);
	rc = -EBUSY;
	pr_err("No credit is available to allocate window\n");

out_free:
	/*
	 * Window is not operational. Free IRQ before closing
	 * window so that do not have to hold mutex.
	 */
	free_irq_setup(txwin);
	h_deallocate_vas_window(txwin->vas_win.winid);
out:
	atomic_dec(&cop_feat_caps->nr_used_credits);
	kfree(txwin);
	return ERR_PTR(rc);
}

static u64 vas_paste_address(struct vas_window *vwin)
{
	struct pseries_vas_window *win;

	win = container_of(vwin, struct pseries_vas_window, vas_win);
	return win->win_addr;
}

static int deallocate_free_window(struct pseries_vas_window *win)
{
	int rc = 0;

	/*
	 * The hypervisor waits for all requests including faults
	 * are processed before closing the window - Means all
	 * credits have to be returned. In the case of fault
	 * request, a credit is returned after OS issues
	 * H_GET_NX_FAULT hcall.
	 * So free IRQ after executing H_DEALLOCATE_VAS_WINDOW
	 * hcall.
	 */
	rc = h_deallocate_vas_window(win->vas_win.winid);
	if (!rc)
		free_irq_setup(win);

	return rc;
}

static int vas_deallocate_window(struct vas_window *vwin)
{
	struct pseries_vas_window *win;
	struct vas_cop_feat_caps *caps;
	int rc = 0;

	if (!vwin)
		return -EINVAL;

	win = container_of(vwin, struct pseries_vas_window, vas_win);

	/* Should not happen */
	if (win->win_type >= VAS_MAX_FEAT_TYPE) {
		pr_err("Window (%u): Invalid window type %u\n",
				vwin->winid, win->win_type);
		return -EINVAL;
	}

	caps = &vascaps[win->win_type].caps;
	mutex_lock(&vas_pseries_mutex);
	/*
	 * VAS window is already closed in the hypervisor when
	 * lost the credit or with migration. So just remove the entry
	 * from the list, remove task references and free vas_window
	 * struct.
	 */
	if (!(win->vas_win.status & VAS_WIN_NO_CRED_CLOSE) &&
		!(win->vas_win.status & VAS_WIN_MIGRATE_CLOSE)) {
		rc = deallocate_free_window(win);
		if (rc) {
			mutex_unlock(&vas_pseries_mutex);
			return rc;
		}
	} else
		vascaps[win->win_type].nr_close_wins--;

	list_del(&win->win_list);
	atomic_dec(&caps->nr_used_credits);
	vascaps[win->win_type].nr_open_windows--;
	mutex_unlock(&vas_pseries_mutex);

	put_vas_user_win_ref(&vwin->task_ref);
	mm_context_remove_vas_window(vwin->task_ref.mm);

	kfree(win);
	return 0;
}

static const struct vas_user_win_ops vops_pseries = {
	.open_win	= vas_allocate_window,	/* Open and configure window */
	.paste_addr	= vas_paste_address,	/* To do copy/paste */
	.close_win	= vas_deallocate_window, /* Close window */
};

/*
 * Supporting only nx-gzip coprocessor type now, but this API code
 * extended to other coprocessor types later.
 */
int vas_register_api_pseries(struct module *mod, enum vas_cop_type cop_type,
			     const char *name)
{
	int rc;

	if (!copypaste_feat)
		return -ENOTSUPP;

	rc = vas_register_coproc_api(mod, cop_type, name, &vops_pseries);

	return rc;
}
EXPORT_SYMBOL_GPL(vas_register_api_pseries);

void vas_unregister_api_pseries(void)
{
	vas_unregister_coproc_api();
}
EXPORT_SYMBOL_GPL(vas_unregister_api_pseries);

/*
 * Get the specific capabilities based on the feature type.
 * Right now supports GZIP default and GZIP QoS capabilities.
 */
static int __init get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
				struct hv_vas_cop_feat_caps *hv_caps)
{
	struct vas_cop_feat_caps *caps;
	struct vas_caps *vcaps;
	int rc = 0;

	vcaps = &vascaps[type];
	memset(vcaps, 0, sizeof(*vcaps));
	INIT_LIST_HEAD(&vcaps->list);

	vcaps->feat = feat;
	caps = &vcaps->caps;

	rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, feat,
					  (u64)virt_to_phys(hv_caps));
	if (rc)
		return rc;

	caps->user_mode = hv_caps->user_mode;
	if (!(caps->user_mode & VAS_COPY_PASTE_USER_MODE)) {
		pr_err("User space COPY/PASTE is not supported\n");
		return -ENOTSUPP;
	}

	caps->descriptor = be64_to_cpu(hv_caps->descriptor);
	caps->win_type = hv_caps->win_type;
	if (caps->win_type >= VAS_MAX_FEAT_TYPE) {
		pr_err("Unsupported window type %u\n", caps->win_type);
		return -EINVAL;
	}
	caps->max_lpar_creds = be16_to_cpu(hv_caps->max_lpar_creds);
	caps->max_win_creds = be16_to_cpu(hv_caps->max_win_creds);
	atomic_set(&caps->nr_total_credits,
		   be16_to_cpu(hv_caps->target_lpar_creds));
	if (feat == VAS_GZIP_DEF_FEAT) {
		caps->def_lpar_creds = be16_to_cpu(hv_caps->def_lpar_creds);

		if (caps->max_win_creds < DEF_WIN_CREDS) {
			pr_err("Window creds(%u) > max allowed window creds(%u)\n",
			       DEF_WIN_CREDS, caps->max_win_creds);
			return -EINVAL;
		}
	}

	rc = sysfs_add_vas_caps(caps);
	if (rc)
		return rc;

	copypaste_feat = true;

	return 0;
}

/*
 * VAS windows can be closed due to lost credits when the core is
 * removed. So reopen them if credits are available due to DLPAR
 * core add and set the window active status. When NX sees the page
 * fault on the unmapped paste address, the kernel handles the fault
 * by setting the remapping to new paste address if the window is
 * active.
 */
static int reconfig_open_windows(struct vas_caps *vcaps, int creds,
				 bool migrate)
{
	long domain[PLPAR_HCALL9_BUFSIZE] = {VAS_DEFAULT_DOMAIN_ID};
	struct vas_cop_feat_caps *caps = &vcaps->caps;
	struct pseries_vas_window *win = NULL, *tmp;
	int rc, mv_ents = 0;
	int flag;

	/*
	 * Nothing to do if there are no closed windows.
	 */
	if (!vcaps->nr_close_wins)
		return 0;

	/*
	 * For the core removal, the hypervisor reduces the credits
	 * assigned to the LPAR and the kernel closes VAS windows
	 * in the hypervisor depends on reduced credits. The kernel
	 * uses LIFO (the last windows that are opened will be closed
	 * first) and expects to open in the same order when credits
	 * are available.
	 * For example, 40 windows are closed when the LPAR lost 2 cores
	 * (dedicated). If 1 core is added, this LPAR can have 20 more
	 * credits. It means the kernel can reopen 20 windows. So move
	 * 20 entries in the VAS windows lost and reopen next 20 windows.
	 * For partition migration, reopen all windows that are closed
	 * during resume.
	 */
	if ((vcaps->nr_close_wins > creds) && !migrate)
		mv_ents = vcaps->nr_close_wins - creds;

	list_for_each_entry_safe(win, tmp, &vcaps->list, win_list) {
		if (!mv_ents)
			break;

		mv_ents--;
	}

	/*
	 * Open windows if they are closed only with migration or
	 * DLPAR (lost credit) before.
	 */
	if (migrate)
		flag = VAS_WIN_MIGRATE_CLOSE;
	else
		flag = VAS_WIN_NO_CRED_CLOSE;

	list_for_each_entry_safe_from(win, tmp, &vcaps->list, win_list) {
		/*
		 * This window is closed with DLPAR and migration events.
		 * So reopen the window with the last event.
		 * The user space is not suspended with the current
		 * migration notifier. So the user space can issue DLPAR
		 * CPU hotplug while migration in progress. In this case
		 * this window will be opened with the last event.
		 */
		if ((win->vas_win.status & VAS_WIN_NO_CRED_CLOSE) &&
			(win->vas_win.status & VAS_WIN_MIGRATE_CLOSE)) {
			win->vas_win.status &= ~flag;
			continue;
		}

		/*
		 * Nothing to do on this window if it is not closed
		 * with this flag
		 */
		if (!(win->vas_win.status & flag))
			continue;

		rc = allocate_setup_window(win, (u64 *)&domain[0],
					   caps->win_type);
		if (rc)
			return rc;

		rc = h_modify_vas_window(win);
		if (rc)
			goto out;

		mutex_lock(&win->vas_win.task_ref.mmap_mutex);
		/*
		 * Set window status to active
		 */
		win->vas_win.status &= ~flag;
		mutex_unlock(&win->vas_win.task_ref.mmap_mutex);
		win->win_type = caps->win_type;
		if (!--vcaps->nr_close_wins)
			break;
	}

	return 0;
out:
	/*
	 * Window modify HCALL failed. So close the window to the
	 * hypervisor and return.
	 */
	free_irq_setup(win);
	h_deallocate_vas_window(win->vas_win.winid);
	return rc;
}

/*
 * The hypervisor reduces the available credits if the LPAR lost core. It
 * means the excessive windows should not be active and the user space
 * should not be using these windows to send compression requests to NX.
 * So the kernel closes the excessive windows and unmap the paste address
 * such that the user space receives paste instruction failure. Then up to
 * the user space to fall back to SW compression and manage with the
 * existing windows.
 */
static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
									bool migrate)
{
	struct pseries_vas_window *win, *tmp;
	struct vas_user_win_ref *task_ref;
	struct vm_area_struct *vma;
	int rc = 0, flag;

	if (migrate)
		flag = VAS_WIN_MIGRATE_CLOSE;
	else
		flag = VAS_WIN_NO_CRED_CLOSE;

	list_for_each_entry_safe(win, tmp, &vcap->list, win_list) {
		/*
		 * This window is already closed due to lost credit
		 * or for migration before. Go for next window.
		 * For migration, nothing to do since this window
		 * closed for DLPAR and will be reopened even on
		 * the destination system with other DLPAR operation.
		 */
		if ((win->vas_win.status & VAS_WIN_MIGRATE_CLOSE) ||
			(win->vas_win.status & VAS_WIN_NO_CRED_CLOSE)) {
			win->vas_win.status |= flag;
			continue;
		}

		task_ref = &win->vas_win.task_ref;
		mutex_lock(&task_ref->mmap_mutex);
		vma = task_ref->vma;
		/*
		 * Number of available credits are reduced, So select
		 * and close windows.
		 */
		win->vas_win.status |= flag;

		mmap_write_lock(task_ref->mm);
		/*
		 * vma is set in the original mapping. But this mapping
		 * is done with mmap() after the window is opened with ioctl.
		 * so we may not see the original mapping if the core remove
		 * is done before the original mmap() and after the ioctl.
		 */
		if (vma)
			zap_page_range(vma, vma->vm_start,
					vma->vm_end - vma->vm_start);

		mmap_write_unlock(task_ref->mm);
		mutex_unlock(&task_ref->mmap_mutex);
		/*
		 * Close VAS window in the hypervisor, but do not
		 * free vas_window struct since it may be reused
		 * when the credit is available later (DLPAR with
		 * adding cores). This struct will be used
		 * later when the process issued with close(FD).
		 */
		rc = deallocate_free_window(win);
		/*
		 * This failure is from the hypervisor.
		 * No way to stop migration for these failures.
		 * So ignore error and continue closing other windows.
		 */
		if (rc && !migrate)
			return rc;

		vcap->nr_close_wins++;

		/*
		 * For migration, do not depend on lpar_creds in case if
		 * mismatch with the hypervisor value (should not happen).
		 * So close all active windows in the list and will be
		 * reopened windows based on the new lpar_creds on the
		 * destination system during resume.
		 */
		if (!migrate && !--excess_creds)
			break;
	}

	return 0;
}

/*
 * Get new VAS capabilities when the core add/removal configuration
 * changes. Reconfig window configurations based on the credits
 * availability from this new capabilities.
 */
int vas_reconfig_capabilties(u8 type, int new_nr_creds)
{
	struct vas_cop_feat_caps *caps;
	int old_nr_creds;
	struct vas_caps *vcaps;
	int rc = 0, nr_active_wins;

	if (type >= VAS_MAX_FEAT_TYPE) {
		pr_err("Invalid credit type %d\n", type);
		return -EINVAL;
	}

	vcaps = &vascaps[type];
	caps = &vcaps->caps;

	mutex_lock(&vas_pseries_mutex);

	old_nr_creds = atomic_read(&caps->nr_total_credits);

	atomic_set(&caps->nr_total_credits, new_nr_creds);
	/*
	 * The total number of available credits may be decreased or
	 * increased with DLPAR operation. Means some windows have to be
	 * closed / reopened. Hold the vas_pseries_mutex so that the
	 * user space can not open new windows.
	 */
	if (old_nr_creds <  new_nr_creds) {
		/*
		 * If the existing target credits is less than the new
		 * target, reopen windows if they are closed due to
		 * the previous DLPAR (core removal).
		 */
		rc = reconfig_open_windows(vcaps, new_nr_creds - old_nr_creds,
					   false);
	} else {
		/*
		 * # active windows is more than new LPAR available
		 * credits. So close the excessive windows.
		 * On pseries, each window will have 1 credit.
		 */
		nr_active_wins = vcaps->nr_open_windows - vcaps->nr_close_wins;
		if (nr_active_wins > new_nr_creds)
			rc = reconfig_close_windows(vcaps,
					nr_active_wins - new_nr_creds,
					false);
	}

	mutex_unlock(&vas_pseries_mutex);
	return rc;
}
/*
 * Total number of default credits available (target_credits)
 * in LPAR depends on number of cores configured. It varies based on
 * whether processors are in shared mode or dedicated mode.
 * Get the notifier when CPU configuration is changed with DLPAR
 * operation so that get the new target_credits (vas default capabilities)
 * and then update the existing windows usage if needed.
 */
static int pseries_vas_notifier(struct notifier_block *nb,
				unsigned long action, void *data)
{
	struct of_reconfig_data *rd = data;
	struct device_node *dn = rd->dn;
	const __be32 *intserv = NULL;
	int new_nr_creds, len, rc = 0;

	if ((action == OF_RECONFIG_ATTACH_NODE) ||
		(action == OF_RECONFIG_DETACH_NODE))
		intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
					  &len);
	/*
	 * Processor config is not changed
	 */
	if (!intserv)
		return NOTIFY_OK;

	rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES,
					vascaps[VAS_GZIP_DEF_FEAT_TYPE].feat,
					(u64)virt_to_phys(&hv_cop_caps));
	if (!rc) {
		new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds);
		rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE,
						new_nr_creds);
	}

	if (rc)
		pr_err("Failed reconfig VAS capabilities with DLPAR\n");

	return rc;
}

static struct notifier_block pseries_vas_nb = {
	.notifier_call = pseries_vas_notifier,
};

/*
 * For LPM, all windows have to be closed on the source partition
 * before migration and reopen them on the destination partition
 * after migration. So closing windows during suspend and
 * reopen them during resume.
 */
int vas_migration_handler(int action)
{
	struct vas_cop_feat_caps *caps;
	int old_nr_creds, new_nr_creds = 0;
	struct vas_caps *vcaps;
	int i, rc = 0;

	/*
	 * NX-GZIP is not enabled. Nothing to do for migration.
	 */
	if (!copypaste_feat)
		return rc;

	mutex_lock(&vas_pseries_mutex);

	if (action == VAS_SUSPEND)
		migration_in_progress = true;
	else
		migration_in_progress = false;

	for (i = 0; i < VAS_MAX_FEAT_TYPE; i++) {
		vcaps = &vascaps[i];
		caps = &vcaps->caps;
		old_nr_creds = atomic_read(&caps->nr_total_credits);

		rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES,
					      vcaps->feat,
					      (u64)virt_to_phys(&hv_cop_caps));
		if (!rc) {
			new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds);
			/*
			 * Should not happen. But incase print messages, close
			 * all windows in the list during suspend and reopen
			 * windows based on new lpar_creds on the destination
			 * system.
			 */
			if (old_nr_creds != new_nr_creds) {
				pr_err("Target credits mismatch with the hypervisor\n");
				pr_err("state(%d): lpar creds: %d HV lpar creds: %d\n",
					action, old_nr_creds, new_nr_creds);
				pr_err("Used creds: %d, Active creds: %d\n",
					atomic_read(&caps->nr_used_credits),
					vcaps->nr_open_windows - vcaps->nr_close_wins);
			}
		} else {
			pr_err("state(%d): Get VAS capabilities failed with %d\n",
				action, rc);
			/*
			 * We can not stop migration with the current lpm
			 * implementation. So continue closing all windows in
			 * the list (during suspend) and return without
			 * opening windows (during resume) if VAS capabilities
			 * HCALL failed.
			 */
			if (action == VAS_RESUME)
				goto out;
		}

		switch (action) {
		case VAS_SUSPEND:
			rc = reconfig_close_windows(vcaps, vcaps->nr_open_windows,
							true);
			break;
		case VAS_RESUME:
			atomic_set(&caps->nr_total_credits, new_nr_creds);
			rc = reconfig_open_windows(vcaps, new_nr_creds, true);
			break;
		default:
			/* should not happen */
			pr_err("Invalid migration action %d\n", action);
			rc = -EINVAL;
			goto out;
		}

		/*
		 * Ignore errors during suspend and return for resume.
		 */
		if (rc && (action == VAS_RESUME))
			goto out;
	}

out:
	mutex_unlock(&vas_pseries_mutex);
	return rc;
}

static int __init pseries_vas_init(void)
{
	struct hv_vas_all_caps *hv_caps;
	int rc = 0;

	/*
	 * Linux supports user space COPY/PASTE only with Radix
	 */
	if (!radix_enabled()) {
		pr_err("API is supported only with radix page tables\n");
		return -ENOTSUPP;
	}

	hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL);
	if (!hv_caps)
		return -ENOMEM;
	/*
	 * Get VAS overall capabilities by passing 0 to feature type.
	 */
	rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, 0,
					  (u64)virt_to_phys(hv_caps));
	if (rc)
		goto out;

	caps_all.descriptor = be64_to_cpu(hv_caps->descriptor);
	caps_all.feat_type = be64_to_cpu(hv_caps->feat_type);

	sysfs_pseries_vas_init(&caps_all);

	/*
	 * QOS capabilities available
	 */
	if (caps_all.feat_type & VAS_GZIP_QOS_FEAT_BIT) {
		rc = get_vas_capabilities(VAS_GZIP_QOS_FEAT,
					  VAS_GZIP_QOS_FEAT_TYPE, &hv_cop_caps);

		if (rc)
			goto out;
	}
	/*
	 * Default capabilities available
	 */
	if (caps_all.feat_type & VAS_GZIP_DEF_FEAT_BIT)
		rc = get_vas_capabilities(VAS_GZIP_DEF_FEAT,
					  VAS_GZIP_DEF_FEAT_TYPE, &hv_cop_caps);

	if (!rc && copypaste_feat) {
		if (firmware_has_feature(FW_FEATURE_LPAR))
			of_reconfig_notifier_register(&pseries_vas_nb);

		pr_info("GZIP feature is available\n");
	} else {
		/*
		 * Should not happen, but only when get default
		 * capabilities HCALL failed. So disable copy paste
		 * feature.
		 */
		copypaste_feat = false;
	}

out:
	kfree(hv_caps);
	return rc;
}
machine_device_initcall(pseries, pseries_vas_init);
