// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/iommu.h>
#include <uapi/linux/idxd.h>
#include <linux/highmem.h>
#include <linux/sched/smt.h>
#include <crypto/internal/acompress.h>

#include "idxd.h"
#include "iaa_crypto.h"
#include "iaa_crypto_stats.h"

#ifdef pr_fmt
#undef pr_fmt
#endif

#define pr_fmt(fmt)			"idxd: " IDXD_SUBDRIVER_NAME ": " fmt

#define IAA_ALG_PRIORITY               300

/* number of iaa instances probed */
static unsigned int nr_iaa;
static unsigned int nr_cpus;
static unsigned int nr_nodes;
static unsigned int nr_cpus_per_node;

/* Number of physical cpus sharing each iaa instance */
static unsigned int cpus_per_iaa;

static struct crypto_comp *deflate_generic_tfm;

/* Per-cpu lookup table for balanced wqs */
static struct wq_table_entry __percpu *wq_table;

static struct idxd_wq *wq_table_next_wq(int cpu)
{
	struct wq_table_entry *entry = per_cpu_ptr(wq_table, cpu);

	if (++entry->cur_wq >= entry->n_wqs)
		entry->cur_wq = 0;

	if (!entry->wqs[entry->cur_wq])
		return NULL;

	pr_debug("%s: returning wq at idx %d (iaa wq %d.%d) from cpu %d\n", __func__,
		 entry->cur_wq, entry->wqs[entry->cur_wq]->idxd->id,
		 entry->wqs[entry->cur_wq]->id, cpu);

	return entry->wqs[entry->cur_wq];
}

static void wq_table_add(int cpu, struct idxd_wq *wq)
{
	struct wq_table_entry *entry = per_cpu_ptr(wq_table, cpu);

	if (WARN_ON(entry->n_wqs == entry->max_wqs))
		return;

	entry->wqs[entry->n_wqs++] = wq;

	pr_debug("%s: added iaa wq %d.%d to idx %d of cpu %d\n", __func__,
		 entry->wqs[entry->n_wqs - 1]->idxd->id,
		 entry->wqs[entry->n_wqs - 1]->id, entry->n_wqs - 1, cpu);
}

static void wq_table_free_entry(int cpu)
{
	struct wq_table_entry *entry = per_cpu_ptr(wq_table, cpu);

	kfree(entry->wqs);
	memset(entry, 0, sizeof(*entry));
}

static void wq_table_clear_entry(int cpu)
{
	struct wq_table_entry *entry = per_cpu_ptr(wq_table, cpu);

	entry->n_wqs = 0;
	entry->cur_wq = 0;
	memset(entry->wqs, 0, entry->max_wqs * sizeof(struct idxd_wq *));
}

LIST_HEAD(iaa_devices);
DEFINE_MUTEX(iaa_devices_lock);

/* If enabled, IAA hw crypto algos are registered, unavailable otherwise */
static bool iaa_crypto_enabled;
static bool iaa_crypto_registered;

/* Verify results of IAA compress or not */
static bool iaa_verify_compress = true;

static ssize_t verify_compress_show(struct device_driver *driver, char *buf)
{
	return sprintf(buf, "%d\n", iaa_verify_compress);
}

static ssize_t verify_compress_store(struct device_driver *driver,
				     const char *buf, size_t count)
{
	int ret = -EBUSY;

	mutex_lock(&iaa_devices_lock);

	if (iaa_crypto_enabled)
		goto out;

	ret = kstrtobool(buf, &iaa_verify_compress);
	if (ret)
		goto out;

	ret = count;
out:
	mutex_unlock(&iaa_devices_lock);

	return ret;
}
static DRIVER_ATTR_RW(verify_compress);

/*
 * The iaa crypto driver supports three 'sync' methods determining how
 * compressions and decompressions are performed:
 *
 * - sync:      the compression or decompression completes before
 *              returning.  This is the mode used by the async crypto
 *              interface when the sync mode is set to 'sync' and by
 *              the sync crypto interface regardless of setting.
 *
 * - async:     the compression or decompression is submitted and returns
 *              immediately.  Completion interrupts are not used so
 *              the caller is responsible for polling the descriptor
 *              for completion.  This mode is applicable to only the
 *              async crypto interface and is ignored for anything
 *              else.
 *
 * - async_irq: the compression or decompression is submitted and
 *              returns immediately.  Completion interrupts are
 *              enabled so the caller can wait for the completion and
 *              yield to other threads.  When the compression or
 *              decompression completes, the completion is signaled
 *              and the caller awakened.  This mode is applicable to
 *              only the async crypto interface and is ignored for
 *              anything else.
 *
 * These modes can be set using the iaa_crypto sync_mode driver
 * attribute.
 */

/* Use async mode */
static bool async_mode;
/* Use interrupts */
static bool use_irq;

/**
 * set_iaa_sync_mode - Set IAA sync mode
 * @name: The name of the sync mode
 *
 * Make the IAA sync mode named @name the current sync mode used by
 * compression/decompression.
 */

static int set_iaa_sync_mode(const char *name)
{
	int ret = 0;

	if (sysfs_streq(name, "sync")) {
		async_mode = false;
		use_irq = false;
	} else if (sysfs_streq(name, "async")) {
		async_mode = true;
		use_irq = false;
	} else if (sysfs_streq(name, "async_irq")) {
		async_mode = true;
		use_irq = true;
	} else {
		ret = -EINVAL;
	}

	return ret;
}

static ssize_t sync_mode_show(struct device_driver *driver, char *buf)
{
	int ret = 0;

	if (!async_mode && !use_irq)
		ret = sprintf(buf, "%s\n", "sync");
	else if (async_mode && !use_irq)
		ret = sprintf(buf, "%s\n", "async");
	else if (async_mode && use_irq)
		ret = sprintf(buf, "%s\n", "async_irq");

	return ret;
}

static ssize_t sync_mode_store(struct device_driver *driver,
			       const char *buf, size_t count)
{
	int ret = -EBUSY;

	mutex_lock(&iaa_devices_lock);

	if (iaa_crypto_enabled)
		goto out;

	ret = set_iaa_sync_mode(buf);
	if (ret == 0)
		ret = count;
out:
	mutex_unlock(&iaa_devices_lock);

	return ret;
}
static DRIVER_ATTR_RW(sync_mode);

static struct iaa_compression_mode *iaa_compression_modes[IAA_COMP_MODES_MAX];

static int find_empty_iaa_compression_mode(void)
{
	int i = -EINVAL;

	for (i = 0; i < IAA_COMP_MODES_MAX; i++) {
		if (iaa_compression_modes[i])
			continue;
		break;
	}

	return i;
}

static struct iaa_compression_mode *find_iaa_compression_mode(const char *name, int *idx)
{
	struct iaa_compression_mode *mode;
	int i;

	for (i = 0; i < IAA_COMP_MODES_MAX; i++) {
		mode = iaa_compression_modes[i];
		if (!mode)
			continue;

		if (!strcmp(mode->name, name)) {
			*idx = i;
			return iaa_compression_modes[i];
		}
	}

	return NULL;
}

static void free_iaa_compression_mode(struct iaa_compression_mode *mode)
{
	kfree(mode->name);
	kfree(mode->ll_table);
	kfree(mode->d_table);

	kfree(mode);
}

/*
 * IAA Compression modes are defined by an ll_table and a d_table.
 * These tables are typically generated and captured using statistics
 * collected from running actual compress/decompress workloads.
 *
 * A module or other kernel code can add and remove compression modes
 * with a given name using the exported @add_iaa_compression_mode()
 * and @remove_iaa_compression_mode functions.
 *
 * When a new compression mode is added, the tables are saved in a
 * global compression mode list.  When IAA devices are added, a
 * per-IAA device dma mapping is created for each IAA device, for each
 * compression mode.  These are the tables used to do the actual
 * compression/deccompression and are unmapped if/when the devices are
 * removed.  Currently, compression modes must be added before any
 * device is added, and removed after all devices have been removed.
 */

/**
 * remove_iaa_compression_mode - Remove an IAA compression mode
 * @name: The name the compression mode will be known as
 *
 * Remove the IAA compression mode named @name.
 */
