/*
 * DM request based crypto driver
 *
 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#include <linux/completion.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include <linux/crypto.h>
#include <linux/qcrypto.h>
#include <linux/workqueue.h>
#include <linux/backing-dev.h>
#include <linux/atomic.h>
#include <linux/scatterlist.h>
#include <linux/device-mapper.h>
#include <linux/printk.h>

#include <asm/page.h>
#include <asm/unaligned.h>
#include <crypto/skcipher.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#include <crypto/hash.h>
#include <crypto/md5.h>
#include <crypto/algapi.h>
#include <crypto/ice.h>

#define DM_MSG_PREFIX "req-crypt"

#define MAX_SG_LIST	1024
#define REQ_DM_512_KB (512*1024)
#define MAX_ENCRYPTION_BUFFERS 1
#define MIN_IOS 256
#define MIN_POOL_PAGES 32
#define KEY_SIZE_XTS 32
#define AES_XTS_IV_LEN 16
#define MAX_MSM_ICE_KEY_LUT_SIZE 32
#define SECTOR_SIZE 512
#define MIN_CRYPTO_TRANSFER_SIZE (4 * 1024)

#define DM_REQ_CRYPT_ERROR -1
#define DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC -2

/*
 * ENCRYPTION_MODE_CRYPTO means dm-req-crypt would invoke crypto operations
 * for all of the requests. Crypto operations are performed by crypto engine
 * plugged with Linux Kernel Crypto APIs
 */
#define DM_REQ_CRYPT_ENCRYPTION_MODE_CRYPTO 0
/*
 * ENCRYPTION_MODE_TRANSPARENT means dm-req-crypt would not invoke crypto
 * operations for any of the requests. Data would be encrypted or decrypted
 * using Inline Crypto Engine(ICE) embedded in storage hardware
 */
#define DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT 1

#define DM_REQ_CRYPT_QUEUE_SIZE 256

struct req_crypt_result {
	struct completion completion;
	int err;
};

#define FDE_KEY_ID	0
#define PFE_KEY_ID	1

static struct dm_dev *dev;
static struct kmem_cache *_req_crypt_io_pool;
static struct kmem_cache *_req_dm_scatterlist_pool;
static sector_t start_sector_orig;
static struct workqueue_struct *req_crypt_queue;
static struct workqueue_struct *req_crypt_split_io_queue;
static mempool_t *req_io_pool;
static mempool_t *req_page_pool;
static mempool_t *req_scatterlist_pool;
static bool is_fde_enabled;
static struct crypto_skcipher *tfm;
static unsigned int encryption_mode;
static struct ice_crypto_setting *ice_settings;

unsigned int num_engines;
unsigned int num_engines_fde, fde_cursor;
unsigned int num_engines_pfe, pfe_cursor;
struct crypto_engine_entry *fde_eng, *pfe_eng;
DEFINE_MUTEX(engine_list_mutex);

struct req_dm_crypt_io {
	struct ice_crypto_setting ice_settings;
	struct work_struct work;
	struct request *cloned_request;
	int error;
	atomic_t pending;
	struct timespec start_time;
	bool should_encrypt;
	bool should_decrypt;
	u32 key_id;
};

struct req_dm_split_req_io {
	struct work_struct work;
	struct scatterlist *req_split_sg_read;
	struct req_crypt_result result;
	struct crypto_engine_entry *engine;
	u8 IV[AES_XTS_IV_LEN];
	int size;
	struct request *clone;
};

#ifdef CONFIG_FIPS_ENABLE
static struct qcrypto_func_set dm_qcrypto_func;
#else
static struct qcrypto_func_set dm_qcrypto_func = {
		qcrypto_cipher_set_device_hw,
		qcrypto_cipher_set_flag,
		qcrypto_get_num_engines,
		qcrypto_get_engine_list
};
#endif
static void req_crypt_cipher_complete
		(struct crypto_async_request *req, int err);
static void req_cryptd_split_req_queue_cb
		(struct work_struct *work);
static void req_cryptd_split_req_queue
		(struct req_dm_split_req_io *io);
static void req_crypt_split_io_complete
		(struct req_crypt_result *res, int err);

static  bool req_crypt_should_encrypt(struct req_dm_crypt_io *req)
{
	int ret = 0;
	bool should_encrypt = false;
	struct bio *bio = NULL;
	bool is_encrypted = false;
	bool is_inplace = false;

	if (!req || !req->cloned_request || !req->cloned_request->bio)
		return false;

	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT)
		return false;
	bio = req->cloned_request->bio;

	/* req->key_id = key_id; @todo support more than 1 pfe key */
	if ((ret == 0) && (is_encrypted || is_inplace)) {
		should_encrypt = true;
		req->key_id = PFE_KEY_ID;
	} else if (is_fde_enabled) {
		should_encrypt = true;
		req->key_id = FDE_KEY_ID;
	}

	return should_encrypt;
}

static  bool req_crypt_should_deccrypt(struct req_dm_crypt_io *req)
{
	int ret = 0;
	bool should_deccrypt = false;
	struct bio *bio = NULL;
	bool is_encrypted = false;
	bool is_inplace = false;

	if (!req || !req->cloned_request || !req->cloned_request->bio)
		return false;
	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT)
		return false;

	bio = req->cloned_request->bio;

	/* req->key_id = key_id; @todo support more than 1 pfe key */
	if ((ret == 0) && (is_encrypted && !is_inplace)) {
		should_deccrypt = true;
		req->key_id = PFE_KEY_ID;
	} else if (is_fde_enabled) {
		should_deccrypt = true;
		req->key_id = FDE_KEY_ID;
	}

	return should_deccrypt;
}

