mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 03:43:03 +00:00
md: Adding support of ICE in dm-req-crypt
Storage hardware can have embedded crypto engine which can greatly reduce degradation in IO performance if crypto operations are performed on data. Added support in dm-req-crypt so that it can work either in transparent mode or crypto mode. In transparent mode, dm-req-crypt will not perform any crypto operation by itself. In crypto mode, dm-req-crypt will perform crypto operation on data using a seperate crypto engine (SW based CE or HW based CE). Change-Id: I8f27840899566c1a608ca13ce6b7480c9866fb6a Signed-off-by: Dinesh K Garg <dineshg@codeaurora.org>
This commit is contained in:
parent
56cab451fc
commit
f281aa1822
|
@ -35,6 +35,7 @@
|
|||
#include <crypto/hash.h>
|
||||
#include <crypto/md5.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/ice.h>
|
||||
|
||||
#define DM_MSG_PREFIX "req-crypt"
|
||||
|
||||
|
@ -45,10 +46,24 @@
|
|||
#define MIN_POOL_PAGES 32
|
||||
#define KEY_SIZE_XTS 64
|
||||
#define AES_XTS_IV_LEN 16
|
||||
#define MAX_MSM_ICE_KEY_LUT_SIZE 32
|
||||
|
||||
#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
|
||||
|
||||
struct req_crypt_result {
|
||||
struct completion completion;
|
||||
int err;
|
||||
|
@ -65,6 +80,8 @@ static mempool_t *req_io_pool;
|
|||
static mempool_t *req_page_pool;
|
||||
static bool is_fde_enabled;
|
||||
static struct crypto_ablkcipher *tfm;
|
||||
static unsigned int encryption_mode;
|
||||
static struct ice_crypto_setting *ice_settings;
|
||||
|
||||
unsigned int num_engines;
|
||||
unsigned int num_engines_fde, fde_cursor;
|
||||
|
@ -73,6 +90,7 @@ 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;
|
||||
|
@ -99,6 +117,8 @@ static bool req_crypt_should_encrypt(struct req_dm_crypt_io *req)
|
|||
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;
|
||||
|
||||
ret = pft_get_key_index(bio, &key_id, &is_encrypted, &is_inplace);
|
||||
|
@ -125,6 +145,8 @@ static bool req_crypt_should_deccrypt(struct req_dm_crypt_io *req)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -831,6 +853,21 @@ static int req_crypt_map(struct dm_target *ti, struct request *clone,
|
|||
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) {
|
||||
error = DM_MAPIO_REMAPPED;
|
||||
goto submit_request;
|
||||
|
@ -857,6 +894,9 @@ static void req_crypt_dtr(struct dm_target *ti)
|
|||
mempool_destroy(req_io_pool);
|
||||
req_io_pool = NULL;
|
||||
}
|
||||
kfree(ice_settings);
|
||||
ice_settings = NULL;
|
||||
|
||||
mutex_lock(&engine_list_mutex);
|
||||
kfree(pfe_eng);
|
||||
pfe_eng = NULL;
|
||||
|
@ -949,6 +989,34 @@ static int req_crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
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;
|
||||
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_256;
|
||||
ice_settings->algo_mode = ICE_CRYPTO_ALGO_MODE_AES_XTS;
|
||||
ice_settings->key_mode = ICE_CRYPTO_USE_LUT_SW_KEY;
|
||||
if (sscanf(argv[1], "%hu",
|
||||
&ice_settings->key_index) != 1 ||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req_crypt_queue = alloc_workqueue("req_cryptd",
|
||||
WQ_UNBOUND |
|
||||
WQ_CPU_INTENSIVE |
|
||||
|
|
Loading…
Reference in a new issue