void remove_iaa_compression_mode(const char *name)
{
	struct iaa_compression_mode *mode;
	int idx;

	mutex_lock(&iaa_devices_lock);

	if (!list_empty(&iaa_devices))
		goto out;

	mode = find_iaa_compression_mode(name, &idx);
	if (mode) {
		free_iaa_compression_mode(mode);
		iaa_compression_modes[idx] = NULL;
	}
out:
	mutex_unlock(&iaa_devices_lock);
}
EXPORT_SYMBOL_GPL(remove_iaa_compression_mode);

/**
 * add_iaa_compression_mode - Add an IAA compression mode
 * @name: The name the compression mode will be known as
 * @ll_table: The ll table
 * @ll_table_size: The ll table size in bytes
 * @d_table: The d table
 * @d_table_size: The d table size in bytes
 * @init: Optional callback function to init the compression mode data
 * @free: Optional callback function to free the compression mode data
 *
 * Add a new IAA compression mode named @name.
 *
 * Returns 0 if successful, errcode otherwise.
 */
int add_iaa_compression_mode(const char *name,
			     const u32 *ll_table,
			     int ll_table_size,
			     const u32 *d_table,
			     int d_table_size,
			     iaa_dev_comp_init_fn_t init,
			     iaa_dev_comp_free_fn_t free)
{
	struct iaa_compression_mode *mode;
	int idx, ret = -ENOMEM;

	mutex_lock(&iaa_devices_lock);

	if (!list_empty(&iaa_devices)) {
		ret = -EBUSY;
		goto out;
	}

	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
	if (!mode)
		goto out;

	mode->name = kstrdup(name, GFP_KERNEL);
	if (!mode->name)
		goto free;

	if (ll_table) {
		mode->ll_table = kzalloc(ll_table_size, GFP_KERNEL);
		if (!mode->ll_table)
			goto free;
		memcpy(mode->ll_table, ll_table, ll_table_size);
		mode->ll_table_size = ll_table_size;
	}

	if (d_table) {
		mode->d_table = kzalloc(d_table_size, GFP_KERNEL);
		if (!mode->d_table)
			goto free;
		memcpy(mode->d_table, d_table, d_table_size);
		mode->d_table_size = d_table_size;
	}

	mode->init = init;
	mode->free = free;

	idx = find_empty_iaa_compression_mode();
	if (idx < 0)
		goto free;

	pr_debug("IAA compression mode %s added at idx %d\n",
		 mode->name, idx);

	iaa_compression_modes[idx] = mode;

	ret = 0;
out:
	mutex_unlock(&iaa_devices_lock);

	return ret;
free:
	free_iaa_compression_mode(mode);
	goto out;
}
EXPORT_SYMBOL_GPL(add_iaa_compression_mode);

static struct iaa_device_compression_mode *
get_iaa_device_compression_mode(struct iaa_device *iaa_device, int idx)
{
	return iaa_device->compression_modes[idx];
}

static void free_device_compression_mode(struct iaa_device *iaa_device,
					 struct iaa_device_compression_mode *device_mode)
{
	size_t size = sizeof(struct aecs_comp_table_record) + IAA_AECS_ALIGN;
	struct device *dev = &iaa_device->idxd->pdev->dev;

	kfree(device_mode->name);

	if (device_mode->aecs_comp_table)
		dma_free_coherent(dev, size, device_mode->aecs_comp_table,
				  device_mode->aecs_comp_table_dma_addr);
	kfree(device_mode);
}

#define IDXD_OP_FLAG_AECS_RW_TGLS       0x400000
#define IAX_AECS_DEFAULT_FLAG (IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR | IDXD_OP_FLAG_CC)
#define IAX_AECS_COMPRESS_FLAG	(IAX_AECS_DEFAULT_FLAG | IDXD_OP_FLAG_RD_SRC2_AECS)
#define IAX_AECS_DECOMPRESS_FLAG (IAX_AECS_DEFAULT_FLAG | IDXD_OP_FLAG_RD_SRC2_AECS)
#define IAX_AECS_GEN_FLAG (IAX_AECS_DEFAULT_FLAG | \
						IDXD_OP_FLAG_WR_SRC2_AECS_COMP | \
						IDXD_OP_FLAG_AECS_RW_TGLS)

static int check_completion(struct device *dev,
			    struct iax_completion_record *comp,
			    bool compress,
			    bool only_once);

static int init_device_compression_mode(struct iaa_device *iaa_device,
					struct iaa_compression_mode *mode,
					int idx, struct idxd_wq *wq)
{
	size_t size = sizeof(struct aecs_comp_table_record) + IAA_AECS_ALIGN;
	struct device *dev = &iaa_device->idxd->pdev->dev;
	struct iaa_device_compression_mode *device_mode;
	int ret = -ENOMEM;

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

	device_mode->name = kstrdup(mode->name, GFP_KERNEL);
	if (!device_mode->name)
		goto free;

	device_mode->aecs_comp_table = dma_alloc_coherent(dev, size,
							  &device_mode->aecs_comp_table_dma_addr, GFP_KERNEL);
	if (!device_mode->aecs_comp_table)
		goto free;

	/* Add Huffman table to aecs */
	memset(device_mode->aecs_comp_table, 0, sizeof(*device_mode->aecs_comp_table));
	memcpy(device_mode->aecs_comp_table->ll_sym, mode->ll_table, mode->ll_table_size);
	memcpy(device_mode->aecs_comp_table->d_sym, mode->d_table, mode->d_table_size);

	if (mode->init) {
		ret = mode->init(device_mode);
		if (ret)
			goto free;
	}

	/* mode index should match iaa_compression_modes idx */
	iaa_device->compression_modes[idx] = device_mode;

	pr_debug("IAA %s compression mode initialized for iaa device %d\n",
		 mode->name, iaa_device->idxd->id);

	ret = 0;
out:
	return ret;
free:
	pr_debug("IAA %s compression mode initialization failed for iaa device %d\n",
		 mode->name, iaa_device->idxd->id);

	free_device_compression_mode(iaa_device, device_mode);
	goto out;
}

static int init_device_compression_modes(struct iaa_device *iaa_device,
					 struct idxd_wq *wq)
{
	struct iaa_compression_mode *mode;
	int i, ret = 0;

	for (i = 0; i < IAA_COMP_MODES_MAX; i++) {
		mode = iaa_compression_modes[i];
		if (!mode)
			continue;

		ret = init_device_compression_mode(iaa_device, mode, i, wq);
		if (ret)
			break;
	}

	return ret;
}

static void remove_device_compression_modes(struct iaa_device *iaa_device)
{
	struct iaa_device_compression_mode *device_mode;
	int i;

	for (i = 0; i < IAA_COMP_MODES_MAX; i++) {
		device_mode = iaa_device->compression_modes[i];
		if (!device_mode)
			continue;

		free_device_compression_mode(iaa_device, device_mode);
		iaa_device->compression_modes[i] = NULL;
		if (iaa_compression_modes[i]->free)
			iaa_compression_modes[i]->free(device_mode);
	}
}

static struct iaa_device *iaa_device_alloc(void)
{
	struct iaa_device *iaa_device;

	iaa_device = kzalloc(sizeof(*iaa_device), GFP_KERNEL);
	if (!iaa_device)
		return NULL;

	INIT_LIST_HEAD(&iaa_device->wqs);

	return iaa_device;
}

static bool iaa_has_wq(struct iaa_device *iaa_device, struct idxd_wq *wq)
{
	struct iaa_wq *iaa_wq;

	list_for_each_entry(iaa_wq, &iaa_device->wqs, list) {
		if (iaa_wq->wq == wq)
			return true;
	}

	return false;
}

static struct iaa_device *add_iaa_device(struct idxd_device *idxd)
{
	struct iaa_device *iaa_device;

	iaa_device = iaa_device_alloc();
	if (!iaa_device)
		return NULL;

	iaa_device->idxd = idxd;

	list_add_tail(&iaa_device->list, &iaa_devices);

	nr_iaa++;

	return iaa_device;
}

static int init_iaa_device(struct iaa_device *iaa_device, struct iaa_wq *iaa_wq)
{
	int ret = 0;

	ret = init_device_compression_modes(iaa_device, iaa_wq->wq);
	if (ret)
		return ret;

	return ret;
}