static void req_crypt_inc_pending(struct req_dm_crypt_io *io)
{
	atomic_inc(&io->pending);
}

static void req_crypt_dec_pending_encrypt(struct req_dm_crypt_io *io)
{
	int error = 0;
	struct request *clone = NULL;

	if (io) {
		error = io->error;
		if (io->cloned_request) {
			clone = io->cloned_request;
		} else {
			DMERR("%s io->cloned_request is NULL\n",
								__func__);
			/*
			 * If Clone is NULL we cannot do anything,
			 * this should never happen
			 */
			WARN_ON(1);
			return;
		}
	} else {
		DMERR("%s io is NULL\n", __func__);
		/*
		 * If Clone is NULL we cannot do anything,
		 * this should never happen
		 */
		WARN_ON(1);
		return;
	}

	atomic_dec(&io->pending);

	if (error < 0) {
		dm_kill_unmapped_request(clone, error);
		mempool_free(io, req_io_pool);
	} else
		dm_dispatch_request(clone);
}

static void req_crypt_dec_pending_decrypt(struct req_dm_crypt_io *io)
{
	int error = 0;
	struct request *clone = NULL;

	if (io) {
		error = io->error;
		if (io->cloned_request) {
			clone = io->cloned_request;
		} else {
			DMERR("%s io->cloned_request is NULL\n",
								__func__);
			/*
			 * If Clone is NULL we cannot do anything,
			 * this should never happen
			 */
			WARN_ON(1);
			return;
		}
	} else {
		DMERR("%s io is NULL\n",
							__func__);
		/*
		 * If Clone is NULL we cannot do anything,
		 * this should never happen
		 */
		WARN_ON(1);
		return;
	}

	/* Should never get here if io or Clone is NULL */
	dm_end_request(clone, error);
	atomic_dec(&io->pending);
	mempool_free(io, req_io_pool);
}

/*
 * The callback that will be called by the worker queue to perform Decryption
 * for reads and use the dm function to complete the bios and requests.
 */
