|
@@ -1688,6 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|
|
unsigned int key_size, opt_params;
|
|
|
unsigned long long tmpll;
|
|
|
int ret;
|
|
|
+ size_t iv_size_padding;
|
|
|
struct dm_arg_set as;
|
|
|
const char *opt_string;
|
|
|
char dummy;
|
|
@@ -1724,20 +1725,32 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|
|
|
|
|
cc->dmreq_start = sizeof(struct ablkcipher_request);
|
|
|
cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc));
|
|
|
- cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment());
|
|
|
- cc->dmreq_start += crypto_ablkcipher_alignmask(any_tfm(cc)) &
|
|
|
- ~(crypto_tfm_ctx_alignment() - 1);
|
|
|
+ cc->dmreq_start = ALIGN(cc->dmreq_start, __alignof__(struct dm_crypt_request));
|
|
|
+
|
|
|
+ if (crypto_ablkcipher_alignmask(any_tfm(cc)) < CRYPTO_MINALIGN) {
|
|
|
+ /* Allocate the padding exactly */
|
|
|
+ iv_size_padding = -(cc->dmreq_start + sizeof(struct dm_crypt_request))
|
|
|
+ & crypto_ablkcipher_alignmask(any_tfm(cc));
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * If the cipher requires greater alignment than kmalloc
|
|
|
+ * alignment, we don't know the exact position of the
|
|
|
+ * initialization vector. We must assume worst case.
|
|
|
+ */
|
|
|
+ iv_size_padding = crypto_ablkcipher_alignmask(any_tfm(cc));
|
|
|
+ }
|
|
|
|
|
|
cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start +
|
|
|
- sizeof(struct dm_crypt_request) + cc->iv_size);
|
|
|
+ sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size);
|
|
|
if (!cc->req_pool) {
|
|
|
ti->error = "Cannot allocate crypt request mempool";
|
|
|
goto bad;
|
|
|
}
|
|
|
|
|
|
cc->per_bio_data_size = ti->per_bio_data_size =
|
|
|
- sizeof(struct dm_crypt_io) + cc->dmreq_start +
|
|
|
- sizeof(struct dm_crypt_request) + cc->iv_size;
|
|
|
+ ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start +
|
|
|
+ sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size,
|
|
|
+ ARCH_KMALLOC_MINALIGN);
|
|
|
|
|
|
cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
|
|
|
if (!cc->page_pool) {
|