static void del_iaa_device(struct iaa_device *iaa_device)
{
	list_del(&iaa_device->list);

	nr_iaa--;
}

static int add_iaa_wq(struct iaa_device *iaa_device, struct idxd_wq *wq,
		      struct iaa_wq **new_wq)
{
	struct idxd_device *idxd = iaa_device->idxd;
	struct pci_dev *pdev = idxd->pdev;
	struct device *dev = &pdev->dev;
	struct iaa_wq *iaa_wq;

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

	iaa_wq->wq = wq;
	iaa_wq->iaa_device = iaa_device;
	idxd_wq_set_private(wq, iaa_wq);

	list_add_tail(&iaa_wq->list, &iaa_device->wqs);

	iaa_device->n_wq++;

	if (new_wq)
		*new_wq = iaa_wq;

	dev_dbg(dev, "added wq %d to iaa device %d, n_wq %d\n",
		wq->id, iaa_device->idxd->id, iaa_device->n_wq);

	return 0;
}

static void del_iaa_wq(struct iaa_device *iaa_device, struct idxd_wq *wq)
{
	struct idxd_device *idxd = iaa_device->idxd;
	struct pci_dev *pdev = idxd->pdev;
	struct device *dev = &pdev->dev;
	struct iaa_wq *iaa_wq;

	list_for_each_entry(iaa_wq, &iaa_device->wqs, list) {
		if (iaa_wq->wq == wq) {
			list_del(&iaa_wq->list);
			iaa_device->n_wq--;

			dev_dbg(dev, "removed wq %d from iaa_device %d, n_wq %d, nr_iaa %d\n",
				wq->id, iaa_device->idxd->id,
				iaa_device->n_wq, nr_iaa);

			if (iaa_device->n_wq == 0)
				del_iaa_device(iaa_device);
			break;
		}
	}
}

static void clear_wq_table(void)
{
	int cpu;

	for (cpu = 0; cpu < nr_cpus; cpu++)
		wq_table_clear_entry(cpu);

	pr_debug("cleared wq table\n");
}

static void free_iaa_device(struct iaa_device *iaa_device)
{
	if (!iaa_device)
		return;

	remove_device_compression_modes(iaa_device);
	kfree(iaa_device);
}

static void __free_iaa_wq(struct iaa_wq *iaa_wq)
{
	struct iaa_device *iaa_device;

	if (!iaa_wq)
		return;

	iaa_device = iaa_wq->iaa_device;
	if (iaa_device->n_wq == 0)
		free_iaa_device(iaa_wq->iaa_device);
}

static void free_iaa_wq(struct iaa_wq *iaa_wq)
{
	struct idxd_wq *wq;

	__free_iaa_wq(iaa_wq);

	wq = iaa_wq->wq;

	kfree(iaa_wq);
	idxd_wq_set_private(wq, NULL);
}

static int iaa_wq_get(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct iaa_wq *iaa_wq;
	int ret = 0;

	spin_lock(&idxd->dev_lock);
	iaa_wq = idxd_wq_get_private(wq);
	if (iaa_wq && !iaa_wq->remove) {
		iaa_wq->ref++;
		idxd_wq_get(wq);
	} else {
		ret = -ENODEV;
	}
	spin_unlock(&idxd->dev_lock);

	return ret;
}

static int iaa_wq_put(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct iaa_wq *iaa_wq;
	bool free = false;
	int ret = 0;

	spin_lock(&idxd->dev_lock);
	iaa_wq = idxd_wq_get_private(wq);
	if (iaa_wq) {
		iaa_wq->ref--;
		if (iaa_wq->ref == 0 && iaa_wq->remove) {
			idxd_wq_set_private(wq, NULL);
			free = true;
		}
		idxd_wq_put(wq);
	} else {
		ret = -ENODEV;
	}
	spin_unlock(&idxd->dev_lock);
	if (free) {
		__free_iaa_wq(iaa_wq);
		kfree(iaa_wq);
	}

	return ret;
}

static void free_wq_table(void)
{
	int cpu;

	for (cpu = 0; cpu < nr_cpus; cpu++)
		wq_table_free_entry(cpu);

	free_percpu(wq_table);

	pr_debug("freed wq table\n");
}

static int alloc_wq_table(int max_wqs)
{
	struct wq_table_entry *entry;
	int cpu;

	wq_table = alloc_percpu(struct wq_table_entry);
	if (!wq_table)
		return -ENOMEM;

	for (cpu = 0; cpu < nr_cpus; cpu++) {
		entry = per_cpu_ptr(wq_table, cpu);
		entry->wqs = kcalloc(max_wqs, sizeof(struct wq *), GFP_KERNEL);
		if (!entry->wqs) {
			free_wq_table();
			return -ENOMEM;
		}

		entry->max_wqs = max_wqs;
	}

	pr_debug("initialized wq table\n");

	return 0;
}

static int save_iaa_wq(struct idxd_wq *wq)
{
	struct iaa_device *iaa_device, *found = NULL;
	struct idxd_device *idxd;
	struct pci_dev *pdev;
	struct device *dev;
	int ret = 0;

	list_for_each_entry(iaa_device, &iaa_devices, list) {
		if (iaa_device->idxd == wq->idxd) {
			idxd = iaa_device->idxd;
			pdev = idxd->pdev;
			dev = &pdev->dev;
			/*
			 * Check to see that we don't already have this wq.
			 * Shouldn't happen but we don't control probing.
			 */
			if (iaa_has_wq(iaa_device, wq)) {
				dev_dbg(dev, "same wq probed multiple times for iaa_device %p\n",
					iaa_device);
				goto out;
			}

			found = iaa_device;

			ret = add_iaa_wq(iaa_device, wq, NULL);
			if (ret)
				goto out;

			break;
		}
	}

	if (!found) {
		struct iaa_device *new_device;
		struct iaa_wq *new_wq;

		new_device = add_iaa_device(wq->idxd);
		if (!new_device) {
			ret = -ENOMEM;
			goto out;
		}

		ret = add_iaa_wq(new_device, wq, &new_wq);
		if (ret) {
			del_iaa_device(new_device);
			free_iaa_device(new_device);
			goto out;
		}

		ret = init_iaa_device(new_device, new_wq);
		if (ret) {
			del_iaa_wq(new_device, new_wq->wq);
			del_iaa_device(new_device);
			free_iaa_wq(new_wq);
			goto out;
		}
	}

	if (WARN_ON(nr_iaa == 0))
		return -EINVAL;

	cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
out:
	return 0;
}

static void remove_iaa_wq(struct idxd_wq *wq)
{
	struct iaa_device *iaa_device;

	list_for_each_entry(iaa_device, &iaa_devices, list) {
		if (iaa_has_wq(iaa_device, wq)) {
			del_iaa_wq(iaa_device, wq);
			break;
		}
	}

	if (nr_iaa)
		cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
	else
		cpus_per_iaa = 0;
}

static int wq_table_add_wqs(int iaa, int cpu)
{
	struct iaa_device *iaa_device, *found_device = NULL;
	int ret = 0, cur_iaa = 0, n_wqs_added = 0;
	struct idxd_device *idxd;
	struct iaa_wq *iaa_wq;
	struct pci_dev *pdev;
	struct device *dev;

	list_for_each_entry(iaa_device, &iaa_devices, list) {
		idxd = iaa_device->idxd;
		pdev = idxd->pdev;
		dev = &pdev->dev;

		if (cur_iaa != iaa) {
			cur_iaa++;
			continue;
		}

		found_device = iaa_device;
		dev_dbg(dev, "getting wq from iaa_device %d, cur_iaa %d\n",
			found_device->idxd->id, cur_iaa);
		break;
	}

	if (!found_device) {
		found_device = list_first_entry_or_null(&iaa_devices,
							struct iaa_device, list);
		if (!found_device) {
			pr_debug("couldn't find any iaa devices with wqs!\n");
			ret = -EINVAL;
			goto out;
		}
		cur_iaa = 0;

		idxd = found_device->idxd;
		pdev = idxd->pdev;
		dev = &pdev->dev;
		dev_dbg(dev, "getting wq from only iaa_device %d, cur_iaa %d\n",
			found_device->idxd->id, cur_iaa);
	}

	list_for_each_entry(iaa_wq, &found_device->wqs, list) {
		wq_table_add(cpu, iaa_wq->wq);
		pr_debug("rebalance: added wq for cpu=%d: iaa wq %d.%d\n",
			 cpu, iaa_wq->wq->idxd->id, iaa_wq->wq->id);
		n_wqs_added++;
	}

	if (!n_wqs_added) {
		pr_debug("couldn't find any iaa wqs!\n");
		ret = -EINVAL;
		goto out;
	}
out:
	return ret;
}

