dm crypt: Allow unaligned buffer lengths for skcipher devices
Subsystems (3)
cover dm crypt: Allow unaligned buffer lengths for skcipher devices
Hi,
This changeset allows processing of unaligned bio requests in dm crypt for the I/Os generated from a windows guest OS in a QEMU environment. If this changeset is accepted, then I will be submitting another changeset that addresses the similar issue in AEAD disks and dm-integrity module.
Thanks
Sudhakar
Sudhakar Panneerselvam (2):
dm crypt: Allow unaligned bio buffer lengths for skcipher devices dm crypt: Handle unaligned bio buffer lengths for lmk and tcw
drivers/md/dm-crypt.c | 154 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 46 deletions(-)
Signature · 1 line
1.8.3.1
RFC PATCH 1/2 dm crypt: Allow unaligned bio buffer lengths for skcipher devices
crypt_convert_block_skcipher() rejects the I/O if the buffer length is not a multiple of its sector size. This assumption holds true as long as the originator of the I/Os are within Linux. But, in a QEMU environment, with windows as guests that uses vhost-scsi interface, it was observed that block layer could receive bio requests whose individual buffer lengths may not be aligned at the sector size all the time. This results in windows guest failing to boot or failing to format the block devices that are backed by dm-crypt.
Not all low level block drivers require that the dma alignment to be a multiple of 512 bytes. Some of the LLDs that has much relaxed constraint on the buffer alignment are iSCSI, NVMe, SBP, MegaRaid, qla2xxx. Hence, assuming the buffer lengths to be aligned to its sector size and based on that rejecting the I/Os doesn't appear to be correct.
crypt_map() already ensures that the I/Os are always a multiple of its sector size, hence, by the time the I/O reaches crypt_convert_block_skcipher() and finds the data associated with the sector is not fully in the same bio vector means that it could just be that the sector data is scattered across two bio vectors. Hence, this patch removes the buffer length check and adds the code that prepares the sg list appropriately in case sector data is split between two bio vectors.
With this change, windows was successfully be able to boot from a block device that is backed by dm-crypt device in a QEMU environment.
--- drivers/md/dm-crypt.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-)
drivers/md/dm-crypt.c +40 -10
@@ -1275,6 +1275,23 @@ static void *iv_tag_from_dmreq(struct crypt_config *cc,return tag_from_dmreq (cc, dmreq) + cc->integrity_tag_size; } +static int build_split_sg (struct scatterlist *sg,struct bio_vec *bvec, +struct bio *bio,struct bvec_iter *iter, +unsigned short int sector_size) +{ +int bytes_first_page; + + bytes_first_page = bvec->bv_len; +sg_set_page (sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset); +bio_advance_iter (bio, iter, bvec->bv_len); + *bvec =bio_iter_iovec (bio, *iter); + sg++; +sg_set_page (sg, bvec->bv_page, sector_size - bytes_first_page, + bvec->bv_offset); + +return bytes_first_page; +} + static int crypt_convert_block_aead(struct crypt_config *cc, struct convert_context *ctx, struct aead_request *req,
@@ -1379,15 +1396,12 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc,struct bio_vec bv_in =bio_iter_iovec (ctx->bio_in, ctx->iter_in);struct bio_vec bv_out =bio_iter_iovec (ctx->bio_out, ctx->iter_out);struct scatterlist *sg_in, *sg_out; +int src_split =0 , dst_split =0 ;struct dm_crypt_request *dmreq;u8 *iv, *org_iv, *tag_iv;__le64 *sector;int r =0 ; -/* Reject unexpected unaligned bio. */ -if (unlikely (bv_in.bv_len & (cc->sector_size -1 ))) -return -EIO ; - dmreq =dmreq_of_req (cc, req); dmreq->iv_sector = ctx->cc_sector;if (test_bit (CRYPT_IV_LARGE_SECTORS , &cc->cipher_flags))
@@ -1407,11 +1421,25 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc, sg_in = &dmreq->sg_in[0 ]; sg_out = &dmreq->sg_out[0 ]; -sg_init_table (sg_in,1 ); -sg_set_page (sg_in, bv_in.bv_page, cc->sector_size, bv_in.bv_offset); +if (unlikely (bv_in.bv_len < cc->sector_size)) { +sg_init_table (sg_in,2 ); + src_split =build_split_sg (sg_in, &bv_in, ctx->bio_in, + &ctx->iter_in, cc->sector_size); + }else { +sg_init_table (sg_in,1 ); +sg_set_page (sg_in, bv_in.bv_page, cc->sector_size, + bv_in.bv_offset); + } -sg_init_table (sg_out,1 ); -sg_set_page (sg_out, bv_out.bv_page, cc->sector_size, bv_out.bv_offset); +if (unlikely (bv_out.bv_len < cc->sector_size)) { +sg_init_table (sg_out,2 ); + dst_split =build_split_sg (sg_out, &bv_out, ctx->bio_out, + &ctx->iter_out, cc->sector_size); + }else { +sg_init_table (sg_out,1 ); +sg_set_page (sg_out, bv_out.bv_page, cc->sector_size, + bv_out.bv_offset); + }if (cc->iv_gen_ops) {/* For READs use IV stored in integrity metadata */
@@ -1442,8 +1470,10 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc,if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) r = cc->iv_gen_ops->post (cc, org_iv, dmreq); -bio_advance_iter (ctx->bio_in, &ctx->iter_in, cc->sector_size); -bio_advance_iter (ctx->bio_out, &ctx->iter_out, cc->sector_size); +bio_advance_iter (ctx->bio_in, &ctx->iter_in, + cc->sector_size - src_split); +bio_advance_iter (ctx->bio_out, &ctx->iter_out, + cc->sector_size - dst_split);return r; }
Signature · 1 line
1.8.3.1
RFC PATCH 2/2 dm crypt: Handle unaligned bio buffer lengths for lmk and tcw
In reply to Sudhakar PanneerselvamUs sg_miter_* apis to process unaligned buffer lengths while handling bio buffers for lmk and tcw IV generation algorithms.
--- drivers/md/dm-crypt.c | 104 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 36 deletions(-)
drivers/md/dm-crypt.c +68 -36
@@ -471,11 +471,13 @@ static int crypt_iv_lmk_wipe(struct crypt_config *cc)static int crypt_iv_lmk_one (struct crypt_config *cc,u8 *iv,struct dm_crypt_request *dmreq, -u8 *data) +struct scatterlist *sg) {struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;SHASH_DESC_ON_STACK (desc, lmk->hash_tfm); +struct sg_mapping_iter miter;struct md5_state md5state; +size_t len =16 *31 ;__le32 buf[4 ];int i, r;
@@ -492,7 +494,19 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, }/* Sector is always 512B, block size 16, add data of blocks 1-31 */ - r =crypto_shash_update (desc, data +16 ,16 *31 ); +sg_miter_start (&miter, sg,sg_nents (sg), +SG_MITER_ATOMIC |SG_MITER_FROM_SG ); +sg_miter_skip (&miter,16 ); +while (sg_miter_next (&miter) && len >0 ) { +size_t hash_len =min_t (size_t, miter.length, len); + + r =crypto_shash_update (desc, miter.addr, hash_len); +if (r) +break ; + len -= hash_len; + } +sg_miter_stop (&miter); +if (r)return r;
@@ -520,15 +534,11 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,static int crypt_iv_lmk_gen (struct crypt_config *cc,u8 *iv,struct dm_crypt_request *dmreq) { -struct scatterlist *sg; -u8 *src;int r =0 ;if (bio_data_dir (dmreq->ctx->bio_in) ==WRITE ) { - sg =crypt_get_sg_data (cc, dmreq->sg_in); - src =kmap_atomic (sg_page (sg)); - r =crypt_iv_lmk_one (cc, iv, dmreq, src + sg->offset); -kunmap_atomic (src); + r =crypt_iv_lmk_one (cc, iv, dmreq, +crypt_get_sg_data (cc, dmreq->sg_in)); }else memset (iv,0 , cc->iv_size);
@@ -538,22 +548,32 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv,static int crypt_iv_lmk_post (struct crypt_config *cc,u8 *iv,struct dm_crypt_request *dmreq) { +struct sg_mapping_iter miter;struct scatterlist *sg; -u8 *dst; -int r; +int r, offset =0 ; +size_t len;if (bio_data_dir (dmreq->ctx->bio_in) ==WRITE )return 0 ; sg =crypt_get_sg_data (cc, dmreq->sg_out); - dst =kmap_atomic (sg_page (sg)); - r =crypt_iv_lmk_one (cc, iv, dmreq, dst + sg->offset); + r =crypt_iv_lmk_one (cc, iv, dmreq, sg); +if (r) +return r;/* Tweak the first block of plaintext sector */ -if (!r) -crypto_xor (dst + sg->offset, iv, cc->iv_size); + len = cc->iv_size; +sg_miter_start (&miter, sg,sg_nents (sg), +SG_MITER_ATOMIC |SG_MITER_TO_SG ); +while (sg_miter_next (&miter) && len >0 ) { +size_t xor_len =min_t (size_t, miter.length, len); + +crypto_xor (miter.addr, iv + offset, xor_len); + len -= xor_len; + offset += xor_len; + } +sg_miter_stop (&miter); -kunmap_atomic (dst);return r; }
@@ -627,12 +647,14 @@ static int crypt_iv_tcw_wipe(struct crypt_config *cc)static int crypt_iv_tcw_whitening (struct crypt_config *cc,struct dm_crypt_request *dmreq, -u8 *data) +struct scatterlist *sg) {struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;__le64 sector =cpu_to_le64 (dmreq->iv_sector); +struct sg_mapping_iter miter;u8 buf[TCW_WHITENING_SIZE ];SHASH_DESC_ON_STACK (desc, tcw->crc32_tfm); +size_t remain, sgoffset =0 ;int i, r;/* xor whitening with sector number */
@@ -656,8 +678,31 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,crypto_xor (&buf[4 ], &buf[8 ],4 );/* apply whitening (8 bytes) to whole sector */ -for (i =0 ; i < ((1 <<SECTOR_SHIFT ) /8 ); i++) -crypto_xor (data + i *8 , buf,8 ); +sg_miter_start (&miter, sg,sg_nents (sg), +SG_MITER_ATOMIC |SG_MITER_TO_SG ); +sg_miter_next (&miter); + remain = miter.length; +for (i =0 ; i < ((1 <<SECTOR_SHIFT ) /8 ); i++) { +size_t len =8 , offset =0 ; + +while (len >0 ) { +size_t xor_len =min_t (size_t, remain, len); + +crypto_xor (miter.addr + sgoffset, buf + offset, + xor_len); + len -= xor_len; + remain -= xor_len; + offset += xor_len; + sgoffset += xor_len; +if (remain ==0 ) { +sg_miter_next (&miter); + sgoffset =0 ; + remain = miter.length; + } + } + } +sg_miter_stop (&miter); + out:memzero_explicit (buf,sizeof (buf));return r;
@@ -666,19 +711,14 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,static int crypt_iv_tcw_gen (struct crypt_config *cc,u8 *iv,struct dm_crypt_request *dmreq) { -struct scatterlist *sg;struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;__le64 sector =cpu_to_le64 (dmreq->iv_sector); -u8 *src;int r =0 ;/* Remove whitening from ciphertext */ -if (bio_data_dir (dmreq->ctx->bio_in) !=WRITE ) { - sg =crypt_get_sg_data (cc, dmreq->sg_in); - src =kmap_atomic (sg_page (sg)); - r =crypt_iv_tcw_whitening (cc, dmreq, src + sg->offset); -kunmap_atomic (src); - } +if (bio_data_dir (dmreq->ctx->bio_in) !=WRITE ) + r =crypt_iv_tcw_whitening (cc, dmreq, +crypt_get_sg_data (cc, dmreq->sg_in));/* Calculate IV */ crypto_xor_cpy (iv, tcw->iv_seed, (u8 *)§or,8 );
@@ -692,20 +732,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,static int crypt_iv_tcw_post (struct crypt_config *cc,u8 *iv,struct dm_crypt_request *dmreq) { -struct scatterlist *sg; -u8 *dst; -int r; -if (bio_data_dir (dmreq->ctx->bio_in) !=WRITE )return 0 ;/* Apply whitening on ciphertext */ - sg =crypt_get_sg_data (cc, dmreq->sg_out); - dst =kmap_atomic (sg_page (sg)); - r =crypt_iv_tcw_whitening (cc, dmreq, dst + sg->offset); -kunmap_atomic (dst); - -return r; +return crypt_iv_tcw_whitening (cc, dmreq, +crypt_get_sg_data (cc, dmreq->sg_out)); } static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,
Signature · 1 line
1.8.3.1
Could someone review this patch set, please?
Thanks
Sudhakar
Quoted 35 lines
-----Original Message-----
From: Sudhakar Panneerselvam
Sent: Wednesday, September 16, 2020 12:40 PM
To: [email protected]; [email protected]; [email protected]
Cc: Shirley Ma <[email protected]>; [email protected]; Martin Petersen <[email protected]>
Subject: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesHi,
This changeset allows processing of unaligned bio requests in dm crypt for the I/Os generated from a windows guest OS in a QEMU environment. If this changeset is accepted, then I will be submitting another changeset that addresses the similar issue in AEAD disks and dm-integrity module.
Thanks
SudhakarSudhakar Panneerselvam (2):
dm crypt: Allow unaligned bio buffer lengths for skcipher devices dm crypt: Handle unaligned bio buffer lengths for lmk and tcwdrivers/md/dm-crypt.c | 154 +++++++++++++++++++++++++++++++++++---- ----------- 1 file changed, 108 insertions(+), 46 deletions(-)--
1.8.3.1--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Thanks,
Mike
Quoted 41 lines · Sudhakar Panneerselvam
Could someone review this patch set, please?
Thanks
SudhakarQuoted 35 lines
-----Original Message-----
From: Sudhakar Panneerselvam
Sent: Wednesday, September 16, 2020 12:40 PM
To: [email protected]; [email protected]; [email protected]
Cc: Shirley Ma <[email protected]>; [email protected]; Martin Petersen <[email protected]>
Subject: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesHi,
This changeset allows processing of unaligned bio requests in dm crypt for the I/Os generated from a windows guest OS in a QEMU environment. If this changeset is accepted, then I will be submitting another changeset that addresses the similar issue in AEAD disks and dm-integrity module.
Thanks
SudhakarSudhakar Panneerselvam (2):
dm crypt: Allow unaligned bio buffer lengths for skcipher devices dm crypt: Handle unaligned bio buffer lengths for lmk and tcwdrivers/md/dm-crypt.c | 154 +++++++++++++++++++++++++++++++++++---- ----------- 1 file changed, 108 insertions(+), 46 deletions(-)--
1.8.3.1--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
Quoted 9 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
Quoted 6 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
I don't understand why this is needed, since dm-crypt already sets its logical_block_size to its crypto sector_size. Isn't it expected that I/O that isn't aligned to logical_block_size fails? It's the I/O submitter's responsibility to ensure logical_block_size alignment of all I/O segments. Exactly how is the misaligned I/O actually being submitted here?
- Eric
Quoted 17 lines · Eric Biggers
Quoted 9 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
Quoted 6 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Quoted 5 lines
I don't understand why this is needed, since dm-crypt already sets its
logical_block_sizeto its cryptosector_size. Isn't it expected that I/O that isn't aligned tological_block_sizefails? It's the I/O submitter's responsibility to ensurelogical_block_sizealignment of all I/O segments. Exactly how is the misaligned I/O actually being submitted here?
Thanks for mentioning it - exactly that I asked when reading this patch... It seems that we are here fixing a problem that is just caused when someone ignores clearly set restrictions.
Who is submitting these bioses? Why can it not be fixed there?
What happens with writes to fs journals, etc., is it still safe if we are processing such unaligned bios?
Milan
Hello Milan,
Quoted 36 lines
-----Original Message-----
From: Milan Broz [mailto:[email protected]]
Sent: Thursday, September 24, 2020 2:16 AM
To: Eric Biggers <[email protected]>; Mike Snitzer <[email protected]>
Cc: Sudhakar Panneerselvam <[email protected]>; [email protected]; [email protected]; Martin Petersen <[email protected]>; [email protected]; [email protected]; Shirley Ma <[email protected]>; [email protected]; [email protected]
Subject: Re: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesQuoted 17 lines · Eric Biggers
Quoted 9 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
Quoted 6 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Quoted 5 lines
I don't understand why this is needed, since dm-crypt already sets its
logical_block_sizeto its cryptosector_size. Isn't it expected that I/O that isn't aligned tological_block_sizefails? It's the I/O submitter's responsibility to ensurelogical_block_sizealignment of all I/O segments. Exactly how is the misaligned I/O actually being submitted here?
Quoted 8 lines
Thanks for mentioning it - exactly that I asked when reading this patch... It seems that we are here fixing a problem that is just caused when someone ignores clearly set restrictions.
Who is submitting these bioses? Why can it not be fixed there?
What happens with writes to fs journals, etc., is it still safe if we are processing such unaligned bios?
I don't follow your question regarding fs journals. I am not sure why it is not safe to process unaligned bio segment lengths of fs journals writes. Could you explain with some example on why that would be a problem?
Please see my reply to Eric's/Mike's email, in that, I explained why this issue needs to be fixed in dm-crypt. I hope I have answered to your questions there. If not, let me know, I will try to answer.
Thanks
Sudhakar
Quoted 2 lines
Milan
Hello Eric,
Quoted 29 lines
-----Original Message-----
From: Eric Biggers [mailto:[email protected]]
Sent: Wednesday, September 23, 2020 11:14 PM
To: Mike Snitzer <[email protected]>
Cc: Sudhakar Panneerselvam <[email protected]>; [email protected]; [email protected]; Martin Petersen <[email protected]>; [email protected]; [email protected]; Shirley Ma <[email protected]>; [email protected]; Milan Broz <[email protected]>; [email protected]
Subject: Re: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesQuoted 9 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
Quoted 6 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Quoted 5 lines
I don't understand why this is needed, since dm-crypt already sets its
logical_block_sizeto its cryptosector_size. Isn't it expected that I/O that isn't aligned tological_block_sizefails? It's the I/O submitter's responsibility to ensurelogical_block_sizealignment of all I/O segments. Exactly how is the misaligned I/O actually being submitted here?
You are right that each I/O size should be a multiple of the block device's sector size, but I am not sure if there is any constraint that individual segment lengths should be aligned to its sector size, could you help me with how this is enforced in block layer? The closest I see is "dma_alignment" member in "struct request_queue" of the low-level block device driver and as mentioned in the patch description, iSCSI, MegaRaid, qla2xxx, nvme and others have much relaxed constraint.
To your other question, the IO stack looks like this:
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> dm-crypt <--> iSCSI block device
One real example out of my debugging: Windows sends a I/O request with 6656 bytes to vhost-scsi interface. Vhost-scsi uses translate_desc() in drivers/vhost/vhost.c to convert windows user space memory buffers to kernel iovecs. Vhost-scsi then converts the iovecs to sg entries in vhost_scsi_mapal() which is then handed over to "target" subsystem and eventually submitted to dm-crypt. This 6656 bytes IO has got 3 segments, first segment had 1584, second 4096 and the last had 976 bytes. Dm-crypt rejects the I/O after seeing the first segment length 1584 which is not a 512 byte multiple.
Let me know if there are further questions.
Thanks
Sudhakar
Quoted 2 lines
- Eric
Mikulas Patocka
maintainerQuoted 59 lines · Sudhakar Panneerselvam
Hello Eric,
Quoted 29 lines
-----Original Message-----
From: Eric Biggers [mailto:[email protected]]
Sent: Wednesday, September 23, 2020 11:14 PM
To: Mike Snitzer <[email protected]>
Cc: Sudhakar Panneerselvam <[email protected]>; [email protected]; [email protected]; Martin Petersen <[email protected]>; [email protected]; [email protected]; Shirley Ma <[email protected]>; [email protected]; Milan Broz <[email protected]>; [email protected]
Subject: Re: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesQuoted 9 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
Quoted 6 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Quoted 5 lines
I don't understand why this is needed, since dm-crypt already sets its
logical_block_sizeto its cryptosector_size. Isn't it expected that I/O that isn't aligned tological_block_sizefails? It's the I/O submitter's responsibility to ensurelogical_block_sizealignment of all I/O segments. Exactly how is the misaligned I/O actually being submitted here?You are right that each I/O size should be a multiple of the block device's sector size, but I am not sure if there is any constraint that individual segment lengths should be aligned to its sector size, could you help me with how this is enforced in block layer? The closest I see is "
dma_alignment" member in "structrequest_queue" of the low-level block device driver and as mentioned in the patch description, iSCSI, MegaRaid, qla2xxx, nvme and others have much relaxed constraint.To your other question, the IO stack looks like this:
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> dm-crypt <--> iSCSI block device
One real example out of my debugging: Windows sends a I/O request with 6656 bytes to vhost-scsi interface. Vhost-scsi uses
translate_desc()indrivers/vhost/vhost.cto convert windows user space memory buffers to kernel iovecs. Vhost-scsi then converts the iovecs to sg entries invhost_scsi_mapal()which is then handed over to "target" subsystem and eventually submitted to dm-crypt. This 6656 bytes IO has got 3 segments, first segment had 1584, second 4096 and the last had 976 bytes. Dm-crypt rejects the I/O after seeing the first segment length 1584 which is not a 512 byte multiple.
Quoted 4 lines
Let me know if there are further questions.
Thanks
Sudhakar
Hi
I think it should be fixed in vhost-scsi.
Mikulas
Hi Mikulas,
Quoted 13 lines
Quoted 1 line
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> dm-crypt
<--> iSCSI block device
Quoted 11 lines
One real example out of my debugging: Windows sends a I/O request with 6656 bytes to vhost-scsi interface. Vhost-scsi uses
translate_desc()indrivers/vhost/vhost.cto convert windows user space memory buffers to kernel iovecs. Vhost-scsi then converts the iovecs to sg entries invhost_scsi_mapal()which is then handed over to "target" subsystem and eventually submitted to dm-crypt. This 6656 bytes IO has got 3 segments, first segment had 1584, second 4096 and the last had 976 bytes. Dm-crypt rejects the I/O after seeing the first segment length 1584 which is not a 512 byte multiple.
Quoted 8 lines
Quoted 4 lines
Let me know if there are further questions.
Thanks
SudhakarHi
I think it should be fixed in vhost-scsi.
In the above example of 6656 bytes I/O, windows allocates 6656 bytes virtually contiguous I/O. This IO, when it lands in the kernel, translates to 3 physically discontiguous pages, that's why translate_desc() had to create 3 iovecs to handle this I/O. I don't understand how vhost-scsi could have solved this issue. Only other possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.
Thanks
Sudhakar
Quoted 3 lines
Mikulas
Mikulas Patocka
maintainerQuoted 22 lines · Sudhakar Panneerselvam
Hi Mikulas,
Quoted 20 lines
Quoted 1 line
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> dm-crypt
<--> iSCSI block device
Quoted 11 lines
One real example out of my debugging: Windows sends a I/O request with 6656 bytes to vhost-scsi interface. Vhost-scsi uses
translate_desc()indrivers/vhost/vhost.cto convert windows user space memory buffers to kernel iovecs. Vhost-scsi then converts the iovecs to sg entries invhost_scsi_mapal()which is then handed over to "target" subsystem and eventually submitted to dm-crypt. This 6656 bytes IO has got 3 segments, first segment had 1584, second 4096 and the last had 976 bytes. Dm-crypt rejects the I/O after seeing the first segment length 1584 which is not a 512 byte multiple.Quoted 4 lines
Let me know if there are further questions.
Thanks
SudhakarHi
Quoted 7 lines
Quoted 1 line
I think it should be fixed in vhost-scsi.
In the above example of 6656 bytes I/O, windows allocates 6656 bytes virtually contiguous I/O. This IO, when it lands in the kernel, translates to 3 physically discontiguous pages, that's why
translate_desc()had to create 3 iovecs to handle this I/O. I don't understand how vhost-scsi could have solved this issue.
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
Quoted 8 lines
Only other
possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.Thanks
Sudhakar
Are you sure that the problem is only with dm-crypt? You haven't tried all the existing block device drivers, have you?
Mikulas
Quoted 2 lines
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
I don't like this idea. Because, you need to allocate additional pages for the entire I/O size(for the misaligned case, if you think through carefully, you will know why we have to allocate a temporary buffer that is as big as the original IO) and on top of it, copying the buffer from original to temporary buffer which is all unnecessary while it can simply be fixed in dm-crypt without any of these additional overheads.
Quoted 7 lines
Quoted 7 lines
Only other
possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.
Quoted 5 lines
Quoted 2 lines
Thanks
SudhakarAre you sure that the problem is only with dm-crypt? You haven't tried all the existing block device drivers, have you?
My question is, why dm-crypt worries about alignment requirement of other layers? Is there anything that impacts dm-crypt if the segment lengths are not aligned?(I believe this case is just not handled so far in dm-crypt and my patch addresses it). Should dm-crypt not just pass on all those I/O requests to those respective layers to handle it which will be more graceful?
-Sudhakar
Quoted 8 lines
Mikulas
--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
Mikulas Patocka
maintainerQuoted 5 lines · Sudhakar Panneerselvam
Quoted 2 lines
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
I don't like this idea. Because, you need to allocate additional pages for the entire I/O size(for the misaligned case, if you think through
You can break the I/O to smaller pieces. You can use mempool for pre-allocation of the pages.
Quoted 15 lines
carefully, you will know why we have to allocate a temporary buffer that is as big as the original IO) and on top of it, copying the buffer from original to temporary buffer which is all unnecessary while it can simply be fixed in dm-crypt without any of these additional overheads.
Quoted 10 lines
Quoted 9 lines
Only other
possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.Thanks
Sudhakar
Quoted 6 lines
Quoted 2 lines
Are you sure that the problem is only with dm-crypt? You haven't tried all the existing block device drivers, have you?
My question is, why dm-crypt worries about alignment requirement of other layers? Is there anything that impacts dm-crypt if the segment lengths are not aligned?(I believe this case is just not handled so far
Because the code is simpler if it assumes aligned buffers.
Quoted 5 lines
in dm-crypt and my patch addresses it). Should dm-crypt not just pass on all those I/O requests to those respective layers to handle it which will be more graceful?
-Sudhakar
So, suppose that we change dm-crypt to handle your workload - what are you going to do with other block device drivers that assume aligned bio vector length? How will you find all the other drivers that need to be changed?
You are claiming that "every other component in the Linux IO path handles this case well except for dm-crypt", but this claim is wrong. There are other driver that don't handle misaligned length as well.
Mikulas
Quoted 11 lines · Sudhakar Panneerselvam
Quoted 6 lines
Quoted 3 lines
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
I don't like this idea. Because, you need to allocate additional pages for the entire I/O size(for the misaligned case, if you think through
You can break the I/O to smaller pieces. You can use mempool for pre-allocation of the pages.
Assuming we do this, how is this code simpler(based on your comment below) than the fix in dm-crypt? In fact, this approach would make the code change look bad in vhost, at the same time having performance penalty. By doing this, we are just moving the responsibility to other unrelated component.
Quoted 17 lines
Quoted 17 lines
carefully, you will know why we have to allocate a temporary buffer that is as big as the original IO) and on top of it, copying the buffer from original to temporary buffer which is all unnecessary while it can simply be fixed in dm-crypt without any of these additional overheads.
Quoted 11 lines
Quoted 9 lines
Only other
possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.Thanks
SudhakarAre you sure that the problem is only with dm-crypt? You haven't tried
Quoted 8 lines
all
Quoted 5 lines
Quoted 1 line
the existing block device drivers, have you?
My question is, why dm-crypt worries about alignment requirement of other layers? Is there anything that impacts dm-crypt if the segment lengths are not aligned?(I believe this case is just not handled so far
Because the code is simpler if it assumes aligned buffers.
Did you get a chance to review my changes? If you want more documentation, improve the code, etc, let me know, I can do that if there is scope for that.
Quoted 7 lines
Quoted 6 lines
in dm-crypt and my patch addresses it). Should dm-crypt not just pass on all those I/O requests to those respective layers to handle it which will be more graceful?
-Sudhakar
Quoted 8 lines
So, suppose that we change dm-crypt to handle your workload - what are you
going to do with other block device drivers that assume aligned bio vector length? How will you find all the other drivers that need to be changed?You are claiming that "every other component in the Linux IO path handles this case well except for dm-crypt", but this claim is wrong. There are other driver that don't handle misaligned length as well.
I should not have said, "every other component", I take that back, sorry. How about doing something like this in crypt_convert_block_skcipher():
Add a check that looks at the alignment requirement of the low-level driver and reject the I/O if it doesn't meet that requirement. This means, we still need to handle the case in this function where the low lever driver support unaligned buffer lengths, that means, my other changes in this function would still be needed.
Is this acceptable to everyone?
-Sudhakar
Quoted 8 lines
Mikulas
--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
Quoted 9 lines · Sudhakar Panneerselvam
Quoted 9 lines · Sudhakar Panneerselvam
Quoted 6 lines
Quoted 3 lines
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
I don't like this idea. Because, you need to allocate additional pages for the entire I/O size(for the misaligned case, if you think through
Quoted 8 lines
Quoted 2 lines
You can break the I/O to smaller pieces. You can use mempool for pre-allocation of the pages.
Assuming we do this, how is this code simpler(based on your comment below) than the fix in dm-crypt? In fact, this approach would make the code change look bad in vhost, at the same time having performance penalty. By doing this, we are just moving the responsibility to other unrelated component.
Because vhost is at the top of the block-io food chain. Fixing the unaligned segments there will ensure that it does not matter what device is under it. It will work.
I am still baffled that the unaligned segments go through in the first place... Do we have something missing in the BIO code ?
Quoted 68 lines
Quoted 18 lines
Quoted 18 lines
carefully, you will know why we have to allocate a temporary buffer that is as big as the original IO) and on top of it, copying the buffer from original to temporary buffer which is all unnecessary while it can simply be fixed in dm-crypt without any of these additional overheads.
Quoted 11 lines
Quoted 9 lines
Only other
possibility I see is to have windows fix it by always sending 512 byte aligned buffer lengths, but going with my earlier point that every other component in the Linux IO path handles this case well except for dm-crypt, so it make more sense to fix it in dm-crypt.Thanks
SudhakarAre you sure that the problem is only with dm-crypt? You haven't tried
Quoted 8 lines
all
Quoted 5 lines
Quoted 1 line
the existing block device drivers, have you?
My question is, why dm-crypt worries about alignment requirement of other layers? Is there anything that impacts dm-crypt if the segment lengths are not aligned?(I believe this case is just not handled so far
Because the code is simpler if it assumes aligned buffers.
Did you get a chance to review my changes? If you want more documentation, improve the code, etc, let me know, I can do that if there is scope for that.
Quoted 7 lines
Quoted 6 lines
in dm-crypt and my patch addresses it). Should dm-crypt not just pass on all those I/O requests to those respective layers to handle it which will be more graceful?
-Sudhakar
Quoted 8 lines
So, suppose that we change dm-crypt to handle your workload - what are you
going to do with other block device drivers that assume aligned bio vector length? How will you find all the other drivers that need to be changed?You are claiming that "every other component in the Linux IO path handles this case well except for dm-crypt", but this claim is wrong. There are other driver that don't handle misaligned length as well.
I should not have said, "every other component", I take that back, sorry. How about doing something like this in
crypt_convert_block_skcipher():Add a check that looks at the alignment requirement of the low-level driver and reject the I/O if it doesn't meet that requirement. This means, we still need to handle the case in this function where the low lever driver support unaligned buffer lengths, that means, my other changes in this function would still be needed.
Is this acceptable to everyone?
-Sudhakar
Quoted 8 lines
Mikulas
--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
Signature · 2 lines
Damien Le Moal Western Digital Research
Mike Snitzer
NAKQuoted 19 lines · Damien Le Moal
Quoted 9 lines · Sudhakar Panneerselvam
Quoted 9 lines · Sudhakar Panneerselvam
Quoted 6 lines
Quoted 3 lines
By copying it to a temporary aligned buffer and issuing I/O on this buffer.
I don't like this idea. Because, you need to allocate additional pages for the entire I/O size(for the misaligned case, if you think through
Quoted 8 lines
Quoted 2 lines
You can break the I/O to smaller pieces. You can use mempool for pre-allocation of the pages.
Assuming we do this, how is this code simpler(based on your comment below) than the fix in dm-crypt? In fact, this approach would make the code change look bad in vhost, at the same time having performance penalty. By doing this, we are just moving the responsibility to other unrelated component.
Quoted 3 lines
Because vhost is at the top of the block-io food chain. Fixing the unaligned segments there will ensure that it does not matter what device is under it. It will work.
Right, I agree. This should be addressed in vhost-scsi. And vhost-scsi probably needs to be interfacing through block core to submit IO that respects the limits of its underlying block device.
So please lift your proposed dm-crypt changes to vhost-scsi:
https://patchwork.kernel.org/patch/11781207/
https://patchwork.kernel.org/patch/11781053/
Maybe work with vhost-scsi maintainers to see about making the code reusable in block core; so that any future unaligned application IO is dealt in other drivers using the same common code.
But I'm not interested in taking these changes into dm-crypt:
NAK
Quoted 2 lines
I am still baffled that the unaligned segments go through in the first place... Do we have something missing in the BIO code ?
Cc'ing linux-block, could be.
Thanks,
Mike
Mikulas Patocka
maintainerQuoted 11 lines · Mike Snitzer
You've clearly done a nice job with these changes. Looks clean.
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
... and dm-writecache also expects that the bio is aligned ...
Mikulas
Quoted 5 lines
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Thanks,
Mike
Hello Mike,
Quoted 11 lines
-----Original Message-----
From: Mike Snitzer [mailto:[email protected]]
Sent: Wednesday, September 23, 2020 7:28 PM
To: Sudhakar Panneerselvam <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Shirley Ma <[email protected]>; [email protected]; Martin Petersen <[email protected]>; Milan Broz <[email protected]>
Subject: Re: [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devices
Quoted 1 line
You've clearly done a nice job with these changes. Looks clean.
Thanks.
Quoted 3 lines
BUT, I'm struggling to just accept that dm-crypt needs to go to these extra lengths purely because of one bad apple usecase.
During my initial stages of investigation, I had the same impression as yours, but digging further, I felt fixing dm-crypt would be more appropriate.
In the following two test cases, windows installation/formatting/booting, all were successful.
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> iSCSI block device Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> Local MegaRaid Block Device
When I inserted dm-crypt in the IO path, that is where I noticed windows boot/install/format failures. The IO path is like this:
Windows Guest <--> Vhost-Scsi <--> LIO(scsi/target/blockio) <--> dm-crypt <--> iSCSI block device
After these tests, I realized that, when every other component in the IO stack can handle unaligned bio lengths, why can't make dm-crypt handle the same. Hence, the patch.
Quoted 4 lines
These alignment constraints aren't new. Are there other portions of Linux's crypto subsystem that needed comparable fixes in order to work with Microsfot OS initiated IO through a guest?
I ran basic test with "--cipher aes-xts-plain64" and verified the fix. Also, noticed that the crypto subsystem uses APIs in crypto/skcipher.c which are already specifically written to handle unaligned buffers.
Quoted 3 lines
You forecast that these same kinds of changes are needed for AEAD and dm-integrity... that's alarming.
I understand the concern. I have tried to ensure the patch doesn't result in degrade in performance for the Linux use case. If at all, there is any performance impact due to this change, it will be only for windows(I didn't see any performance drop in my test, though).
Thanks
Sudhakar
Quoted 55 lines
Are we _certain_ there is no other way forward? (Sorry I don't have suggestions.. I'm in "fact finding mode" ;)
Thanks,
MikeQuoted 12 lines · Sudhakar Panneerselvam
Could someone review this patch set, please?
Thanks
SudhakarQuoted 7 lines
-----Original Message-----
From: Sudhakar Panneerselvam
Sent: Wednesday, September 16, 2020 12:40 PM
To: [email protected]; [email protected]; [email protected]
Cc: Shirley Ma <[email protected]>; [email protected]; Martin Petersen <[email protected]>
Subject: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned bufferlengths
Quoted 6 lines
Quoted 6 lines
for skcipher devices
Hi,
This changeset allows processing of unaligned bio requests in dm crypt for the I/Os generated from a windows guest OS in a QEMU environment.
If
Quoted 11 lines
Quoted 11 lines
this changeset is accepted, then I will be submitting another changeset that addresses the similar issue in AEAD disks and dm-integrity module.
Thanks
SudhakarSudhakar Panneerselvam (2):
dm crypt: Allow unaligned bio buffer lengths for skcipher devices dm crypt: Handle unaligned bio buffer lengths for lmk and tcwdrivers/md/dm-crypt.c | 154+++++++++++++++++++++++++++++++++++----
Quoted 12 lines
Quoted 11 lines
-----------
1 file changed, 108 insertions(+), 46 deletions(-)--
1.8.3.1--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel
Mikulas Patocka
maintainerQuoted 4 lines · Sudhakar Panneerselvam
Could someone review this patch set, please?
Thanks
Sudhakar
Hi
I'd like to ask - what sector size do you use in dm-crypt? Could the issue be fixed just by using the smallest possible 512-byte sectors?
What I/O method does qemu use? Is it direct i/o + aio? What is unaligned - the base address? Or length? Or the sector number? Could you use strace on qemu and show an example of an I/O that fails due to alignment?
Mikulas
Hello Mikulas,
Quoted 17 lines
-----Original Message-----
From: Mikulas Patocka [mailto:[email protected]]
Sent: Thursday, September 24, 2020 6:40 AM
To: Sudhakar Panneerselvam <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; dm- [email protected]; [email protected]; Shirley Ma <[email protected]>; [email protected]; Martin Petersen <[email protected]>
Subject: RE: [dm-devel] [RFC PATCH 0/2] dm crypt: Allow unaligned buffer lengths for skcipher devicesQuoted 2 lines · Sudhakar Panneerselvam
Could someone review this patch set, please?
Quoted 7 lines
Quoted 2 lines
Thanks
SudhakarHi
I'd like to ask - what sector size do you use in dm-crypt? Could the issue be fixed just by using the smallest possible 512-byte sectors?
My test has been with 512 bytes sector length.
Quoted 4 lines
What I/O method does qemu use? Is it direct i/o + aio? What is unaligned - the base address? Or length? Or the sector number? Could you use strace on qemu and show an example of an I/O that fails due to alignment?
Please see my update on June 11 @ https://github.com/virtio-win/kvm-guest-drivers-windows/issues/446 when I originally posted this issue to windows virtio forum. It has some finer details of the reproduction steps and might answer some of your questions.
Also, please see my reply to Eric's email on some of the low level details of function call sequence leading to the issue. If there are further questions, let me know.
Thanks
Sudhakar
Quoted 3 lines
Mikulas