static void req_cryptd_crypt_read_convert(struct req_dm_crypt_io *io)
{
	struct request *clone = NULL;
	int error = DM_REQ_CRYPT_ERROR;
	int total_sg_len = 0, total_bytes_in_req = 0, temp_size = 0, i = 0;
	struct scatterlist *sg = NULL;
	struct scatterlist *req_sg_read = NULL;

	unsigned int engine_list_total = 0;
	struct crypto_engine_entry *curr_engine_list = NULL;
	bool split_transfers = 0;
	sector_t tempiv;
	struct req_dm_split_req_io *split_io = NULL;

	if (io) {
		error = io->error;
		if (io->cloned_request) {
			clone = io->cloned_request;
		} else {
			DMERR("%s io->cloned_request is NULL\n",
								__func__);
			error = DM_REQ_CRYPT_ERROR;
			goto submit_request;
		}
	} else {
		DMERR("%s io is NULL\n",
							__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto submit_request;
	}

	req_crypt_inc_pending(io);

	mutex_lock(&engine_list_mutex);

	engine_list_total = (io->key_id == FDE_KEY_ID ? num_engines_fde :
						   (io->key_id == PFE_KEY_ID ?
							num_engines_pfe : 0));

	curr_engine_list = (io->key_id == FDE_KEY_ID ? fde_eng :
						   (io->key_id == PFE_KEY_ID ?
							pfe_eng : NULL));

	mutex_unlock(&engine_list_mutex);

	req_sg_read = (struct scatterlist *)mempool_alloc(req_scatterlist_pool,
								GFP_KERNEL);
	if (!req_sg_read) {
		DMERR("%s req_sg_read allocation failed\n",
						__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}
	memset(req_sg_read, 0, sizeof(struct scatterlist) * MAX_SG_LIST);

	total_sg_len = blk_rq_map_sg_no_cluster(clone->q, clone, req_sg_read);
	if ((total_sg_len <= 0) || (total_sg_len > MAX_SG_LIST)) {
		DMERR("%s Request Error%d", __func__, total_sg_len);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}

	total_bytes_in_req = clone->__data_len;
	if (total_bytes_in_req > REQ_DM_512_KB) {
		DMERR("%s total_bytes_in_req > 512 MB %d",
				__func__, total_bytes_in_req);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}


	if ((clone->__data_len >= (MIN_CRYPTO_TRANSFER_SIZE *
		engine_list_total))
		&& (engine_list_total > 1))
		split_transfers = 1;

	if (split_transfers) {
		split_io = kzalloc(sizeof(struct req_dm_split_req_io)
				* engine_list_total, GFP_KERNEL);
		if (!split_io) {
			DMERR("%s split_io allocation failed\n", __func__);
			error = DM_REQ_CRYPT_ERROR;
			goto skcipher_req_alloc_failure;
		}

		split_io[0].req_split_sg_read = sg = req_sg_read;
		split_io[engine_list_total - 1].size = total_bytes_in_req;
		for (i = 0; i < (engine_list_total); i++) {
			while ((sg) && i < (engine_list_total - 1)) {
				split_io[i].size += sg->length;
				split_io[engine_list_total - 1].size -=
						sg->length;
				if (split_io[i].size >=
						(total_bytes_in_req /
							engine_list_total)) {
					split_io[i + 1].req_split_sg_read =
							sg_next(sg);
					sg_mark_end(sg);
					break;
				}
				sg = sg_next(sg);
			}
			split_io[i].engine = &curr_engine_list[i];
			init_completion(&split_io[i].result.completion);
			memset(&split_io[i].IV, 0, AES_XTS_IV_LEN);
			tempiv = clone->__sector + (temp_size / SECTOR_SIZE);
			memcpy(&split_io[i].IV, &tempiv, sizeof(sector_t));
			temp_size +=  split_io[i].size;
			split_io[i].clone = clone;
			req_cryptd_split_req_queue(&split_io[i]);
		}
	} else {
		split_io = kzalloc(sizeof(struct req_dm_split_req_io),
				GFP_KERNEL);
		if (!split_io) {
			DMERR("%s split_io allocation failed\n", __func__);
			error = DM_REQ_CRYPT_ERROR;
			goto skcipher_req_alloc_failure;
		}
		split_io->engine = &curr_engine_list[0];
		init_completion(&split_io->result.completion);
		memcpy(split_io->IV, &clone->__sector, sizeof(sector_t));
		split_io->req_split_sg_read = req_sg_read;
		split_io->size = total_bytes_in_req;
		split_io->clone = clone;
		req_cryptd_split_req_queue(split_io);
	}

	if (!split_transfers) {
		wait_for_completion_interruptible(&split_io->result.completion);
		if (split_io->result.err) {
			DMERR("%s error = %d for request\n",
				 __func__, split_io->result.err);
			error = DM_REQ_CRYPT_ERROR;
			goto skcipher_req_alloc_failure;
		}
	} else {
		for (i = 0; i < (engine_list_total); i++) {
			wait_for_completion_interruptible(
					&split_io[i].result.completion);
			if (split_io[i].result.err) {
				DMERR("%s error = %d for %dst request\n",
					 __func__, split_io[i].result.err, i);
				error = DM_REQ_CRYPT_ERROR;
				goto skcipher_req_alloc_failure;
			}
		}
	}
	error = 0;
skcipher_req_alloc_failure:

	mempool_free(req_sg_read, req_scatterlist_pool);
	kfree(split_io);
submit_request:
	if (io)
		io->error = error;
	req_crypt_dec_pending_decrypt(io);
}

/*
 * This callback is called by the worker queue to perform non-decrypt reads
 * and use the dm function to complete the bios and requests.
 */
static void req_cryptd_crypt_read_plain(struct req_dm_crypt_io *io)
{
	struct request *clone = NULL;
	int error = 0;

	if (!io || !io->cloned_request) {
		DMERR("%s io is invalid\n", __func__);
		WARN_ON(1); /* should not happen */
		return;
	}

	clone = io->cloned_request;

	dm_end_request(clone, error);
	mempool_free(io, req_io_pool);
}

/*
 * The callback that will be called by the worker queue to perform Encryption
 * for writes and submit the request using the elevelator.
 */
static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io)
{
	struct request *clone = NULL;
	struct bio *bio_src = NULL;
	unsigned int total_sg_len_req_in = 0, total_sg_len_req_out = 0,
		total_bytes_in_req = 0, error = DM_MAPIO_REMAPPED, rc = 0;
	struct req_iterator iter;
	struct req_iterator iter1;
	struct skcipher_request *req = NULL;
	struct req_crypt_result result;
	struct bio_vec bvec;
	struct scatterlist *req_sg_in = NULL;
	struct scatterlist *req_sg_out = NULL;
	int copy_bio_sector_to_req = 0;
	gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
	struct page *page = NULL;
	u8 IV[AES_XTS_IV_LEN];
	int remaining_size = 0, err = 0;
	struct crypto_engine_entry engine;
	unsigned int engine_list_total = 0;
	struct crypto_engine_entry *curr_engine_list = NULL;
	unsigned int *engine_cursor = NULL;


	if (io) {
		if (io->cloned_request) {
			clone = io->cloned_request;
		} else {
			DMERR("%s io->cloned_request is NULL\n",
								__func__);
			error = DM_REQ_CRYPT_ERROR;
			goto submit_request;
		}
	} else {
		DMERR("%s io is NULL\n",
							__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto submit_request;
	}

	req_crypt_inc_pending(io);

	req = skcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req) {
		DMERR("%s skcipher request allocation failed\n",
					__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}

	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
				req_crypt_cipher_complete, &result);

	mutex_lock(&engine_list_mutex);
	engine_list_total = (io->key_id == FDE_KEY_ID ? num_engines_fde :
						   (io->key_id == PFE_KEY_ID ?
							num_engines_pfe : 0));

	curr_engine_list = (io->key_id == FDE_KEY_ID ? fde_eng :
						(io->key_id == PFE_KEY_ID ?
						pfe_eng : NULL));

	engine_cursor = (io->key_id == FDE_KEY_ID ? &fde_cursor :
					(io->key_id == PFE_KEY_ID ? &pfe_cursor
					: NULL));
	if ((engine_list_total < 1) || (curr_engine_list == NULL) ||
				(engine_cursor == NULL)) {
		DMERR("%s Unknown Key ID!\n", __func__);
		error = DM_REQ_CRYPT_ERROR;
		mutex_unlock(&engine_list_mutex);
		goto skcipher_req_alloc_failure;
	}

	engine = curr_engine_list[*engine_cursor];
	(*engine_cursor)++;
	(*engine_cursor) %= engine_list_total;

	err = (dm_qcrypto_func.cipher_set)(req, engine.ce_device,
				   engine.hw_instance);
	if (err) {
		DMERR("%s qcrypto_cipher_set_device_hw failed with err %d\n",
				__func__, err);
		mutex_unlock(&engine_list_mutex);
		goto skcipher_req_alloc_failure;
	}
	mutex_unlock(&engine_list_mutex);

	init_completion(&result.completion);

	(dm_qcrypto_func.cipher_flag)(req,
		QCRYPTO_CTX_USE_PIPE_KEY | QCRYPTO_CTX_XTS_DU_SIZE_512B);
	crypto_skcipher_clear_flags(tfm, ~0);
	crypto_skcipher_setkey(tfm, NULL, KEY_SIZE_XTS);

	req_sg_in = (struct scatterlist *)mempool_alloc(req_scatterlist_pool,
								GFP_KERNEL);
	if (!req_sg_in) {
		DMERR("%s req_sg_in allocation failed\n",
					__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}
	memset(req_sg_in, 0, sizeof(struct scatterlist) * MAX_SG_LIST);

	req_sg_out = (struct scatterlist *)mempool_alloc(req_scatterlist_pool,
								GFP_KERNEL);
	if (!req_sg_out) {
		DMERR("%s req_sg_out allocation failed\n",
					__func__);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}
	memset(req_sg_out, 0, sizeof(struct scatterlist) * MAX_SG_LIST);

	total_sg_len_req_in = blk_rq_map_sg(clone->q, clone, req_sg_in);
	if ((total_sg_len_req_in <= 0) ||
			(total_sg_len_req_in > MAX_SG_LIST)) {
		DMERR("%s Request Error%d", __func__, total_sg_len_req_in);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}

	total_bytes_in_req = clone->__data_len;
	if (total_bytes_in_req > REQ_DM_512_KB) {
		DMERR("%s total_bytes_in_req > 512 MB %d",
				__func__, total_bytes_in_req);
		error = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}

	rq_for_each_segment(bvec, clone, iter) {
		if (bvec.bv_len > remaining_size) {
			page = NULL;
			while (page == NULL) {
				page = mempool_alloc(req_page_pool, gfp_mask);
				if (!page) {
					DMERR("%s Crypt page alloc failed",
							__func__);
					congestion_wait(BLK_RW_ASYNC, HZ/100);
				}
			}

			bvec.bv_page = page;
			bvec.bv_offset = 0;
			remaining_size = PAGE_SIZE -  bvec.bv_len;
			if (remaining_size < 0)
				WARN_ON(1);
		} else {
			bvec.bv_page = page;
			bvec.bv_offset = PAGE_SIZE - remaining_size;
			remaining_size = remaining_size -  bvec.bv_len;
		}
	}

	total_sg_len_req_out = blk_rq_map_sg(clone->q, clone, req_sg_out);
	if ((total_sg_len_req_out <= 0) ||
			(total_sg_len_req_out > MAX_SG_LIST)) {
		DMERR("%s Request Error %d", __func__, total_sg_len_req_out);
		error = DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC;
		goto skcipher_req_alloc_failure;
	}

	memset(IV, 0, AES_XTS_IV_LEN);
	memcpy(IV, &clone->__sector, sizeof(sector_t));

	skcipher_request_set_crypt(req, req_sg_in, req_sg_out,
			total_bytes_in_req, (void *) IV);

	rc = crypto_skcipher_encrypt(req);

	switch (rc) {
	case 0:
		break;

	case -EBUSY:
		/*
		 * Lets make this synchronous request by waiting on
		 * in progress as well
		 */
	case -EINPROGRESS:
		wait_for_completion_interruptible(&result.completion);
		if (result.err) {
			DMERR("%s error = %d encrypting the request\n",
				 __func__, result.err);
			error = DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC;
			goto skcipher_req_alloc_failure;
		}
		break;

	default:
		error = DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC;
		goto skcipher_req_alloc_failure;
	}

	__rq_for_each_bio(bio_src, clone) {
		if (copy_bio_sector_to_req == 0)
			copy_bio_sector_to_req++;
		blk_queue_bounce(clone->q, &bio_src);
	}

	/*
	 * Recalculate the phy_segments as we allocate new pages
	 * This is used by storage driver to fill the sg list.
	 */
	blk_recalc_rq_segments(clone);

skcipher_req_alloc_failure:
	if (req)
		skcipher_request_free(req);

	if (error == DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC) {
		rq_for_each_segment(bvec, clone, iter1) {
			if (bvec.bv_offset == 0) {
				mempool_free(bvec.bv_page, req_page_pool);
				bvec.bv_page = NULL;
			} else
				bvec.bv_page = NULL;
		}
	}

	mempool_free(req_sg_in, req_scatterlist_pool);
	mempool_free(req_sg_out, req_scatterlist_pool);
submit_request:
	if (io)
		io->error = error;
	req_crypt_dec_pending_encrypt(io);
}

/*
 * This callback is called by the worker queue to perform non-encrypted writes
 * and submit the request using the elevelator.
 */
static void req_cryptd_crypt_write_plain(struct req_dm_crypt_io *io)
{
	struct request *clone = NULL;

	if (!io || !io->cloned_request) {
		DMERR("%s io is invalid\n", __func__);
		WARN_ON(1); /* should not happen */
		return;
	}

	clone = io->cloned_request;
	io->error = 0;
	dm_dispatch_request(clone);
}

/* Queue callback function that will get triggered */
static void req_cryptd_crypt(struct work_struct *work)
{
	struct req_dm_crypt_io *io =
			container_of(work, struct req_dm_crypt_io, work);

	if (rq_data_dir(io->cloned_request) == WRITE) {
		if (io->should_encrypt)
			req_cryptd_crypt_write_convert(io);
		else
			req_cryptd_crypt_write_plain(io);
	} else if (rq_data_dir(io->cloned_request) == READ) {
		if (io->should_decrypt)
			req_cryptd_crypt_read_convert(io);
		else
			req_cryptd_crypt_read_plain(io);
	} else {
		DMERR("%s received non-write request for Clone 0x%p\n",
				__func__, io->cloned_request);
	}
}

static void req_cryptd_split_req_queue_cb(struct work_struct *work)
{
	struct req_dm_split_req_io *io =
			container_of(work, struct req_dm_split_req_io, work);
	struct skcipher_request *req = NULL;
	struct req_crypt_result result;
	int err = 0;
	struct crypto_engine_entry *engine = NULL;

	if ((!io) || (!io->req_split_sg_read) || (!io->engine)) {
		DMERR("%s Input invalid\n",
			 __func__);
		err = DM_REQ_CRYPT_ERROR;
		/* If io is not populated this should not be called */
		WARN_ON(1);
		return;
	}
	req = skcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req) {
		DMERR("%s skcipher request allocation failed\n", __func__);
		err = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}

	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
					req_crypt_cipher_complete, &result);

	engine = io->engine;

	err = (dm_qcrypto_func.cipher_set)(req, engine->ce_device,
			engine->hw_instance);
	if (err) {
		DMERR("%s qcrypto_cipher_set_device_hw failed with err %d\n",
				__func__, err);
		goto skcipher_req_alloc_failure;
	}
	init_completion(&result.completion);
	(dm_qcrypto_func.cipher_flag)(req,
		QCRYPTO_CTX_USE_PIPE_KEY | QCRYPTO_CTX_XTS_DU_SIZE_512B);

	crypto_skcipher_clear_flags(tfm, ~0);
	crypto_skcipher_setkey(tfm, NULL, KEY_SIZE_XTS);

	skcipher_request_set_crypt(req, io->req_split_sg_read,
			io->req_split_sg_read, io->size, (void *) io->IV);

	err = crypto_skcipher_decrypt(req);
	switch (err) {
	case 0:
		break;

	case -EBUSY:
		/*
		 * Lets make this synchronous request by waiting on
		 * in progress as well
		 */
	case -EINPROGRESS:
		wait_for_completion_io(&result.completion);
		if (result.err) {
			DMERR("%s error = %d encrypting the request\n",
				 __func__, result.err);
			err = DM_REQ_CRYPT_ERROR;
			goto skcipher_req_alloc_failure;
		}
		break;

	default:
		err = DM_REQ_CRYPT_ERROR;
		goto skcipher_req_alloc_failure;
	}
	err = 0;
skcipher_req_alloc_failure:
	if (req)
		skcipher_request_free(req);

	req_crypt_split_io_complete(&io->result, err);
}