/*
 * Rebalance the wq table so that given a cpu, it's easy to find the
 * closest IAA instance.  The idea is to try to choose the most
 * appropriate IAA instance for a caller and spread available
 * workqueues around to clients.
 */
static void rebalance_wq_table(void)
{
	const struct cpumask *node_cpus;
	int node, cpu, iaa = -1;

	if (nr_iaa == 0)
		return;

	pr_debug("rebalance: nr_nodes=%d, nr_cpus %d, nr_iaa %d, cpus_per_iaa %d\n",
		 nr_nodes, nr_cpus, nr_iaa, cpus_per_iaa);

	clear_wq_table();

	if (nr_iaa == 1) {
		for (cpu = 0; cpu < nr_cpus; cpu++) {
			if (WARN_ON(wq_table_add_wqs(0, cpu))) {
				pr_debug("could not add any wqs for iaa 0 to cpu %d!\n", cpu);
				return;
			}
		}

		return;
	}

	for_each_node_with_cpus(node) {
		node_cpus = cpumask_of_node(node);

		for (cpu = 0; cpu < nr_cpus_per_node; cpu++) {
			int node_cpu = cpumask_nth(cpu, node_cpus);

			if (WARN_ON(node_cpu >= nr_cpu_ids)) {
				pr_debug("node_cpu %d doesn't exist!\n", node_cpu);
				return;
			}

			if ((cpu % cpus_per_iaa) == 0)
				iaa++;

			if (WARN_ON(wq_table_add_wqs(iaa, node_cpu))) {
				pr_debug("could not add any wqs for iaa %d to cpu %d!\n", iaa, cpu);
				return;
			}
		}
	}
}

static inline int check_completion(struct device *dev,
				   struct iax_completion_record *comp,
				   bool compress,
				   bool only_once)
{
	char *op_str = compress ? "compress" : "decompress";
	int ret = 0;

	while (!comp->status) {
		if (only_once)
			return -EAGAIN;
		cpu_relax();
	}

	if (comp->status != IAX_COMP_SUCCESS) {
		if (comp->status == IAA_ERROR_WATCHDOG_EXPIRED) {
			ret = -ETIMEDOUT;
			dev_dbg(dev, "%s timed out, size=0x%x\n",
				op_str, comp->output_size);
			update_completion_timeout_errs();
			goto out;
		}

		if (comp->status == IAA_ANALYTICS_ERROR &&
		    comp->error_code == IAA_ERROR_COMP_BUF_OVERFLOW && compress) {
			ret = -E2BIG;
			dev_dbg(dev, "compressed > uncompressed size,"
				" not compressing, size=0x%x\n",
				comp->output_size);
			update_completion_comp_buf_overflow_errs();
			goto out;
		}

		if (comp->status == IAA_ERROR_DECOMP_BUF_OVERFLOW) {
			ret = -EOVERFLOW;
			goto out;
		}

		ret = -EINVAL;
		dev_dbg(dev, "iaa %s status=0x%x, error=0x%x, size=0x%x\n",
			op_str, comp->status, comp->error_code, comp->output_size);
		print_hex_dump(KERN_INFO, "cmp-rec: ", DUMP_PREFIX_OFFSET, 8, 1, comp, 64, 0);
		update_completion_einval_errs();

		goto out;
	}
out:
	return ret;
}

static int deflate_generic_decompress(struct acomp_req *req)
{
	void *src, *dst;
	int ret;

	src = kmap_local_page(sg_page(req->src)) + req->src->offset;
	dst = kmap_local_page(sg_page(req->dst)) + req->dst->offset;

	ret = crypto_comp_decompress(deflate_generic_tfm,
				     src, req->slen, dst, &req->dlen);

	kunmap_local(src);
	kunmap_local(dst);

	update_total_sw_decomp_calls();

	return ret;
}

static int iaa_remap_for_verify(struct device *dev, struct iaa_wq *iaa_wq,
				struct acomp_req *req,
				dma_addr_t *src_addr, dma_addr_t *dst_addr);

static int iaa_compress_verify(struct crypto_tfm *tfm, struct acomp_req *req,
			       struct idxd_wq *wq,
			       dma_addr_t src_addr, unsigned int slen,
			       dma_addr_t dst_addr, unsigned int *dlen,
			       u32 compression_crc);

static void iaa_desc_complete(struct idxd_desc *idxd_desc,
			      enum idxd_complete_type comp_type,
			      bool free_desc, void *__ctx,
			      u32 *status)
{
	struct iaa_device_compression_mode *active_compression_mode;
	struct iaa_compression_ctx *compression_ctx;
	struct crypto_ctx *ctx = __ctx;
	struct iaa_device *iaa_device;
	struct idxd_device *idxd;
	struct iaa_wq *iaa_wq;
	struct pci_dev *pdev;
	struct device *dev;
	int ret, err = 0;

	compression_ctx = crypto_tfm_ctx(ctx->tfm);

	iaa_wq = idxd_wq_get_private(idxd_desc->wq);
	iaa_device = iaa_wq->iaa_device;
	idxd = iaa_device->idxd;
	pdev = idxd->pdev;
	dev = &pdev->dev;

	active_compression_mode = get_iaa_device_compression_mode(iaa_device,
								  compression_ctx->mode);
	dev_dbg(dev, "%s: compression mode %s,"
		" ctx->src_addr %llx, ctx->dst_addr %llx\n", __func__,
		active_compression_mode->name,
		ctx->src_addr, ctx->dst_addr);

	ret = check_completion(dev, idxd_desc->iax_completion,
			       ctx->compress, false);
	if (ret) {
		dev_dbg(dev, "%s: check_completion failed ret=%d\n", __func__, ret);
		if (!ctx->compress &&
		    idxd_desc->iax_completion->status == IAA_ANALYTICS_ERROR) {
			pr_warn("%s: falling back to deflate-generic decompress, "
				"analytics error code %x\n", __func__,
				idxd_desc->iax_completion->error_code);
			ret = deflate_generic_decompress(ctx->req);
			if (ret) {
				dev_dbg(dev, "%s: deflate-generic failed ret=%d\n",
					__func__, ret);
				err = -EIO;
				goto err;
			}
		} else {
			err = -EIO;
			goto err;
		}
	} else {
		ctx->req->dlen = idxd_desc->iax_completion->output_size;
	}

	/* Update stats */
	if (ctx->compress) {
		update_total_comp_bytes_out(ctx->req->dlen);
		update_wq_comp_bytes(iaa_wq->wq, ctx->req->dlen);
	} else {
		update_total_decomp_bytes_in(ctx->req->dlen);
		update_wq_decomp_bytes(iaa_wq->wq, ctx->req->dlen);
	}

	if (ctx->compress && compression_ctx->verify_compress) {
		dma_addr_t src_addr, dst_addr;
		u32 compression_crc;

		compression_crc = idxd_desc->iax_completion->crc;

		ret = iaa_remap_for_verify(dev, iaa_wq, ctx->req, &src_addr, &dst_addr);
		if (ret) {
			dev_dbg(dev, "%s: compress verify remap failed ret=%d\n", __func__, ret);
			err = -EIO;
			goto out;
		}

		ret = iaa_compress_verify(ctx->tfm, ctx->req, iaa_wq->wq, src_addr,
					  ctx->req->slen, dst_addr, &ctx->req->dlen,
					  compression_crc);
		if (ret) {
			dev_dbg(dev, "%s: compress verify failed ret=%d\n", __func__, ret);
			err = -EIO;
		}

		dma_unmap_sg(dev, ctx->req->dst, sg_nents(ctx->req->dst), DMA_TO_DEVICE);
		dma_unmap_sg(dev, ctx->req->src, sg_nents(ctx->req->src), DMA_FROM_DEVICE);

		goto out;
	}
err:
	dma_unmap_sg(dev, ctx->req->dst, sg_nents(ctx->req->dst), DMA_FROM_DEVICE);
	dma_unmap_sg(dev, ctx->req->src, sg_nents(ctx->req->src), DMA_TO_DEVICE);
out:
	if (ret != 0)
		dev_dbg(dev, "asynchronous compress failed ret=%d\n", ret);

	if (ctx->req->base.complete)
		acomp_request_complete(ctx->req, err);

	if (free_desc)
		idxd_free_desc(idxd_desc->wq, idxd_desc);
	iaa_wq_put(idxd_desc->wq);
}

