From nobody Tue Nov 4 08:12:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1504177763338211.49193606002234; Thu, 31 Aug 2017 04:09:23 -0700 (PDT) Received: from localhost ([::1]:55049 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNLd-0000sU-Ad for importer@patchew.org; Thu, 31 Aug 2017 07:09:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50068) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNI1-0006ea-BU for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dnNHv-0007bD-55 for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46196) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dnNHs-0007YF-Mu; Thu, 31 Aug 2017 07:05:28 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BAF9E7F3E4; Thu, 31 Aug 2017 11:05:27 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id D88DF9ABBC; Thu, 31 Aug 2017 11:05:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com BAF9E7F3E4 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Thu, 31 Aug 2017 12:05:15 +0100 Message-Id: <20170831110518.10741-2-berrange@redhat.com> In-Reply-To: <20170831110518.10741-1-berrange@redhat.com> References: <20170831110518.10741-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 31 Aug 2017 11:05:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 1/4] block: use 1 MB bounce buffers for crypto instead of 16KB X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-block@nongnu.org, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Using 16KB bounce buffers creates a significant performance penalty for I/O to encrypted volumes on storage which high I/O latency (rotating rust & network drives), because it triggers lots of fairly small I/O operations. On tests with rotating rust, and cache=3Dnone|directsync, write speed increased from 2MiB/s to 32MiB/s, on a par with that achieved by the in-kernel luks driver. With other cache modes the in-kernel driver is still notably faster because it is able to report completion of the I/O request before any encryption is done, while the in-QEMU driver must encrypt the data before completion. Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Daniel P. Berrange --- block/crypto.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/block/crypto.c b/block/crypto.c index 58ef6f2f52..cc8afe0e0d 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -379,7 +379,7 @@ static void block_crypto_close(BlockDriverState *bs) } =20 =20 -#define BLOCK_CRYPTO_MAX_SECTORS 32 +#define BLOCK_CRYPTO_MAX_SECTORS 2048 =20 static coroutine_fn int block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num, @@ -396,9 +396,8 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sec= tor_num, =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 - /* Bounce buffer so we have a linear mem region for - * entire sector. XXX optimize so we avoid bounce - * buffer in case that qiov->niov =3D=3D 1 + /* Bounce buffer because we don't wish to expose cipher text + * in qiov which points to guest memory. */ cipher_data =3D qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 5= 12, @@ -464,9 +463,8 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t se= ctor_num, =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 - /* Bounce buffer so we have a linear mem region for - * entire sector. XXX optimize so we avoid bounce - * buffer in case that qiov->niov =3D=3D 1 + /* Bounce buffer because we're not permitted to touch + * contents of qiov - it points to guest memory. */ cipher_data =3D qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 5= 12, --=20 2.13.5 From nobody Tue Nov 4 08:12:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1504177663801143.53413150341112; Thu, 31 Aug 2017 04:07:43 -0700 (PDT) Received: from localhost ([::1]:55038 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNK1-00080n-3O for importer@patchew.org; Thu, 31 Aug 2017 07:07:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50021) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNHy-0006bc-IE for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dnNHx-0007dC-Bm for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41672) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dnNHu-0007ZE-JD; Thu, 31 Aug 2017 07:05:30 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8703B267CD; Thu, 31 Aug 2017 11:05:29 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id F15819ABBC; Thu, 31 Aug 2017 11:05:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8703B267CD Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Thu, 31 Aug 2017 12:05:16 +0100 Message-Id: <20170831110518.10741-3-berrange@redhat.com> In-Reply-To: <20170831110518.10741-1-berrange@redhat.com> References: <20170831110518.10741-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 31 Aug 2017 11:05:29 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 2/4] block: use BDRV_SECTOR_SIZE in crypto driver X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-block@nongnu.org, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Daniel P. Berrange Reviewed-by: Eric Blake --- block/crypto.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/block/crypto.c b/block/crypto.c index cc8afe0e0d..e63f094379 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -392,16 +392,16 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t s= ector_num, QEMUIOVector hd_qiov; int ret =3D 0; size_t payload_offset =3D - qcrypto_block_get_payload_offset(crypto->block) / 512; + qcrypto_block_get_payload_offset(crypto->block) / BDRV_SECTOR_SIZE; =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 /* Bounce buffer because we don't wish to expose cipher text * in qiov which points to guest memory. */ - cipher_data =3D - qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 5= 12, - qiov->size)); + cipher_data =3D qemu_try_blockalign( + bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * BDRV_SECTOR_SIZE, + qiov->size)); if (cipher_data =3D=3D NULL) { ret =3D -ENOMEM; goto cleanup; @@ -415,7 +415,7 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sec= tor_num, } =20 qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512); + qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * BDRV_SECTOR= _SIZE); =20 ret =3D bdrv_co_readv(bs->file, payload_offset + sector_num, @@ -426,18 +426,18 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t s= ector_num, =20 if (qcrypto_block_decrypt(crypto->block, sector_num, - cipher_data, cur_nr_sectors * 512, + cipher_data, cur_nr_sectors * BDRV_SECTO= R_SIZE, NULL) < 0) { ret =3D -EIO; goto cleanup; } =20 qemu_iovec_from_buf(qiov, bytes_done, - cipher_data, cur_nr_sectors * 512); + cipher_data, cur_nr_sectors * BDRV_SECTOR_SIZE= ); =20 remaining_sectors -=3D cur_nr_sectors; sector_num +=3D cur_nr_sectors; - bytes_done +=3D cur_nr_sectors * 512; + bytes_done +=3D cur_nr_sectors * BDRV_SECTOR_SIZE; } =20 cleanup: @@ -459,16 +459,16 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t = sector_num, QEMUIOVector hd_qiov; int ret =3D 0; size_t payload_offset =3D - qcrypto_block_get_payload_offset(crypto->block) / 512; + qcrypto_block_get_payload_offset(crypto->block) / BDRV_SECTOR_SIZE; =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 /* Bounce buffer because we're not permitted to touch * contents of qiov - it points to guest memory. */ - cipher_data =3D - qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 5= 12, - qiov->size)); + cipher_data =3D qemu_try_blockalign( + bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * BDRV_SECTOR_SIZE, + qiov->size)); if (cipher_data =3D=3D NULL) { ret =3D -ENOMEM; goto cleanup; @@ -482,18 +482,18 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t = sector_num, } =20 qemu_iovec_to_buf(qiov, bytes_done, - cipher_data, cur_nr_sectors * 512); + cipher_data, cur_nr_sectors * BDRV_SECTOR_SIZE); =20 if (qcrypto_block_encrypt(crypto->block, sector_num, - cipher_data, cur_nr_sectors * 512, + cipher_data, cur_nr_sectors * BDRV_SECTO= R_SIZE, NULL) < 0) { ret =3D -EIO; goto cleanup; } =20 qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512); + qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * BDRV_SECTOR= _SIZE); =20 ret =3D bdrv_co_writev(bs->file, payload_offset + sector_num, @@ -504,7 +504,7 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t se= ctor_num, =20 remaining_sectors -=3D cur_nr_sectors; sector_num +=3D cur_nr_sectors; - bytes_done +=3D cur_nr_sectors * 512; + bytes_done +=3D cur_nr_sectors * BDRV_SECTOR_SIZE; } =20 cleanup: --=20 2.13.5 From nobody Tue Nov 4 08:12:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1504177987065334.89495612264375; Thu, 31 Aug 2017 04:13:07 -0700 (PDT) Received: from localhost ([::1]:55068 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNPE-0003U4-VF for importer@patchew.org; Thu, 31 Aug 2017 07:13:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50146) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNI9-0006mg-PM for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dnNI2-0007lF-UP for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49462) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dnNHx-0007d5-Pn; Thu, 31 Aug 2017 07:05:33 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CEBFD404312; Thu, 31 Aug 2017 11:05:32 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id E45739ABBC; Thu, 31 Aug 2017 11:05:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com CEBFD404312 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Thu, 31 Aug 2017 12:05:17 +0100 Message-Id: <20170831110518.10741-4-berrange@redhat.com> In-Reply-To: <20170831110518.10741-1-berrange@redhat.com> References: <20170831110518.10741-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 31 Aug 2017 11:05:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 3/4] block: convert crypto driver to bdrv_co_preadv|pwritev X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-block@nongnu.org, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Make the crypto driver implement the bdrv_co_preadv|pwritev callbacks, and also use bdrv_co_preadv|pwritev for I/O with the protocol driver beneath. Signed-off-by: Daniel P. Berrange Reviewed-by: Eric Blake --- block/crypto.c | 103 +++++++++++++++++++++++++++++------------------------= ---- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/block/crypto.c b/block/crypto.c index e63f094379..40daa77188 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -380,19 +380,23 @@ static void block_crypto_close(BlockDriverState *bs) =20 =20 #define BLOCK_CRYPTO_MAX_SECTORS 2048 +#define BLOCK_CRYPTO_MAX_LENGTH (BLOCK_CRYPTO_MAX_SECTORS * BDRV_SECTOR_SI= ZE) =20 static coroutine_fn int -block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num, - int remaining_sectors, QEMUIOVector *qiov) +block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t byt= es, + QEMUIOVector *qiov, int flags) { BlockCrypto *crypto =3D bs->opaque; - int cur_nr_sectors; /* number of sectors in current iteration */ + uint64_t cur_bytes; /* number of bytes in current iteration */ uint64_t bytes_done =3D 0; uint8_t *cipher_data =3D NULL; QEMUIOVector hd_qiov; int ret =3D 0; - size_t payload_offset =3D - qcrypto_block_get_payload_offset(crypto->block) / BDRV_SECTOR_SIZE; + size_t payload_offset =3D qcrypto_block_get_payload_offset(crypto->blo= ck); + uint64_t sector_num =3D offset / BDRV_SECTOR_SIZE; + + assert((offset % BDRV_SECTOR_SIZE) =3D=3D 0); + assert((bytes % BDRV_SECTOR_SIZE) =3D=3D 0); =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 @@ -400,44 +404,39 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t s= ector_num, * in qiov which points to guest memory. */ cipher_data =3D qemu_try_blockalign( - bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * BDRV_SECTOR_SIZE, - qiov->size)); + bs->file->bs, MIN(BLOCK_CRYPTO_MAX_LENGTH, qiov->size)); if (cipher_data =3D=3D NULL) { ret =3D -ENOMEM; goto cleanup; } =20 - while (remaining_sectors) { - cur_nr_sectors =3D remaining_sectors; + while (bytes) { + cur_bytes =3D bytes; =20 - if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) { - cur_nr_sectors =3D BLOCK_CRYPTO_MAX_SECTORS; + if (cur_bytes > BLOCK_CRYPTO_MAX_LENGTH) { + cur_bytes =3D BLOCK_CRYPTO_MAX_LENGTH; } =20 qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * BDRV_SECTOR= _SIZE); + qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); =20 - ret =3D bdrv_co_readv(bs->file, - payload_offset + sector_num, - cur_nr_sectors, &hd_qiov); + ret =3D bdrv_co_preadv(bs->file, payload_offset + offset + bytes_d= one, + cur_bytes, &hd_qiov, 0); if (ret < 0) { goto cleanup; } =20 - if (qcrypto_block_decrypt(crypto->block, - sector_num, - cipher_data, cur_nr_sectors * BDRV_SECTO= R_SIZE, - NULL) < 0) { + if (qcrypto_block_decrypt(crypto->block, sector_num, cipher_data, + cur_bytes, NULL) < 0) { ret =3D -EIO; goto cleanup; } =20 - qemu_iovec_from_buf(qiov, bytes_done, - cipher_data, cur_nr_sectors * BDRV_SECTOR_SIZE= ); + qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes); =20 - remaining_sectors -=3D cur_nr_sectors; - sector_num +=3D cur_nr_sectors; - bytes_done +=3D cur_nr_sectors * BDRV_SECTOR_SIZE; + sector_num +=3D cur_bytes / BDRV_SECTOR_SIZE; + bytes -=3D cur_bytes; + bytes_done +=3D cur_bytes; } =20 cleanup: @@ -449,17 +448,20 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t s= ector_num, =20 =20 static coroutine_fn int -block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num, - int remaining_sectors, QEMUIOVector *qiov) +block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t by= tes, + QEMUIOVector *qiov, int flags) { BlockCrypto *crypto =3D bs->opaque; - int cur_nr_sectors; /* number of sectors in current iteration */ + uint64_t cur_bytes; /* number of bytes in current iteration */ uint64_t bytes_done =3D 0; uint8_t *cipher_data =3D NULL; QEMUIOVector hd_qiov; int ret =3D 0; - size_t payload_offset =3D - qcrypto_block_get_payload_offset(crypto->block) / BDRV_SECTOR_SIZE; + size_t payload_offset =3D qcrypto_block_get_payload_offset(crypto->blo= ck); + uint64_t sector_num =3D offset / BDRV_SECTOR_SIZE; + + assert((offset % BDRV_SECTOR_SIZE) =3D=3D 0); + assert((bytes % BDRV_SECTOR_SIZE) =3D=3D 0); =20 qemu_iovec_init(&hd_qiov, qiov->niov); =20 @@ -467,44 +469,39 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t = sector_num, * contents of qiov - it points to guest memory. */ cipher_data =3D qemu_try_blockalign( - bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * BDRV_SECTOR_SIZE, - qiov->size)); + bs->file->bs, MIN(BLOCK_CRYPTO_MAX_LENGTH, qiov->size)); if (cipher_data =3D=3D NULL) { ret =3D -ENOMEM; goto cleanup; } =20 - while (remaining_sectors) { - cur_nr_sectors =3D remaining_sectors; + while (bytes) { + cur_bytes =3D bytes; =20 - if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) { - cur_nr_sectors =3D BLOCK_CRYPTO_MAX_SECTORS; + if (cur_bytes > BLOCK_CRYPTO_MAX_LENGTH) { + cur_bytes =3D BLOCK_CRYPTO_MAX_LENGTH; } =20 - qemu_iovec_to_buf(qiov, bytes_done, - cipher_data, cur_nr_sectors * BDRV_SECTOR_SIZE); + qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes); =20 - if (qcrypto_block_encrypt(crypto->block, - sector_num, - cipher_data, cur_nr_sectors * BDRV_SECTO= R_SIZE, - NULL) < 0) { + if (qcrypto_block_encrypt(crypto->block, sector_num, cipher_data, + cur_bytes, NULL) < 0) { ret =3D -EIO; goto cleanup; } =20 qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * BDRV_SECTOR= _SIZE); + qemu_iovec_add(&hd_qiov, cipher_data, cur_bytes); =20 - ret =3D bdrv_co_writev(bs->file, - payload_offset + sector_num, - cur_nr_sectors, &hd_qiov); + ret =3D bdrv_co_pwritev(bs->file, payload_offset + offset + bytes_= done, + cur_bytes, &hd_qiov, 0); if (ret < 0) { goto cleanup; } =20 - remaining_sectors -=3D cur_nr_sectors; - sector_num +=3D cur_nr_sectors; - bytes_done +=3D cur_nr_sectors * BDRV_SECTOR_SIZE; + sector_num +=3D cur_bytes / BDRV_SECTOR_SIZE; + bytes -=3D cur_bytes; + bytes_done +=3D cur_bytes; } =20 cleanup: @@ -514,6 +511,11 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t s= ector_num, return ret; } =20 +static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp) +{ + bs->bl.request_alignment =3D BDRV_SECTOR_SIZE; /* No sub-sector I/O */ +} + =20 static int64_t block_crypto_getlength(BlockDriverState *bs) { @@ -611,8 +613,9 @@ BlockDriver bdrv_crypto_luks =3D { .bdrv_truncate =3D block_crypto_truncate, .create_opts =3D &block_crypto_create_opts_luks, =20 - .bdrv_co_readv =3D block_crypto_co_readv, - .bdrv_co_writev =3D block_crypto_co_writev, + .bdrv_refresh_limits =3D block_crypto_refresh_limits, + .bdrv_co_preadv =3D block_crypto_co_preadv, + .bdrv_co_pwritev =3D block_crypto_co_pwritev, .bdrv_getlength =3D block_crypto_getlength, .bdrv_get_info =3D block_crypto_get_info_luks, .bdrv_get_specific_info =3D block_crypto_get_specific_info_luks, --=20 2.13.5 From nobody Tue Nov 4 08:12:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1504177790796655.9481676462713; Thu, 31 Aug 2017 04:09:50 -0700 (PDT) Received: from localhost ([::1]:55051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNM4-0001E1-Em for importer@patchew.org; Thu, 31 Aug 2017 07:09:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50166) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dnNIF-0006qw-3B for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dnNID-0007vR-9s for qemu-devel@nongnu.org; Thu, 31 Aug 2017 07:05:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41812) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dnNHz-0007fD-L6; Thu, 31 Aug 2017 07:05:35 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A2D1B267C6; Thu, 31 Aug 2017 11:05:34 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 133799ABBC; Thu, 31 Aug 2017 11:05:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A2D1B267C6 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Thu, 31 Aug 2017 12:05:18 +0100 Message-Id: <20170831110518.10741-5-berrange@redhat.com> In-Reply-To: <20170831110518.10741-1-berrange@redhat.com> References: <20170831110518.10741-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 31 Aug 2017 11:05:34 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 4/4] block: convert qcrypto_block_encrypt|decrypt to take bytes offset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-block@nongnu.org, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Instead of sector offset, take the bytes offset when encrypting or decrypting data. Signed-off-by: Daniel P. Berrange --- block/crypto.c | 8 ++++---- block/qcow.c | 7 +++++-- block/qcow2-cluster.c | 8 +++----- block/qcow2.c | 4 ++-- crypto/block-luks.c | 12 ++++++++---- crypto/block-qcow.c | 12 ++++++++---- crypto/block.c | 14 ++++++++------ crypto/blockpriv.h | 4 ++-- include/crypto/block.h | 14 ++++++++------ 9 files changed, 48 insertions(+), 35 deletions(-) diff --git a/block/crypto.c b/block/crypto.c index 40daa77188..6b8d88efbc 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -426,8 +426,8 @@ block_crypto_co_preadv(BlockDriverState *bs, uint64_t o= ffset, uint64_t bytes, goto cleanup; } =20 - if (qcrypto_block_decrypt(crypto->block, sector_num, cipher_data, - cur_bytes, NULL) < 0) { + if (qcrypto_block_decrypt(crypto->block, offset + bytes_done, + cipher_data, cur_bytes, NULL) < 0) { ret =3D -EIO; goto cleanup; } @@ -484,8 +484,8 @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t = offset, uint64_t bytes, =20 qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes); =20 - if (qcrypto_block_encrypt(crypto->block, sector_num, cipher_data, - cur_bytes, NULL) < 0) { + if (qcrypto_block_encrypt(crypto->block, offset + bytes_done, + cipher_data, cur_bytes, NULL) < 0) { ret =3D -EIO; goto cleanup; } diff --git a/block/qcow.c b/block/qcow.c index c08cdc4a7b..c2a446e824 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -456,7 +456,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, if (i < n_start || i >=3D n_end) { Error *err =3D NULL; memset(s->cluster_data, 0x00, 512); - if (qcrypto_block_encrypt(s->crypto, start_sec= t + i, + if (qcrypto_block_encrypt(s->crypto, + start_sect + i * + BDRV_SECTOR_SIZE, s->cluster_data, BDRV_SECTOR_SIZE, &err) < 0) { @@ -636,7 +638,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState = *bs, int64_t sector_num, } if (bs->encrypted) { assert(s->crypto); - if (qcrypto_block_decrypt(s->crypto, sector_num, buf, + if (qcrypto_block_decrypt(s->crypto, + sector_num * BDRV_SECTOR_SIZE, b= uf, n * BDRV_SECTOR_SIZE, &err) < 0)= { goto fail; } diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index f06c08f64c..85ffc33c2c 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -396,15 +396,13 @@ static bool coroutine_fn do_perform_cow_encrypt(Block= DriverState *bs, { if (bytes && bs->encrypted) { BDRVQcow2State *s =3D bs->opaque; - int64_t sector =3D (s->crypt_physical_offset ? + int64_t offset =3D (s->crypt_physical_offset ? (cluster_offset + offset_in_cluster) : - (src_cluster_offset + offset_in_cluster)) - >> BDRV_SECTOR_BITS; + (src_cluster_offset + offset_in_cluster)); assert((offset_in_cluster & ~BDRV_SECTOR_MASK) =3D=3D 0); assert((bytes & ~BDRV_SECTOR_MASK) =3D=3D 0); assert(s->crypto); - if (qcrypto_block_encrypt(s->crypto, sector, buffer, - bytes, NULL) < 0) { + if (qcrypto_block_encrypt(s->crypto, offset, buffer, bytes, NULL) = < 0) { return false; } } diff --git a/block/qcow2.c b/block/qcow2.c index 40ba26c111..1c9f6c8f7d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1824,7 +1824,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverSt= ate *bs, uint64_t offset, if (qcrypto_block_decrypt(s->crypto, (s->crypt_physical_offset ? cluster_offset + offset_in_clus= ter : - offset) >> BDRV_SECTOR_BITS, + offset), cluster_data, cur_bytes, &err) < 0) { @@ -1961,7 +1961,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverS= tate *bs, uint64_t offset, if (qcrypto_block_encrypt(s->crypto, (s->crypt_physical_offset ? cluster_offset + offset_in_cluster : - offset) >> BDRV_SECTOR_BITS, + offset), cluster_data, cur_bytes, &err) < 0) { error_free(err); diff --git a/crypto/block-luks.c b/crypto/block-luks.c index afb8543108..672b0986e0 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -1403,29 +1403,33 @@ static void qcrypto_block_luks_cleanup(QCryptoBlock= *block) =20 static int qcrypto_block_luks_decrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { + assert(!(offset % QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); + assert(!(len % QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); return qcrypto_block_decrypt_helper(block->cipher, block->niv, block->ivgen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - startsector, buf, len, errp); + offset, buf, len, errp); } =20 =20 static int qcrypto_block_luks_encrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { + assert(!(offset % QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); + assert(!(len % QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); return qcrypto_block_encrypt_helper(block->cipher, block->niv, block->ivgen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - startsector, buf, len, errp); + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index a456fe338b..9d2efa27d6 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -142,29 +142,33 @@ qcrypto_block_qcow_cleanup(QCryptoBlock *block) =20 static int qcrypto_block_qcow_decrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { + assert(!(offset % QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); + assert(!(len % QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); return qcrypto_block_decrypt_helper(block->cipher, block->niv, block->ivgen, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - startsector, buf, len, errp); + offset, buf, len, errp); } =20 =20 static int qcrypto_block_qcow_encrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { + assert(!(offset % QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); + assert(!(len % QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); return qcrypto_block_encrypt_helper(block->cipher, block->niv, block->ivgen, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - startsector, buf, len, errp); + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block.c b/crypto/block.c index b097d451af..84ef5d870a 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -127,22 +127,22 @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock= *block, =20 =20 int qcrypto_block_decrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { - return block->driver->decrypt(block, startsector, buf, len, errp); + return block->driver->decrypt(block, offset, buf, len, errp); } =20 =20 int qcrypto_block_encrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { - return block->driver->encrypt(block, startsector, buf, len, errp); + return block->driver->encrypt(block, offset, buf, len, errp); } =20 =20 @@ -188,13 +188,14 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *ciphe= r, size_t niv, QCryptoIVGen *ivgen, int sectorsize, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { uint8_t *iv; int ret =3D -1; + uint64_t startsector =3D offset / sectorsize; =20 iv =3D niv ? g_new0(uint8_t, niv) : NULL; =20 @@ -237,13 +238,14 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *ciphe= r, size_t niv, QCryptoIVGen *ivgen, int sectorsize, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp) { uint8_t *iv; int ret =3D -1; + uint64_t startsector =3D offset / sectorsize; =20 iv =3D niv ? g_new0(uint8_t, niv) : NULL; =20 diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 0edb810e22..53e66e58fb 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -81,7 +81,7 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, size_t niv, QCryptoIVGen *ivgen, int sectorsize, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp); @@ -90,7 +90,7 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, size_t niv, QCryptoIVGen *ivgen, int sectorsize, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp); diff --git a/include/crypto/block.h b/include/crypto/block.h index f0e543bee1..2dea165a8a 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -161,18 +161,19 @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock= *block, /** * @qcrypto_block_decrypt: * @block: the block encryption object - * @startsector: the sector from which @buf was read + * @offset: the position at which @iov was read * @buf: the buffer to decrypt * @len: the length of @buf in bytes * @errp: pointer to a NULL-initialized error object * * Decrypt @len bytes of cipher text in @buf, writing - * plain text back into @buf + * plain text back into @buf. @len and @offset must be + * a multiple of the encryption format sector size. * * Returns 0 on success, -1 on failure */ int qcrypto_block_decrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp); @@ -180,18 +181,19 @@ int qcrypto_block_decrypt(QCryptoBlock *block, /** * @qcrypto_block_encrypt: * @block: the block encryption object - * @startsector: the sector to which @buf will be written + * @offset: the position at which @iov will be written * @buf: the buffer to decrypt * @len: the length of @buf in bytes * @errp: pointer to a NULL-initialized error object * * Encrypt @len bytes of plain text in @buf, writing - * cipher text back into @buf + * cipher text back into @buf. @len and @offset must be + * a multiple of the encryption format sector size. * * Returns 0 on success, -1 on failure */ int qcrypto_block_encrypt(QCryptoBlock *block, - uint64_t startsector, + uint64_t offset, uint8_t *buf, size_t len, Error **errp); --=20 2.13.5