static void req_cryptd_split_req_queue(struct req_dm_split_req_io *io)
{
	INIT_WORK(&io->work, req_cryptd_split_req_queue_cb);
	queue_work(req_crypt_split_io_queue, &io->work);
}

static void req_cryptd_queue_crypt(struct req_dm_crypt_io *io)
{
	INIT_WORK(&io->work, req_cryptd_crypt);
	queue_work(req_crypt_queue, &io->work);
}

/*
 * Cipher complete callback, this is triggered by the Linux crypto api once
 * the operation is done. This signals the waiting thread that the crypto
 * operation is complete.
 */
static void req_crypt_cipher_complete(struct crypto_async_request *req, int err)
{
	struct req_crypt_result *res = req->data;

	if (err == -EINPROGRESS)
		return;

	res->err = err;
	complete(&res->completion);
}

static void req_crypt_split_io_complete(struct req_crypt_result *res, int err)
{
	if (err == -EINPROGRESS)
		return;

	res->err = err;
	complete(&res->completion);
}
/*
 * If bio->bi_dev is a partition, remap the location
 */
static inline void req_crypt_blk_partition_remap(struct bio *bio)
{
	struct block_device *bdev = bio->bi_bdev;

	if (bio_sectors(bio) && bdev != bdev->bd_contains) {
		struct hd_struct *p = bdev->bd_part;
		/*
		 * Check for integer overflow, should never happen.
		 */
		if (p->start_sect > (UINT_MAX - bio->bi_iter.bi_sector))
			WARN_ON(1);

		bio->bi_iter.bi_sector += p->start_sect;
		bio->bi_bdev = bdev->bd_contains;
	}
}