static int iaa_compress(struct crypto_tfm *tfm,	struct acomp_req *req,
			struct idxd_wq *wq,
			dma_addr_t src_addr, unsigned int slen,
			dma_addr_t dst_addr, unsigned int *dlen,
			u32 *compression_crc,
			bool disable_async)
{
	struct iaa_device_compression_mode *active_compression_mode;
	struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);
	struct iaa_device *iaa_device;
	struct idxd_desc *idxd_desc;
	struct iax_hw_desc *desc;
	struct idxd_device *idxd;
	struct iaa_wq *iaa_wq;
	struct pci_dev *pdev;
	struct device *dev;
	int ret = 0;

	iaa_wq = idxd_wq_get_private(wq);
	iaa_device = iaa_wq->iaa_device;
	idxd = iaa_device->idxd;
	pdev = idxd->pdev;
	dev = &pdev->dev;

	active_compression_mode = get_iaa_device_compression_mode(iaa_device, ctx->mode);

	idxd_desc = idxd_alloc_desc(wq, IDXD_OP_BLOCK);
	if (IS_ERR(idxd_desc)) {
		dev_dbg(dev, "idxd descriptor allocation failed\n");
		dev_dbg(dev, "iaa compress failed: ret=%ld\n", PTR_ERR(idxd_desc));
		return PTR_ERR(idxd_desc);
	}
	desc = idxd_desc->iax_hw;

	desc->flags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR |
		IDXD_OP_FLAG_RD_SRC2_AECS | IDXD_OP_FLAG_CC;
	desc->opcode = IAX_OPCODE_COMPRESS;
	desc->compr_flags = IAA_COMP_FLAGS;
	desc->priv = 0;

	desc->src1_addr = (u64)src_addr;
	desc->src1_size = slen;
	desc->dst_addr = (u64)dst_addr;
	desc->max_dst_size = *dlen;
	desc->src2_addr = active_compression_mode->aecs_comp_table_dma_addr;
	desc->src2_size = sizeof(struct aecs_comp_table_record);
	desc->completion_addr = idxd_desc->compl_dma;

	if (ctx->use_irq && !disable_async) {
		desc->flags |= IDXD_OP_FLAG_RCI;

		idxd_desc->crypto.req = req;
		idxd_desc->crypto.tfm = tfm;
		idxd_desc->crypto.src_addr = src_addr;
		idxd_desc->crypto.dst_addr = dst_addr;
		idxd_desc->crypto.compress = true;

		dev_dbg(dev, "%s use_async_irq: compression mode %s,"
			" src_addr %llx, dst_addr %llx\n", __func__,
			active_compression_mode->name,
			src_addr, dst_addr);
	} else if (ctx->async_mode && !disable_async)
		req->base.data = idxd_desc;

	dev_dbg(dev, "%s: compression mode %s,"
		" desc->src1_addr %llx, desc->src1_size %d,"
		" desc->dst_addr %llx, desc->max_dst_size %d,"
		" desc->src2_addr %llx, desc->src2_size %d\n", __func__,
		active_compression_mode->name,
		desc->src1_addr, desc->src1_size, desc->dst_addr,
		desc->max_dst_size, desc->src2_addr, desc->src2_size);

	ret = idxd_submit_desc(wq, idxd_desc);
	if (ret) {
		dev_dbg(dev, "submit_desc failed ret=%d\n", ret);
		goto err;
	}

	/* Update stats */
	update_total_comp_calls();
	update_wq_comp_calls(wq);

	if (ctx->async_mode && !disable_async) {
		ret = -EINPROGRESS;
		dev_dbg(dev, "%s: returning -EINPROGRESS\n", __func__);
		goto out;
	}

	ret = check_completion(dev, idxd_desc->iax_completion, true, false);
	if (ret) {
		dev_dbg(dev, "check_completion failed ret=%d\n", ret);
		goto err;
	}

	*dlen = idxd_desc->iax_completion->output_size;

	/* Update stats */
	update_total_comp_bytes_out(*dlen);
	update_wq_comp_bytes(wq, *dlen);

	*compression_crc = idxd_desc->iax_completion->crc;

	if (!ctx->async_mode || disable_async)
		idxd_free_desc(wq, idxd_desc);
out:
	return ret;
err:
	idxd_free_desc(wq, idxd_desc);
	dev_dbg(dev, "iaa compress failed: ret=%d\n", ret);

	goto out;
}

static int iaa_remap_for_verify(struct device *dev, struct iaa_wq *iaa_wq,
				struct acomp_req *req,
				dma_addr_t *src_addr, dma_addr_t *dst_addr)
{
	int ret = 0;
	int nr_sgs;

	dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
	dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);

	nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_FROM_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "verify: couldn't map src sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto out;
	}
	*src_addr = sg_dma_address(req->src);
	dev_dbg(dev, "verify: dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
		" req->slen %d, sg_dma_len(sg) %d\n", *src_addr, nr_sgs,
		req->src, req->slen, sg_dma_len(req->src));

	nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_TO_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "verify: couldn't map dst sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_FROM_DEVICE);
		goto out;
	}
	*dst_addr = sg_dma_address(req->dst);
	dev_dbg(dev, "verify: dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
		" req->dlen %d, sg_dma_len(sg) %d\n", *dst_addr, nr_sgs,
		req->dst, req->dlen, sg_dma_len(req->dst));
out:
	return ret;
}

static int iaa_compress_verify(struct crypto_tfm *tfm, struct acomp_req *req,
			       struct idxd_wq *wq,
			       dma_addr_t src_addr, unsigned int slen,
			       dma_addr_t dst_addr, unsigned int *dlen,
			       u32 compression_crc)
{
	struct iaa_device_compression_mode *active_compression_mode;
	struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);
	struct iaa_device *iaa_device;
	struct idxd_desc *idxd_desc;
	struct iax_hw_desc *desc;
	struct idxd_device *idxd;
	struct iaa_wq *iaa_wq;
	struct pci_dev *pdev;
	struct device *dev;
	int ret = 0;

	iaa_wq = idxd_wq_get_private(wq);
	iaa_device = iaa_wq->iaa_device;
	idxd = iaa_device->idxd;
	pdev = idxd->pdev;
	dev = &pdev->dev;

	active_compression_mode = get_iaa_device_compression_mode(iaa_device, ctx->mode);

	idxd_desc = idxd_alloc_desc(wq, IDXD_OP_BLOCK);
	if (IS_ERR(idxd_desc)) {
		dev_dbg(dev, "idxd descriptor allocation failed\n");
		dev_dbg(dev, "iaa compress failed: ret=%ld\n",
			PTR_ERR(idxd_desc));
		return PTR_ERR(idxd_desc);
	}
	desc = idxd_desc->iax_hw;

	/* Verify (optional) - decompress and check crc, suppress dest write */

	desc->flags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR | IDXD_OP_FLAG_CC;
	desc->opcode = IAX_OPCODE_DECOMPRESS;
	desc->decompr_flags = IAA_DECOMP_FLAGS | IAA_DECOMP_SUPPRESS_OUTPUT;
	desc->priv = 0;

	desc->src1_addr = (u64)dst_addr;
	desc->src1_size = *dlen;
	desc->dst_addr = (u64)src_addr;
	desc->max_dst_size = slen;
	desc->completion_addr = idxd_desc->compl_dma;

	dev_dbg(dev, "(verify) compression mode %s,"
		" desc->src1_addr %llx, desc->src1_size %d,"
		" desc->dst_addr %llx, desc->max_dst_size %d,"
		" desc->src2_addr %llx, desc->src2_size %d\n",
		active_compression_mode->name,
		desc->src1_addr, desc->src1_size, desc->dst_addr,
		desc->max_dst_size, desc->src2_addr, desc->src2_size);

	ret = idxd_submit_desc(wq, idxd_desc);
	if (ret) {
		dev_dbg(dev, "submit_desc (verify) failed ret=%d\n", ret);
		goto err;
	}

	ret = check_completion(dev, idxd_desc->iax_completion, false, false);
	if (ret) {
		dev_dbg(dev, "(verify) check_completion failed ret=%d\n", ret);
		goto err;
	}

	if (compression_crc != idxd_desc->iax_completion->crc) {
		ret = -EINVAL;
		dev_dbg(dev, "(verify) iaa comp/decomp crc mismatch:"
			" comp=0x%x, decomp=0x%x\n", compression_crc,
			idxd_desc->iax_completion->crc);
		print_hex_dump(KERN_INFO, "cmp-rec: ", DUMP_PREFIX_OFFSET,
			       8, 1, idxd_desc->iax_completion, 64, 0);
		goto err;
	}

	idxd_free_desc(wq, idxd_desc);