/*
 * The endio function is called from ksoftirqd context (atomic).
 * For write operations the new pages created form the mempool
 * is freed and returned.  * For read operations, decryption is
 * required, since this is called in a atomic  * context, the
 * request is sent to a worker queue to complete decryptiona and
 * free the request once done.
 */
static int req_crypt_endio(struct dm_target *ti, struct request *clone,
			    int error, union map_info *map_context)
{
	int err = 0;
	struct req_iterator iter1;
	struct bio_vec bvec;
	struct req_dm_crypt_io *req_io = map_context->ptr;

	/* If it is for ICE, free up req_io and return */
	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT) {
		mempool_free(req_io, req_io_pool);
		err = error;
		goto submit_request;
	}

	if (rq_data_dir(clone) == WRITE) {
		rq_for_each_segment(bvec, clone, iter1) {
			if (req_io->should_encrypt && bvec.bv_offset == 0) {
				mempool_free(bvec.bv_page, req_page_pool);
				bvec.bv_page = NULL;
			} else
				bvec.bv_page = NULL;
		}
		mempool_free(req_io, req_io_pool);
		goto submit_request;
	} else if (rq_data_dir(clone) == READ) {
		req_io->error = error;
		req_cryptd_queue_crypt(req_io);
		err = DM_ENDIO_INCOMPLETE;
		goto submit_request;
	}

submit_request:
	return err;
}

/*
 * This function is called with interrupts disabled
 * The function remaps the clone for the underlying device.
 * If it is a write request, it calls into the worker queue to
 * encrypt the data
 * and submit the request directly using the elevator
 * For a read request no pre-processing is required the request
 * is returned to dm once mapping is done
 */
static int req_crypt_map(struct dm_target *ti, struct request *clone,
			 union map_info *map_context)
{
	struct req_dm_crypt_io *req_io = NULL;
	int error = DM_REQ_CRYPT_ERROR, copy_bio_sector_to_req = 0;
	struct bio *bio_src = NULL;
	gfp_t gfp_flag = GFP_KERNEL;

	if (in_interrupt() || irqs_disabled())
		gfp_flag = GFP_NOWAIT;

	req_io = mempool_alloc(req_io_pool, gfp_flag);
	if (!req_io) {
		WARN_ON(1);
		error = DM_REQ_CRYPT_ERROR;
		goto submit_request;
	}

	/* Save the clone in the req_io, the callback to the worker
	 * queue will get the req_io
	 */
	req_io->cloned_request = clone;
	map_context->ptr = req_io;
	atomic_set(&req_io->pending, 0);

	if (rq_data_dir(clone) == WRITE)
		req_io->should_encrypt = req_crypt_should_encrypt(req_io);
	if (rq_data_dir(clone) == READ)
		req_io->should_decrypt = req_crypt_should_deccrypt(req_io);

	/* Get the queue of the underlying original device */
	clone->q = bdev_get_queue(dev->bdev);
	clone->rq_disk = dev->bdev->bd_disk;

	__rq_for_each_bio(bio_src, clone) {
		bio_src->bi_bdev = dev->bdev;
		/* Currently the way req-dm works is that once the underlying
		 * device driver completes the request by calling into the
		 * block layer. The block layer completes the bios (clones) and
		 * then the cloned request. This is undesirable for req-dm-crypt
		 * hence added a flag BIO_DONTFREE, this flag will ensure that
		 * blk layer does not complete the cloned bios before completing
		 * the request. When the crypt endio is called, post-processing
		 * is done and then the dm layer will complete the bios (clones)
		 * and free them.
		 */
		if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT)
			bio_src->bi_flags |= 1 << BIO_INLINECRYPT;
		else
			bio_src->bi_flags |= 1 << BIO_DONTFREE;

		/*
		 * If this device has partitions, remap block n
		 * of partition p to block n+start(p) of the disk.
		 */
		req_crypt_blk_partition_remap(bio_src);
		if (copy_bio_sector_to_req == 0) {
			clone->__sector = bio_src->bi_iter.bi_sector;
			copy_bio_sector_to_req++;
		}
		blk_queue_bounce(clone->q, &bio_src);
	}

	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT) {
		/* Set all crypto parameters for inline crypto engine */
		memcpy(&req_io->ice_settings, ice_settings,
					sizeof(struct ice_crypto_setting));
	} else {
		/* ICE checks for key_index which could be >= 0. If a chip has
		 * both ICE and GPCE and wanted to use GPCE, there could be
		 * issue. Storage driver send all requests to ICE driver. If
		 * it sees key_index as 0, it would assume it is for ICE while
		 * it is not. Hence set invalid key index by default.
		 */
		req_io->ice_settings.key_index = -1;

	}

	if (rq_data_dir(clone) == READ ||
		encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT) {
		error = DM_MAPIO_REMAPPED;
		goto submit_request;
	} else if (rq_data_dir(clone) == WRITE) {
		req_cryptd_queue_crypt(req_io);
		error = DM_MAPIO_SUBMITTED;
		goto submit_request;
	}

submit_request:
	return error;

}

static void deconfigure_qcrypto(void)
{
	mempool_destroy(req_page_pool);
	req_page_pool = NULL;

	mempool_destroy(req_scatterlist_pool);
	req_scatterlist_pool = NULL;

	if (req_crypt_split_io_queue) {
		destroy_workqueue(req_crypt_split_io_queue);
		req_crypt_split_io_queue = NULL;
	}
	if (req_crypt_queue) {
		destroy_workqueue(req_crypt_queue);
		req_crypt_queue = NULL;
	}

	kmem_cache_destroy(_req_dm_scatterlist_pool);

	mutex_lock(&engine_list_mutex);
	kfree(pfe_eng);
	pfe_eng = NULL;
	kfree(fde_eng);
	fde_eng = NULL;
	mutex_unlock(&engine_list_mutex);

	if (tfm) {
		crypto_free_skcipher(tfm);
		tfm = NULL;
	}
}