out:
	return ret;
err:
	idxd_free_desc(wq, idxd_desc);
	dev_dbg(dev, "iaa compress failed: ret=%d\n", ret);

	goto out;
}

static int iaa_decompress(struct crypto_tfm *tfm, struct acomp_req *req,
			  struct idxd_wq *wq,
			  dma_addr_t src_addr, unsigned int slen,
			  dma_addr_t dst_addr, unsigned int *dlen,
			  bool disable_async)
{
	struct iaa_device_compression_mode *active_compression_mode;
	struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);
	struct iaa_device *iaa_device;
	struct idxd_desc *idxd_desc;
	struct iax_hw_desc *desc;
	struct idxd_device *idxd;
	struct iaa_wq *iaa_wq;
	struct pci_dev *pdev;
	struct device *dev;
	int ret = 0;

	iaa_wq = idxd_wq_get_private(wq);
	iaa_device = iaa_wq->iaa_device;
	idxd = iaa_device->idxd;
	pdev = idxd->pdev;
	dev = &pdev->dev;

	active_compression_mode = get_iaa_device_compression_mode(iaa_device, ctx->mode);

	idxd_desc = idxd_alloc_desc(wq, IDXD_OP_BLOCK);
	if (IS_ERR(idxd_desc)) {
		dev_dbg(dev, "idxd descriptor allocation failed\n");
		dev_dbg(dev, "iaa decompress failed: ret=%ld\n",
			PTR_ERR(idxd_desc));
		return PTR_ERR(idxd_desc);
	}
	desc = idxd_desc->iax_hw;

	desc->flags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR | IDXD_OP_FLAG_CC;
	desc->opcode = IAX_OPCODE_DECOMPRESS;
	desc->max_dst_size = PAGE_SIZE;
	desc->decompr_flags = IAA_DECOMP_FLAGS;
	desc->priv = 0;

	desc->src1_addr = (u64)src_addr;
	desc->dst_addr = (u64)dst_addr;
	desc->max_dst_size = *dlen;
	desc->src1_size = slen;
	desc->completion_addr = idxd_desc->compl_dma;

	if (ctx->use_irq && !disable_async) {
		desc->flags |= IDXD_OP_FLAG_RCI;

		idxd_desc->crypto.req = req;
		idxd_desc->crypto.tfm = tfm;
		idxd_desc->crypto.src_addr = src_addr;
		idxd_desc->crypto.dst_addr = dst_addr;
		idxd_desc->crypto.compress = false;

		dev_dbg(dev, "%s: use_async_irq compression mode %s,"
			" src_addr %llx, dst_addr %llx\n", __func__,
			active_compression_mode->name,
			src_addr, dst_addr);
	} else if (ctx->async_mode && !disable_async)
		req->base.data = idxd_desc;

	dev_dbg(dev, "%s: decompression mode %s,"
		" desc->src1_addr %llx, desc->src1_size %d,"
		" desc->dst_addr %llx, desc->max_dst_size %d,"
		" desc->src2_addr %llx, desc->src2_size %d\n", __func__,
		active_compression_mode->name,
		desc->src1_addr, desc->src1_size, desc->dst_addr,
		desc->max_dst_size, desc->src2_addr, desc->src2_size);

	ret = idxd_submit_desc(wq, idxd_desc);
	if (ret) {
		dev_dbg(dev, "submit_desc failed ret=%d\n", ret);
		goto err;
	}

	/* Update stats */
	update_total_decomp_calls();
	update_wq_decomp_calls(wq);

	if (ctx->async_mode && !disable_async) {
		ret = -EINPROGRESS;
		dev_dbg(dev, "%s: returning -EINPROGRESS\n", __func__);
		goto out;
	}

	ret = check_completion(dev, idxd_desc->iax_completion, false, false);
	if (ret) {
		dev_dbg(dev, "%s: check_completion failed ret=%d\n", __func__, ret);
		if (idxd_desc->iax_completion->status == IAA_ANALYTICS_ERROR) {
			pr_warn("%s: falling back to deflate-generic decompress, "
				"analytics error code %x\n", __func__,
				idxd_desc->iax_completion->error_code);
			ret = deflate_generic_decompress(req);
			if (ret) {
				dev_dbg(dev, "%s: deflate-generic failed ret=%d\n",
					__func__, ret);
				goto err;
			}
		} else {
			goto err;
		}
	} else {
		req->dlen = idxd_desc->iax_completion->output_size;
	}

	*dlen = req->dlen;

	if (!ctx->async_mode || disable_async)
		idxd_free_desc(wq, idxd_desc);

	/* Update stats */
	update_total_decomp_bytes_in(slen);
	update_wq_decomp_bytes(wq, slen);
out:
	return ret;
err:
	idxd_free_desc(wq, idxd_desc);
	dev_dbg(dev, "iaa decompress failed: ret=%d\n", ret);

	goto out;
}

static int iaa_comp_acompress(struct acomp_req *req)
{
	struct iaa_compression_ctx *compression_ctx;
	struct crypto_tfm *tfm = req->base.tfm;
	dma_addr_t src_addr, dst_addr;
	bool disable_async = false;
	int nr_sgs, cpu, ret = 0;
	struct iaa_wq *iaa_wq;
	u32 compression_crc;
	struct idxd_wq *wq;
	struct device *dev;
	u64 start_time_ns;
	int order = -1;

	compression_ctx = crypto_tfm_ctx(tfm);

	if (!iaa_crypto_enabled) {
		pr_debug("iaa_crypto disabled, not compressing\n");
		return -ENODEV;
	}

	if (!req->src || !req->slen) {
		pr_debug("invalid src, not compressing\n");
		return -EINVAL;
	}

	cpu = get_cpu();
	wq = wq_table_next_wq(cpu);
	put_cpu();
	if (!wq) {
		pr_debug("no wq configured for cpu=%d\n", cpu);
		return -ENODEV;
	}

	ret = iaa_wq_get(wq);
	if (ret) {
		pr_debug("no wq available for cpu=%d\n", cpu);
		return -ENODEV;
	}

	iaa_wq = idxd_wq_get_private(wq);

	if (!req->dst) {
		gfp_t flags = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;

		/* incompressible data will always be < 2 * slen */
		req->dlen = 2 * req->slen;
		order = order_base_2(round_up(req->dlen, PAGE_SIZE) / PAGE_SIZE);
		req->dst = sgl_alloc_order(req->dlen, order, false, flags, NULL);
		if (!req->dst) {
			ret = -ENOMEM;
			order = -1;
			goto out;
		}
		disable_async = true;
	}

	dev = &wq->idxd->pdev->dev;

	nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map src sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto out;
	}
	src_addr = sg_dma_address(req->src);
	dev_dbg(dev, "dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
		" req->slen %d, sg_dma_len(sg) %d\n", src_addr, nr_sgs,
		req->src, req->slen, sg_dma_len(req->src));

	nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map dst sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto err_map_dst;
	}
	dst_addr = sg_dma_address(req->dst);
	dev_dbg(dev, "dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
		" req->dlen %d, sg_dma_len(sg) %d\n", dst_addr, nr_sgs,
		req->dst, req->dlen, sg_dma_len(req->dst));

	start_time_ns = iaa_get_ts();
	ret = iaa_compress(tfm, req, wq, src_addr, req->slen, dst_addr,
			   &req->dlen, &compression_crc, disable_async);
	update_max_comp_delay_ns(start_time_ns);
	if (ret == -EINPROGRESS)
		return ret;

	if (!ret && compression_ctx->verify_compress) {
		ret = iaa_remap_for_verify(dev, iaa_wq, req, &src_addr, &dst_addr);
		if (ret) {
			dev_dbg(dev, "%s: compress verify remap failed ret=%d\n", __func__, ret);
			goto out;
		}

		ret = iaa_compress_verify(tfm, req, wq, src_addr, req->slen,
					  dst_addr, &req->dlen, compression_crc);
		if (ret)
			dev_dbg(dev, "asynchronous compress verification failed ret=%d\n", ret);

		dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_TO_DEVICE);
		dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_FROM_DEVICE);

		goto out;
	}

	if (ret)
		dev_dbg(dev, "asynchronous compress failed ret=%d\n", ret);

	dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