static void req_crypt_dtr(struct dm_target *ti)
{
	DMDEBUG("dm-req-crypt Destructor.\n");

	mempool_destroy(req_io_pool);
	req_io_pool = NULL;

	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT) {
		kfree(ice_settings);
		ice_settings = NULL;
	} else {
		deconfigure_qcrypto();
	}

	kmem_cache_destroy(_req_crypt_io_pool);

	if (dev) {
		dm_put_device(ti, dev);
		dev = NULL;
	}
}

static int configure_qcrypto(void)
{
	struct crypto_engine_entry *eng_list = NULL;
	struct block_device *bdev = NULL;
	int err = DM_REQ_CRYPT_ERROR, i;
	struct request_queue *q = NULL;

	bdev = dev->bdev;
	q = bdev_get_queue(bdev);
	blk_queue_max_hw_sectors(q, DM_REQ_CRYPT_QUEUE_SIZE);

	/* Allocate the crypto alloc blk cipher and keep the handle */
	tfm = crypto_alloc_skcipher("qcom-xts(aes)", 0, 0);
	if (IS_ERR(tfm)) {
		DMERR("%s skcipher tfm allocation failed : error\n",
						 __func__);
		tfm = NULL;
		goto exit_err;
	}

	num_engines_fde = num_engines_pfe = 0;

	mutex_lock(&engine_list_mutex);
	num_engines = (dm_qcrypto_func.get_num_engines)();
	if (!num_engines) {
		DMERR(KERN_INFO "%s qcrypto_get_num_engines failed\n",
					__func__);
		err = DM_REQ_CRYPT_ERROR;
		mutex_unlock(&engine_list_mutex);
		goto exit_err;
	}

	eng_list = kcalloc(num_engines, sizeof(*eng_list), GFP_KERNEL);
	if (eng_list == NULL) {
		DMERR("%s engine list allocation failed\n", __func__);
		err = DM_REQ_CRYPT_ERROR;
		mutex_unlock(&engine_list_mutex);
		goto exit_err;
	}

	(dm_qcrypto_func.get_engine_list)(num_engines, eng_list);

	for (i = 0; i < num_engines; i++) {
		if (eng_list[i].ce_device == FDE_KEY_ID)
			num_engines_fde++;
		if (eng_list[i].ce_device == PFE_KEY_ID)
			num_engines_pfe++;
	}

	fde_eng = kcalloc(num_engines_fde, sizeof(*fde_eng), GFP_KERNEL);
	if (fde_eng == NULL) {
		DMERR("%s fde engine list allocation failed\n", __func__);
		mutex_unlock(&engine_list_mutex);
		goto exit_err;
	}

	pfe_eng = kcalloc(num_engines_pfe, sizeof(*pfe_eng), GFP_KERNEL);
	if (pfe_eng == NULL) {
		DMERR("%s pfe engine list allocation failed\n", __func__);
		mutex_unlock(&engine_list_mutex);
		goto exit_err;
	}

	fde_cursor = 0;
	pfe_cursor = 0;

	for (i = 0; i < num_engines; i++) {
		if (eng_list[i].ce_device == FDE_KEY_ID)
			fde_eng[fde_cursor++] = eng_list[i];
		if (eng_list[i].ce_device == PFE_KEY_ID)
			pfe_eng[pfe_cursor++] = eng_list[i];
	}

	fde_cursor = 0;
	pfe_cursor = 0;
	mutex_unlock(&engine_list_mutex);

	_req_dm_scatterlist_pool = kmem_cache_create("req_dm_scatterlist",
				sizeof(struct scatterlist) * MAX_SG_LIST,
				 __alignof__(struct scatterlist), 0, NULL);
	if (!_req_dm_scatterlist_pool)
		goto exit_err;

	req_crypt_queue = alloc_workqueue("req_cryptd",
					WQ_UNBOUND |
					WQ_CPU_INTENSIVE |
					WQ_MEM_RECLAIM,
					0);
	if (!req_crypt_queue) {
		DMERR("%s req_crypt_queue not allocated\n", __func__);
		goto exit_err;
	}

	req_crypt_split_io_queue = alloc_workqueue("req_crypt_split",
					WQ_UNBOUND |
					WQ_CPU_INTENSIVE |
					WQ_MEM_RECLAIM,
					0);
	if (!req_crypt_split_io_queue) {
		DMERR("%s req_crypt_split_io_queue not allocated\n", __func__);
		goto exit_err;
	}
	req_scatterlist_pool = mempool_create_slab_pool(MIN_IOS,
					_req_dm_scatterlist_pool);
	if (!req_scatterlist_pool) {
		DMERR("%s req_scatterlist_pool is not allocated\n", __func__);
		err = -ENOMEM;
		goto exit_err;
	}

	req_page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
	if (!req_page_pool) {
		DMERR("%s req_page_pool not allocated\n", __func__);
		goto exit_err;
	}

	err = 0;

exit_err:
	kfree(eng_list);
	return err;
}

/*
 * Construct an encryption mapping:
 * <cipher> <key> <iv_offset> <dev_path> <start>
 */