err_map_dst:
	dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
out:
	iaa_wq_put(wq);

	if (order >= 0)
		sgl_free_order(req->dst, order);

	return ret;
}

static int iaa_comp_adecompress_alloc_dest(struct acomp_req *req)
{
	gfp_t flags = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
		GFP_KERNEL : GFP_ATOMIC;
	struct crypto_tfm *tfm = req->base.tfm;
	dma_addr_t src_addr, dst_addr;
	int nr_sgs, cpu, ret = 0;
	struct iaa_wq *iaa_wq;
	struct device *dev;
	struct idxd_wq *wq;
	u64 start_time_ns;
	int order = -1;

	cpu = get_cpu();
	wq = wq_table_next_wq(cpu);
	put_cpu();
	if (!wq) {
		pr_debug("no wq configured for cpu=%d\n", cpu);
		return -ENODEV;
	}

	ret = iaa_wq_get(wq);
	if (ret) {
		pr_debug("no wq available for cpu=%d\n", cpu);
		return -ENODEV;
	}

	iaa_wq = idxd_wq_get_private(wq);

	dev = &wq->idxd->pdev->dev;

	nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map src sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto out;
	}
	src_addr = sg_dma_address(req->src);
	dev_dbg(dev, "dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
		" req->slen %d, sg_dma_len(sg) %d\n", src_addr, nr_sgs,
		req->src, req->slen, sg_dma_len(req->src));

	req->dlen = 4 * req->slen; /* start with ~avg comp rato */
alloc_dest:
	order = order_base_2(round_up(req->dlen, PAGE_SIZE) / PAGE_SIZE);
	req->dst = sgl_alloc_order(req->dlen, order, false, flags, NULL);
	if (!req->dst) {
		ret = -ENOMEM;
		order = -1;
		goto out;
	}

	nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map dst sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto err_map_dst;
	}

	dst_addr = sg_dma_address(req->dst);
	dev_dbg(dev, "dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
		" req->dlen %d, sg_dma_len(sg) %d\n", dst_addr, nr_sgs,
		req->dst, req->dlen, sg_dma_len(req->dst));
	start_time_ns = iaa_get_ts();
	ret = iaa_decompress(tfm, req, wq, src_addr, req->slen,
			     dst_addr, &req->dlen, true);
	update_max_decomp_delay_ns(start_time_ns);
	if (ret == -EOVERFLOW) {
		dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
		req->dlen *= 2;
		if (req->dlen > CRYPTO_ACOMP_DST_MAX)
			goto err_map_dst;
		goto alloc_dest;
	}

	if (ret != 0)
		dev_dbg(dev, "asynchronous decompress failed ret=%d\n", ret);

	dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
err_map_dst:
	dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
out:
	iaa_wq_put(wq);

	if (order >= 0)
		sgl_free_order(req->dst, order);

	return ret;
}

static int iaa_comp_adecompress(struct acomp_req *req)
{
	struct crypto_tfm *tfm = req->base.tfm;
	dma_addr_t src_addr, dst_addr;
	int nr_sgs, cpu, ret = 0;
	struct iaa_wq *iaa_wq;
	struct device *dev;
	u64 start_time_ns;
	struct idxd_wq *wq;

	if (!iaa_crypto_enabled) {
		pr_debug("iaa_crypto disabled, not decompressing\n");
		return -ENODEV;
	}

	if (!req->src || !req->slen) {
		pr_debug("invalid src, not decompressing\n");
		return -EINVAL;
	}

	if (!req->dst)
		return iaa_comp_adecompress_alloc_dest(req);

	cpu = get_cpu();
	wq = wq_table_next_wq(cpu);
	put_cpu();
	if (!wq) {
		pr_debug("no wq configured for cpu=%d\n", cpu);
		return -ENODEV;
	}

	ret = iaa_wq_get(wq);
	if (ret) {
		pr_debug("no wq available for cpu=%d\n", cpu);
		return -ENODEV;
	}

	iaa_wq = idxd_wq_get_private(wq);

	dev = &wq->idxd->pdev->dev;

	nr_sgs = dma_map_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map src sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto out;
	}
	src_addr = sg_dma_address(req->src);
	dev_dbg(dev, "dma_map_sg, src_addr %llx, nr_sgs %d, req->src %p,"
		" req->slen %d, sg_dma_len(sg) %d\n", src_addr, nr_sgs,
		req->src, req->slen, sg_dma_len(req->src));

	nr_sgs = dma_map_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
	if (nr_sgs <= 0 || nr_sgs > 1) {
		dev_dbg(dev, "couldn't map dst sg for iaa device %d,"
			" wq %d: ret=%d\n", iaa_wq->iaa_device->idxd->id,
			iaa_wq->wq->id, ret);
		ret = -EIO;
		goto err_map_dst;
	}
	dst_addr = sg_dma_address(req->dst);
	dev_dbg(dev, "dma_map_sg, dst_addr %llx, nr_sgs %d, req->dst %p,"
		" req->dlen %d, sg_dma_len(sg) %d\n", dst_addr, nr_sgs,
		req->dst, req->dlen, sg_dma_len(req->dst));

	start_time_ns = iaa_get_ts();
	ret = iaa_decompress(tfm, req, wq, src_addr, req->slen,
			     dst_addr, &req->dlen, false);
	update_max_decomp_delay_ns(start_time_ns);
	if (ret == -EINPROGRESS)
		return ret;

	if (ret != 0)
		dev_dbg(dev, "asynchronous decompress failed ret=%d\n", ret);

	dma_unmap_sg(dev, req->dst, sg_nents(req->dst), DMA_FROM_DEVICE);
err_map_dst:
	dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
out:
	iaa_wq_put(wq);

	return ret;
}

static void compression_ctx_init(struct iaa_compression_ctx *ctx)
{
	ctx->verify_compress = iaa_verify_compress;
	ctx->async_mode = async_mode;
	ctx->use_irq = use_irq;
}

static int iaa_comp_init_fixed(struct crypto_acomp *acomp_tfm)
{
	struct crypto_tfm *tfm = crypto_acomp_tfm(acomp_tfm);
	struct iaa_compression_ctx *ctx = crypto_tfm_ctx(tfm);

	compression_ctx_init(ctx);

	ctx->mode = IAA_MODE_FIXED;

	return 0;
}

static void dst_free(struct scatterlist *sgl)
{
	/*
	 * Called for req->dst = NULL cases but we free elsewhere
	 * using sgl_free_order().
	 */
}

static struct acomp_alg iaa_acomp_fixed_deflate = {
	.init			= iaa_comp_init_fixed,
	.compress		= iaa_comp_acompress,
	.decompress		= iaa_comp_adecompress,
	.dst_free               = dst_free,
	.base			= {
		.cra_name		= "deflate",
		.cra_driver_name	= "deflate-iaa",
		.cra_flags		= CRYPTO_ALG_ASYNC,
		.cra_ctxsize		= sizeof(struct iaa_compression_ctx),
		.cra_module		= THIS_MODULE,
		.cra_priority		= IAA_ALG_PRIORITY,
	}
};