static int req_crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
	int err = DM_REQ_CRYPT_ERROR;
	unsigned long long tmpll;
	char dummy;
	int ret;

	DMDEBUG("dm-req-crypt Constructor.\n");

	if (argc < 5) {
		DMERR(" %s Not enough args\n", __func__);
		err = DM_REQ_CRYPT_ERROR;
		goto ctr_exit;
	}

	if (argv[3]) {
		if (dm_get_device(ti, argv[3],
				dm_table_get_mode(ti->table), &dev)) {
			DMERR(" %s Device Lookup failed\n", __func__);
			err =  DM_REQ_CRYPT_ERROR;
			goto ctr_exit;
		}
	} else {
		DMERR(" %s Arg[3] invalid\n", __func__);
		err =  DM_REQ_CRYPT_ERROR;
		goto ctr_exit;
	}

	if (argv[4]) {
		if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
			DMERR("%s Invalid device sector\n", __func__);
			err =  DM_REQ_CRYPT_ERROR;
			goto ctr_exit;
		}
	} else {
		DMERR(" %s Arg[4] invalid\n", __func__);
		err =  DM_REQ_CRYPT_ERROR;
		goto ctr_exit;
	}
	start_sector_orig = tmpll;

	/* Allow backward compatible */
	if (argc >= 6) {
		if (argv[5]) {
			if (!strcmp(argv[5], "fde_enabled"))
				is_fde_enabled = true;
			else
				is_fde_enabled = false;
		} else {
			DMERR(" %s Arg[5] invalid\n", __func__);
			err =  DM_REQ_CRYPT_ERROR;
			goto ctr_exit;
		}
	} else {
		DMERR(" %s Arg[5] missing, set FDE enabled.\n", __func__);
		is_fde_enabled = true; /* backward compatible */
	}

	_req_crypt_io_pool = KMEM_CACHE(req_dm_crypt_io, 0);
	if (!_req_crypt_io_pool) {
		err =  DM_REQ_CRYPT_ERROR;
		goto ctr_exit;
	}

	encryption_mode = DM_REQ_CRYPT_ENCRYPTION_MODE_CRYPTO;
	if (argc >= 7 && argv[6]) {
		if (!strcmp(argv[6], "ice"))
			encryption_mode =
				DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT;
	}

	if (encryption_mode == DM_REQ_CRYPT_ENCRYPTION_MODE_TRANSPARENT) {
		/* configure ICE settings */
		ice_settings =
			kzalloc(sizeof(struct ice_crypto_setting), GFP_KERNEL);
		if (!ice_settings) {
			err = -ENOMEM;
			goto ctr_exit;
		}
		ice_settings->key_size = ICE_CRYPTO_KEY_SIZE_128;
		ice_settings->algo_mode = ICE_CRYPTO_ALGO_MODE_AES_XTS;
		ice_settings->key_mode = ICE_CRYPTO_USE_LUT_SW_KEY;
		if (kstrtou16(argv[1], 0, &ice_settings->key_index) ||
			ice_settings->key_index < 0 ||
			ice_settings->key_index > MAX_MSM_ICE_KEY_LUT_SIZE) {
			DMERR("%s Err: key index %d received for ICE\n",
				__func__, ice_settings->key_index);
			err = DM_REQ_CRYPT_ERROR;
			goto ctr_exit;
		}
	} else {
		ret = configure_qcrypto();
		if (ret) {
			DMERR("%s failed to configure qcrypto\n", __func__);
			err = ret;
			goto ctr_exit;
		}
	}

	req_io_pool = mempool_create_slab_pool(MIN_IOS, _req_crypt_io_pool);
	if (!req_io_pool) {
		DMERR("%s req_io_pool not allocated\n", __func__);
		err = -ENOMEM;
		goto ctr_exit;
	}

	/*
	 * If underlying device supports flush/discard, mapped target
	 * should also allow it
	 */
	ti->num_flush_bios = 1;
	ti->num_discard_bios = 1;

	err = 0;
	DMINFO("%s: Mapping block_device %s to dm-req-crypt ok!\n",
	       __func__, argv[3]);
ctr_exit:
	if (err)
		req_crypt_dtr(ti);

	return err;
}

static int req_crypt_iterate_devices(struct dm_target *ti,
				 iterate_devices_callout_fn fn, void *data)
{
	return fn(ti, dev, start_sector_orig, ti->len, data);
}
void set_qcrypto_func_dm(void *dev,
			void *flag,
			void *engines,
			void *engine_list)
{
	dm_qcrypto_func.cipher_set  = dev;
	dm_qcrypto_func.cipher_flag = flag;
	dm_qcrypto_func.get_num_engines = engines;
	dm_qcrypto_func.get_engine_list = engine_list;
}
EXPORT_SYMBOL(set_qcrypto_func_dm);

static struct target_type req_crypt_target = {
	.name   = "req-crypt",
	.version = {1, 0, 0},
	.module = THIS_MODULE,
	.ctr    = req_crypt_ctr,
	.dtr    = req_crypt_dtr,
	.map_rq = req_crypt_map,
	.rq_end_io = req_crypt_endio,
	.iterate_devices = req_crypt_iterate_devices,
};

static int __init req_dm_crypt_init(void)
{
	int r;


	r = dm_register_target(&req_crypt_target);
	if (r < 0) {
		DMERR("register failed %d", r);
		return r;
	}

	DMINFO("dm-req-crypt successfully initalized.\n");

	return r;
}

static void __exit req_dm_crypt_exit(void)
{
	dm_unregister_target(&req_crypt_target);
}

module_init(req_dm_crypt_init);
module_exit(req_dm_crypt_exit);

MODULE_DESCRIPTION(DM_NAME " target for request based transparent encryption / decryption");
MODULE_LICENSE("GPL v2");