static int iaa_register_compression_device(void)
{
	int ret;

	ret = crypto_register_acomp(&iaa_acomp_fixed_deflate);
	if (ret) {
		pr_err("deflate algorithm acomp fixed registration failed (%d)\n", ret);
		goto out;
	}

	iaa_crypto_registered = true;
out:
	return ret;
}

static int iaa_unregister_compression_device(void)
{
	if (iaa_crypto_registered)
		crypto_unregister_acomp(&iaa_acomp_fixed_deflate);

	return 0;
}

static int iaa_crypto_probe(struct idxd_dev *idxd_dev)
{
	struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
	struct idxd_device *idxd = wq->idxd;
	struct idxd_driver_data *data = idxd->data;
	struct device *dev = &idxd_dev->conf_dev;
	bool first_wq = false;
	int ret = 0;

	if (idxd->state != IDXD_DEV_ENABLED)
		return -ENXIO;

	if (data->type != IDXD_TYPE_IAX)
		return -ENODEV;

	mutex_lock(&wq->wq_lock);

	if (idxd_wq_get_private(wq)) {
		mutex_unlock(&wq->wq_lock);
		return -EBUSY;
	}

	if (!idxd_wq_driver_name_match(wq, dev)) {
		dev_dbg(dev, "wq %d.%d driver_name match failed: wq driver_name %s, dev driver name %s\n",
			idxd->id, wq->id, wq->driver_name, dev->driver->name);
		idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME;
		ret = -ENODEV;
		goto err;
	}

	wq->type = IDXD_WQT_KERNEL;

	ret = idxd_drv_enable_wq(wq);
	if (ret < 0) {
		dev_dbg(dev, "enable wq %d.%d failed: %d\n",
			idxd->id, wq->id, ret);
		ret = -ENXIO;
		goto err;
	}

	mutex_lock(&iaa_devices_lock);

	if (list_empty(&iaa_devices)) {
		ret = alloc_wq_table(wq->idxd->max_wqs);
		if (ret)
			goto err_alloc;
		first_wq = true;
	}

	ret = save_iaa_wq(wq);
	if (ret)
		goto err_save;

	rebalance_wq_table();

	if (first_wq) {
		iaa_crypto_enabled = true;
		ret = iaa_register_compression_device();
		if (ret != 0) {
			iaa_crypto_enabled = false;
			dev_dbg(dev, "IAA compression device registration failed\n");
			goto err_register;
		}
		try_module_get(THIS_MODULE);

		pr_info("iaa_crypto now ENABLED\n");
	}

	mutex_unlock(&iaa_devices_lock);
out:
	mutex_unlock(&wq->wq_lock);

	return ret;

err_register:
	remove_iaa_wq(wq);
	free_iaa_wq(idxd_wq_get_private(wq));
err_save:
	if (first_wq)
		free_wq_table();
err_alloc:
	mutex_unlock(&iaa_devices_lock);
	idxd_drv_disable_wq(wq);
err:
	wq->type = IDXD_WQT_NONE;

	goto out;
}

static void iaa_crypto_remove(struct idxd_dev *idxd_dev)
{
	struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
	struct idxd_device *idxd = wq->idxd;
	struct iaa_wq *iaa_wq;
	bool free = false;

	idxd_wq_quiesce(wq);

	mutex_lock(&wq->wq_lock);
	mutex_lock(&iaa_devices_lock);

	remove_iaa_wq(wq);

	spin_lock(&idxd->dev_lock);
	iaa_wq = idxd_wq_get_private(wq);
	if (!iaa_wq) {
		spin_unlock(&idxd->dev_lock);
		pr_err("%s: no iaa_wq available to remove\n", __func__);
		goto out;
	}

	if (iaa_wq->ref) {
		iaa_wq->remove = true;
	} else {
		wq = iaa_wq->wq;
		idxd_wq_set_private(wq, NULL);
		free = true;
	}
	spin_unlock(&idxd->dev_lock);
	if (free) {
		__free_iaa_wq(iaa_wq);
		kfree(iaa_wq);
	}

	idxd_drv_disable_wq(wq);
	rebalance_wq_table();

	if (nr_iaa == 0) {
		iaa_crypto_enabled = false;
		free_wq_table();
		module_put(THIS_MODULE);

		pr_info("iaa_crypto now DISABLED\n");
	}
out:
	mutex_unlock(&iaa_devices_lock);
	mutex_unlock(&wq->wq_lock);
}

static enum idxd_dev_type dev_types[] = {
	IDXD_DEV_WQ,
	IDXD_DEV_NONE,
};

static struct idxd_device_driver iaa_crypto_driver = {
	.probe = iaa_crypto_probe,
	.remove = iaa_crypto_remove,
	.name = IDXD_SUBDRIVER_NAME,
	.type = dev_types,
	.desc_complete = iaa_desc_complete,
};

static int __init iaa_crypto_init_module(void)
{
	int ret = 0;
	int node;

	nr_cpus = num_online_cpus();
	for_each_node_with_cpus(node)
		nr_nodes++;
	if (!nr_nodes) {
		pr_err("IAA couldn't find any nodes with cpus\n");
		return -ENODEV;
	}
	nr_cpus_per_node = nr_cpus / nr_nodes;

	if (crypto_has_comp("deflate-generic", 0, 0))
		deflate_generic_tfm = crypto_alloc_comp("deflate-generic", 0, 0);

	if (IS_ERR_OR_NULL(deflate_generic_tfm)) {
		pr_err("IAA could not alloc %s tfm: errcode = %ld\n",
		       "deflate-generic", PTR_ERR(deflate_generic_tfm));
		return -ENOMEM;
	}

	ret = iaa_aecs_init_fixed();
	if (ret < 0) {
		pr_debug("IAA fixed compression mode init failed\n");
		goto err_aecs_init;
	}

	ret = idxd_driver_register(&iaa_crypto_driver);
	if (ret) {
		pr_debug("IAA wq sub-driver registration failed\n");
		goto err_driver_reg;
	}

	ret = driver_create_file(&iaa_crypto_driver.drv,
				 &driver_attr_verify_compress);
	if (ret) {
		pr_debug("IAA verify_compress attr creation failed\n");
		goto err_verify_attr_create;
	}

	ret = driver_create_file(&iaa_crypto_driver.drv,
				 &driver_attr_sync_mode);
	if (ret) {
		pr_debug("IAA sync mode attr creation failed\n");
		goto err_sync_attr_create;
	}

	if (iaa_crypto_debugfs_init())
		pr_warn("debugfs init failed, stats not available\n");

	pr_debug("initialized\n");
out:
	return ret;

err_sync_attr_create:
	driver_remove_file(&iaa_crypto_driver.drv,
			   &driver_attr_verify_compress);
err_verify_attr_create:
	idxd_driver_unregister(&iaa_crypto_driver);
err_driver_reg:
	iaa_aecs_cleanup_fixed();
err_aecs_init:
	crypto_free_comp(deflate_generic_tfm);

	goto out;
}

static void __exit iaa_crypto_cleanup_module(void)
{
	if (iaa_unregister_compression_device())
		pr_debug("IAA compression device unregister failed\n");

	iaa_crypto_debugfs_cleanup();
	driver_remove_file(&iaa_crypto_driver.drv,
			   &driver_attr_sync_mode);
	driver_remove_file(&iaa_crypto_driver.drv,
			   &driver_attr_verify_compress);
	idxd_driver_unregister(&iaa_crypto_driver);
	iaa_aecs_cleanup_fixed();
	crypto_free_comp(deflate_generic_tfm);

	pr_debug("cleaned up\n");
}

MODULE_IMPORT_NS(IDXD);
MODULE_LICENSE("GPL");
MODULE_ALIAS_IDXD_DEVICE(0);
MODULE_AUTHOR("Intel Corporation");
MODULE_DESCRIPTION("IAA Compression Accelerator Crypto Driver");

module_init(iaa_crypto_init_module);
module_exit(iaa_crypto_cleanup_module);
