From nobody Mon Apr 29 17:56:27 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1606202440; cv=none; d=zohomail.com; s=zohoarc; b=K+vUYVsTZpu6RwRL1HtWhsMWpSqK3YYf/kDeDGlJdLZPPe/lOsj/qx+rg/teqVzaVI8u/J8Md3xDKRHezj4iaSTD5T4B/bdfWzhGFnSmxONQBWhgnoCJwFpCNu0/cOF+ZNpCMedVgLgunny3awyY45Lbxf10Dx95q+6wjbgPUVA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1606202440; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=EXXDAKOyrZra0bOq7lul8TgtVYdiYsmmsQgpMFjoe+w=; b=Axg8ygZbTXmfXfwHRGUMgbg8LY+qk2r3LRWlALVP5dkeZfR0YnE2UhftideeH8yngEOhto1268NqcVGP4wwF7NGz30BX20b9xZ7A9OsgEWieW048NRVTMa5o/qGD/WEWkAIMpzau0sX+txNPmQ51T9pBuscG3D4u4lGp6QoUJ7U= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1606202440097896.5342850541152; Mon, 23 Nov 2020 23:20:40 -0800 (PST) Received: from localhost ([::1]:42100 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1khScw-0008Pp-Na for importer@patchew.org; Tue, 24 Nov 2020 02:20:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41752) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1khSWz-0006pV-CF; Tue, 24 Nov 2020 02:14:29 -0500 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:33125) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1khSWw-0001Je-FM; Tue, 24 Nov 2020 02:14:29 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 115EA5C01E1; Tue, 24 Nov 2020 02:14:24 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 24 Nov 2020 02:14:24 -0500 Received: from apples.local (80-167-98-190-cable.dk.customer.tdc.net [80.167.98.190]) by mail.messagingengine.com (Postfix) with ESMTPA id 56FAC3064AB2; Tue, 24 Nov 2020 02:14:22 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irrelevant.dk; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=EXXDAKOyrZra0 bOq7lul8TgtVYdiYsmmsQgpMFjoe+w=; b=ddVDsFeZQ1LVTm+HZwmDKJ3FGaJ0a FKL1K75SklqSMs4Ta0PvoDtrg5jFbJyMhsbAPo7W0RJaNrvR/iQOm92iuqzBxNZC DnZqWu0RasOeWCr6PH7RTv8A5JMde66LezyqBCrwhdagL8jizBEPbctd6wUx8mZI 7P/Z6TFLJLHOPDHfnG+6F+CGm3du9o/s8sSmvHC8Vctga+xZT5inzfNBZ1EPBCD7 kuBckT0E5SpSf/1grPWRbScI83a10JIG6onIRi7nkmN925/NJ/Qoq/dc+izny0+p hTUJVrVVnKpL5Khy8uigBGbIHn3V5zdK0ys9vhSumPeT7/pMsav7BiqMw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=EXXDAKOyrZra0bOq7lul8TgtVYdiYsmmsQgpMFjoe+w=; b=fiZTsPx1 VK5hr42FyjJIQQi9uakpGn1ZVhHBs0lV4YyoYX4AgfFh3EwKH5yAp92RLDWQqW8F GvUPzQTqeaSRLsQK00WaZP9DwKm5fEU9/+/h32wT18MbfDzn3U7fmCTHzG/ZOwxl mbH4UCKR5dxIiXm+56fmDPGp+ro4Yhn4Rfo66b16SRYY5omeeNSIX+hP8W/+SL2M glz0kb3ybSJezW90Wz0Wc7rP0yYt/Rkcqo16JV4qEh2EgisLSeHLUANPvoXME7DX msnpkmOaSsHrMDQpEtiAdREyeqdrjnIV+kg1Raj/hxmty2+VEw+4Nn6sfArEXyG5 bfPNfMeqaxd6Pg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudegjedgudefvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepmfhlrghu shculfgvnhhsvghnuceoihhtshesihhrrhgvlhgvvhgrnhhtrdgukheqnecuggftrfgrth htvghrnhepueelteegieeuhffgkeefgfevjeeigfetkeeitdfgtdeifefhtdfhfeeuffev gfeknecukfhppeektddrudeijedrleekrdduledtnecuvehluhhsthgvrhfuihiivgeptd enucfrrghrrghmpehmrghilhhfrhhomhepihhtshesihhrrhgvlhgvvhgrnhhtrdgukh X-ME-Proxy: From: Klaus Jensen To: qemu-devel@nongnu.org Subject: [PATCH 1/2] nvme: updated shared header for copy command Date: Tue, 24 Nov 2020 08:14:17 +0100 Message-Id: <20201124071418.12160-2-its@irrelevant.dk> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124071418.12160-1-its@irrelevant.dk> References: <20201124071418.12160-1-its@irrelevant.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=66.111.4.26; envelope-from=its@irrelevant.dk; helo=out2-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Klaus Jensen , Max Reitz , Klaus Jensen , Stefan Hajnoczi , Keith Busch Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Klaus Jensen Add new data structures and types for the Simple Copy command. Signed-off-by: Klaus Jensen Cc: Stefan Hajnoczi Cc: Fam Zheng Acked-by: Stefan Hajnoczi Reviewed-by: Minwoo Im --- include/block/nvme.h | 45 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/include/block/nvme.h b/include/block/nvme.h index e95ff6ca9b37..b56efd6a89af 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -472,6 +472,7 @@ enum NvmeIoCommands { NVME_CMD_COMPARE =3D 0x05, NVME_CMD_WRITE_ZEROES =3D 0x08, NVME_CMD_DSM =3D 0x09, + NVME_CMD_COPY =3D 0x19, }; =20 typedef struct QEMU_PACKED NvmeDeleteQ { @@ -603,6 +604,35 @@ typedef struct QEMU_PACKED NvmeDsmRange { uint64_t slba; } NvmeDsmRange; =20 +enum { + NVME_COPY_FORMAT_0 =3D 0x0, +}; + +typedef struct NvmeCopyCmd { + uint8_t opcode; + uint8_t flags; + uint16_t cid; + uint32_t nsid; + uint32_t rsvd2[4]; + NvmeCmdDptr dptr; + uint64_t sdlba; + uint32_t cdw12; + uint32_t cdw13; + uint32_t ilbrt; + uint16_t lbat; + uint16_t lbatm; +} NvmeCopyCmd; + +typedef struct NvmeCopySourceRange { + uint8_t rsvd0[8]; + uint64_t slba; + uint16_t nlb; + uint8_t rsvd18[6]; + uint32_t eilbrt; + uint16_t elbatm; + uint16_t elbat; +} NvmeCopySourceRange; + enum NvmeAsyncEventRequest { NVME_AER_TYPE_ERROR =3D 0, NVME_AER_TYPE_SMART =3D 1, @@ -680,6 +710,7 @@ enum NvmeStatusCodes { NVME_CONFLICTING_ATTRS =3D 0x0180, NVME_INVALID_PROT_INFO =3D 0x0181, NVME_WRITE_TO_RO =3D 0x0182, + NVME_CMD_SIZE_LIMIT =3D 0x0183, NVME_WRITE_FAULT =3D 0x0280, NVME_UNRECOVERED_READ =3D 0x0281, NVME_E2E_GUARD_ERROR =3D 0x0282, @@ -831,7 +862,7 @@ typedef struct QEMU_PACKED NvmeIdCtrl { uint8_t nvscc; uint8_t rsvd531; uint16_t acwu; - uint8_t rsvd534[2]; + uint16_t ocfs; uint32_t sgls; uint8_t rsvd540[228]; uint8_t subnqn[256]; @@ -854,6 +885,11 @@ enum NvmeIdCtrlOncs { NVME_ONCS_FEATURES =3D 1 << 4, NVME_ONCS_RESRVATIONS =3D 1 << 5, NVME_ONCS_TIMESTAMP =3D 1 << 6, + NVME_ONCS_COPY =3D 1 << 8, +}; + +enum NvmeIdCtrlOcfs { + NVME_OCFS_COPY_FORMAT_0 =3D 1 << NVME_COPY_FORMAT_0, }; =20 enum NvmeIdCtrlFrmw { @@ -995,7 +1031,10 @@ typedef struct QEMU_PACKED NvmeIdNs { uint16_t npdg; uint16_t npda; uint16_t nows; - uint8_t rsvd74[30]; + uint16_t mssrl; + uint32_t mcl; + uint8_t msrc; + uint8_t rsvd81[23]; uint8_t nguid[16]; uint64_t eui64; NvmeLBAF lbaf[16]; @@ -1059,6 +1098,7 @@ static inline void _nvme_check_size(void) QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) !=3D 4); QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) !=3D 16); QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) !=3D 16); + QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRange) !=3D 32); QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) !=3D 64); @@ -1066,6 +1106,7 @@ static inline void _nvme_check_size(void) QEMU_BUILD_BUG_ON(sizeof(NvmeIdentify) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeRwCmd) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeDsmCmd) !=3D 64); + QEMU_BUILD_BUG_ON(sizeof(NvmeCopyCmd) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeRangeType) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) !=3D 64); QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) !=3D 512); --=20 2.29.2 From nobody Mon Apr 29 17:56:27 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1606202890; cv=none; d=zohomail.com; s=zohoarc; b=M9NJGzYnKdPQ8yWnxHQmULvza2mmiqyEZxKQi7iERgKwSpMnpTzBUARAKaJNMOmbG1vBVFdyfcJKnlHXoOpwTWllz0miwcc45XVRCXGLMY5OqjvZgqBpIZHrF4k5t8w3/KgFEcRKskY+2ezKBJEe+iSf7iTVqt9EuPBd4JwcM0A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1606202890; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=MntrGkJALBl9B8Uoh5Jj33osbScpCkhPmPMRVEUbVR8=; b=l3pVPVrngpOBHsg+rgk6zf5btcsPFPAofKqmScKA/bSNq1bLePxpZVrSuiVJjxdu9Befbwuwu+nQpOiirBHbge0xG/lx23Agnk5N9wSrGctxO8UGWWBY0ZfQGiDL8uTlL7hEbnnL9idBSZOR7XH2A6jRz0pgYHEJsjz05TamaA8= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1606202889779892.3464378979154; Mon, 23 Nov 2020 23:28:09 -0800 (PST) Received: from localhost ([::1]:48012 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1khSkC-0002s7-Cu for importer@patchew.org; Tue, 24 Nov 2020 02:28:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41756) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1khSX0-0006pr-5C; Tue, 24 Nov 2020 02:14:30 -0500 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:42987) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1khSWw-0001KS-Sa; Tue, 24 Nov 2020 02:14:29 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id DF0015C01E3; Tue, 24 Nov 2020 02:14:24 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 24 Nov 2020 02:14:24 -0500 Received: from apples.local (80-167-98-190-cable.dk.customer.tdc.net [80.167.98.190]) by mail.messagingengine.com (Postfix) with ESMTPA id B601A3064AB4; Tue, 24 Nov 2020 02:14:23 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irrelevant.dk; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=MntrGkJALBl9B 8Uoh5Jj33osbScpCkhPmPMRVEUbVR8=; b=jzdBuRv+BHSne5sLAyt1zBuq+LGur Yf356NF8k6pMMJT5Vii7/jeKBCIv0tU5TvwjAOuDrDX01A/yI6jKrMMYnXTEV0vn pDgbQdVk/ZFkC+ktk4HHnubsy7kVo8uPW73DjAP8uIr/0DhbbpmdhHJ+WnuVyFKq tZi33WVvkMVOg3Vh8M72volp5X/bYGQala8g5eMpLliitoGsM1WxrrCFrIymlARB 7+UIaaa1qwR+H9v8p0dMnWLrG8RNYlORowdEz1nH+Mm9lJzApuu5U8WX5yTimD6S +nbIDd5xS0Nn2Pw9Qu+C9cWRqOQi4cye0SmMPaZB18ixG4yS9OmDYCThw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=MntrGkJALBl9B8Uoh5Jj33osbScpCkhPmPMRVEUbVR8=; b=IbqZVmQF pGNh4peWrkzcFFpW5rFNcjCNCN1maF4O7crPZbN2yos7WDgf4NHLzDzZvjIup4nN C8G9HMYbvQyOo6oe3nC7XMRrtUO5cVwrmjLLCW8BHN0tLE0fleWrnuIYjUmxfeZm AuBvgA+EDdSDoiKWC1wrtSZ0sTcWIkhxzqMzbA24zCKh/NoqVTWSW1R5wqFBs9mK rKcoJq0OBqKUAdBrU5DcKymyO27aZ7KQAt8XaWmWvBDx9HL8ACasybmbi7e0Ol5L /GuymKzyiiLZx0zguTPmmbqdaImyOsIjwllPnU6cNfq9PATubQGADURuWhSeHJOK 3PG6uQkYHm314Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudegjedgudefvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepmfhlrghu shculfgvnhhsvghnuceoihhtshesihhrrhgvlhgvvhgrnhhtrdgukheqnecuggftrfgrth htvghrnhepueelteegieeuhffgkeefgfevjeeigfetkeeitdfgtdeifefhtdfhfeeuffev gfeknecukfhppeektddrudeijedrleekrdduledtnecuvehluhhsthgvrhfuihiivgeptd enucfrrghrrghmpehmrghilhhfrhhomhepihhtshesihhrrhgvlhgvvhgrnhhtrdgukh X-ME-Proxy: From: Klaus Jensen To: qemu-devel@nongnu.org Subject: [PATCH 2/2] hw/block/nvme: add simple copy command Date: Tue, 24 Nov 2020 08:14:18 +0100 Message-Id: <20201124071418.12160-3-its@irrelevant.dk> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124071418.12160-1-its@irrelevant.dk> References: <20201124071418.12160-1-its@irrelevant.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=66.111.4.26; envelope-from=its@irrelevant.dk; helo=out2-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-block@nongnu.org, Klaus Jensen , Max Reitz , Klaus Jensen , Keith Busch Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Klaus Jensen Add support for TP 4065a ("Simple Copy Command"), v2020.05.04 ("Ratified"). The implementation uses a bounce buffer to first read in the source logical blocks, then issue a write of that bounce buffer. The default maximum number of source logical blocks is 128, translating to 512 KiB for 4k logical blocks which aligns with the default value of MDTS. Signed-off-by: Klaus Jensen --- hw/block/nvme-ns.h | 4 + hw/block/nvme.h | 1 + hw/block/nvme-ns.c | 8 ++ hw/block/nvme.c | 225 +++++++++++++++++++++++++++++++++++++++++- hw/block/trace-events | 6 ++ 5 files changed, 243 insertions(+), 1 deletion(-) diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h index 44bf6271b744..745d288b09cf 100644 --- a/hw/block/nvme-ns.h +++ b/hw/block/nvme-ns.h @@ -21,6 +21,10 @@ =20 typedef struct NvmeNamespaceParams { uint32_t nsid; + + uint16_t mssrl; + uint32_t mcl; + uint8_t msrc; } NvmeNamespaceParams; =20 typedef struct NvmeNamespace { diff --git a/hw/block/nvme.h b/hw/block/nvme.h index 574333caa3f9..f549abeeb930 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -62,6 +62,7 @@ static inline const char *nvme_io_opc_str(uint8_t opc) case NVME_CMD_READ: return "NVME_NVM_CMD_READ"; case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES"; case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM"; + case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY"; default: return "NVME_NVM_CMD_UNKNOWN"; } } diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c index 2d69b5177b51..eb28757c2f17 100644 --- a/hw/block/nvme-ns.c +++ b/hw/block/nvme-ns.c @@ -59,6 +59,11 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp) =20 id_ns->npda =3D id_ns->npdg =3D npdg - 1; =20 + /* simple copy */ + id_ns->mssrl =3D cpu_to_le16(ns->params.mssrl); + id_ns->mcl =3D cpu_to_le32(ns->params.mcl); + id_ns->msrc =3D ns->params.msrc; + return 0; } =20 @@ -150,6 +155,9 @@ static void nvme_ns_realize(DeviceState *dev, Error **e= rrp) static Property nvme_ns_props[] =3D { DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf), DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0), + DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128), + DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128), + DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 255), DEFINE_PROP_END_OF_LIST(), }; =20 diff --git a/hw/block/nvme.c b/hw/block/nvme.c index f7f888402b06..82233f80541e 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -999,6 +999,109 @@ static void nvme_aio_discard_cb(void *opaque, int ret) nvme_enqueue_req_completion(nvme_cq(req), req); } =20 +struct nvme_copy_ctx { + int copies; + uint8_t *bounce; + uint32_t nlb; +}; + +struct nvme_copy_in_ctx { + NvmeRequest *req; + QEMUIOVector iov; +}; + +static void nvme_copy_cb(void *opaque, int ret) +{ + NvmeRequest *req =3D opaque; + NvmeNamespace *ns =3D req->ns; + struct nvme_copy_ctx *ctx =3D req->opaque; + + trace_pci_nvme_copy_cb(nvme_cid(req)); + + if (!ret) { + block_acct_done(blk_get_stats(ns->blkconf.blk), &req->acct); + } else { + block_acct_failed(blk_get_stats(ns->blkconf.blk), &req->acct); + nvme_aio_err(req, ret); + } + + g_free(ctx->bounce); + g_free(ctx); + + nvme_enqueue_req_completion(nvme_cq(req), req); +} + +static void nvme_copy_in_complete(NvmeRequest *req) +{ + NvmeNamespace *ns =3D req->ns; + NvmeCopyCmd *copy =3D (NvmeCopyCmd *)&req->cmd; + struct nvme_copy_ctx *ctx =3D req->opaque; + uint64_t sdlba =3D le64_to_cpu(copy->sdlba); + uint16_t status; + + trace_pci_nvme_copy_in_complete(nvme_cid(req)); + + block_acct_done(blk_get_stats(ns->blkconf.blk), &req->acct); + + status =3D nvme_check_bounds(ns, sdlba, ctx->nlb); + if (status) { + trace_pci_nvme_err_invalid_lba_range(sdlba, ctx->nlb, ns->id_ns.ns= ze); + req->status =3D status; + + g_free(ctx->bounce); + g_free(ctx); + + nvme_enqueue_req_completion(nvme_cq(req), req); + + return; + } + + qemu_iovec_init(&req->iov, 1); + qemu_iovec_add(&req->iov, ctx->bounce, nvme_l2b(ns, ctx->nlb)); + + block_acct_start(blk_get_stats(ns->blkconf.blk), &req->acct, + nvme_l2b(ns, ctx->nlb), BLOCK_ACCT_WRITE); + + req->aiocb =3D blk_aio_pwritev(ns->blkconf.blk, nvme_l2b(ns, sdlba), + &req->iov, 0, nvme_copy_cb, req); +} + +static void nvme_aio_copy_in_cb(void *opaque, int ret) +{ + struct nvme_copy_in_ctx *in_ctx =3D opaque; + NvmeRequest *req =3D in_ctx->req; + NvmeNamespace *ns =3D req->ns; + struct nvme_copy_ctx *ctx =3D req->opaque; + + qemu_iovec_destroy(&in_ctx->iov); + g_free(in_ctx); + + trace_pci_nvme_aio_copy_in_cb(nvme_cid(req)); + + if (ret) { + nvme_aio_err(req, ret); + } + + ctx->copies--; + + if (ctx->copies) { + return; + } + + if (req->status) { + block_acct_failed(blk_get_stats(ns->blkconf.blk), &req->acct); + + g_free(ctx->bounce); + g_free(ctx); + + nvme_enqueue_req_completion(nvme_cq(req), req); + + return; + } + + nvme_copy_in_complete(req); +} + static uint16_t nvme_dsm(NvmeCtrl *n, NvmeRequest *req) { NvmeNamespace *ns =3D req->ns; @@ -1072,6 +1175,122 @@ static uint16_t nvme_dsm(NvmeCtrl *n, NvmeRequest *= req) return status; } =20 +static uint16_t nvme_copy(NvmeCtrl *n, NvmeRequest *req) +{ + NvmeNamespace *ns =3D req->ns; + NvmeCopyCmd *copy =3D (NvmeCopyCmd *)&req->cmd; + g_autofree NvmeCopySourceRange *range =3D NULL; + + uint32_t cdw12 =3D le32_to_cpu(copy->cdw12); + uint16_t nr =3D (cdw12 & 0xff) + 1; + uint8_t format =3D (cdw12 >> 8) & 0xf; + uint32_t nlb =3D 0; + + uint8_t *bounce =3D NULL, *bouncep =3D NULL; + struct nvme_copy_ctx *ctx; + uint16_t status; + int i; + + trace_pci_nvme_copy(nvme_cid(req), nvme_nsid(ns), nr, format); + + if (!(n->id_ctrl.ocfs & (1 << format))) { + trace_pci_nvme_err_copy_invalid_format(format); + return NVME_INVALID_FIELD | NVME_DNR; + } + + if (nr > ns->id_ns.msrc + 1) { + return NVME_CMD_SIZE_LIMIT | NVME_DNR; + } + + range =3D g_new(NvmeCopySourceRange, nr); + + status =3D nvme_dma(n, (uint8_t *)range, nr * sizeof(NvmeCopySourceRan= ge), + DMA_DIRECTION_TO_DEVICE, req); + if (status) { + return status; + } + + for (i =3D 0; i < nr; i++) { + uint32_t _nlb =3D le16_to_cpu(range[i].nlb) + 1; + if (_nlb > le16_to_cpu(ns->id_ns.mssrl)) { + return NVME_CMD_SIZE_LIMIT | NVME_DNR; + } + + nlb +=3D _nlb; + } + + if (nlb > le32_to_cpu(ns->id_ns.mcl)) { + return NVME_CMD_SIZE_LIMIT | NVME_DNR; + } + + bounce =3D bouncep =3D g_malloc(nvme_l2b(ns, nlb)); + + for (i =3D 0; i < nr; i++) { + uint64_t slba =3D le64_to_cpu(range[i].slba); + uint32_t nlb =3D le16_to_cpu(range[i].nlb) + 1; + + status =3D nvme_check_bounds(ns, slba, nlb); + if (status) { + trace_pci_nvme_err_invalid_lba_range(slba, nlb, ns->id_ns.nsze= ); + goto free_bounce; + } + + if (NVME_ERR_REC_DULBE(ns->features.err_rec)) { + status =3D nvme_check_dulbe(ns, slba, nlb); + if (status) { + goto free_bounce; + } + } + } + + block_acct_start(blk_get_stats(ns->blkconf.blk), &req->acct, + nvme_l2b(ns, nlb), BLOCK_ACCT_READ); + + ctx =3D g_new(struct nvme_copy_ctx, 1); + + ctx->bounce =3D bounce; + ctx->nlb =3D nlb; + ctx->copies =3D 1; + + req->opaque =3D ctx; + + for (i =3D 0; i < nr; i++) { + uint64_t slba =3D le64_to_cpu(range[i].slba); + uint32_t nlb =3D le16_to_cpu(range[i].nlb) + 1; + + size_t len =3D nvme_l2b(ns, nlb); + int64_t offset =3D nvme_l2b(ns, slba); + + trace_pci_nvme_copy_source_range(slba, nlb); + + struct nvme_copy_in_ctx *in_ctx =3D g_new(struct nvme_copy_in_ctx,= 1); + in_ctx->req =3D req; + + qemu_iovec_init(&in_ctx->iov, 1); + qemu_iovec_add(&in_ctx->iov, bouncep, len); + + ctx->copies++; + + blk_aio_preadv(ns->blkconf.blk, offset, &in_ctx->iov, 0, + nvme_aio_copy_in_cb, in_ctx); + + bouncep +=3D len; + } + + /* account for the 1-initialization */ + ctx->copies--; + + if (!ctx->copies) { + nvme_copy_in_complete(req); + } + + return NVME_NO_COMPLETE; + +free_bounce: + g_free(bounce); + return status; +} + static uint16_t nvme_flush(NvmeCtrl *n, NvmeRequest *req) { block_acct_start(blk_get_stats(req->ns->blkconf.blk), &req->acct, 0, @@ -1203,6 +1422,8 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest = *req) return nvme_rw(n, req); case NVME_CMD_DSM: return nvme_dsm(n, req); + case NVME_CMD_COPY: + return nvme_copy(n, req); default: trace_pci_nvme_err_invalid_opc(req->cmd.opcode); return NVME_INVALID_OPCODE | NVME_DNR; @@ -2927,9 +3148,11 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *p= ci_dev) id->cqes =3D (0x4 << 4) | 0x4; id->nn =3D cpu_to_le32(n->num_namespaces); id->oncs =3D cpu_to_le16(NVME_ONCS_WRITE_ZEROES | NVME_ONCS_TIMESTAMP | - NVME_ONCS_FEATURES | NVME_ONCS_DSM); + NVME_ONCS_FEATURES | NVME_ONCS_DSM | + NVME_ONCS_COPY); =20 id->vwc =3D 0x1; + id->ocfs =3D cpu_to_le16(NVME_OCFS_COPY_FORMAT_0); id->sgls =3D cpu_to_le32(NVME_CTRL_SGLS_SUPPORT_NO_ALIGN | NVME_CTRL_SGLS_BITBUCKET); =20 diff --git a/hw/block/trace-events b/hw/block/trace-events index 1ffe0b3f76b5..27e78b156d9b 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -42,11 +42,16 @@ pci_nvme_io_cmd(uint16_t cid, uint32_t nsid, uint16_t s= qid, uint8_t opcode, cons pci_nvme_admin_cmd(uint16_t cid, uint16_t sqid, uint8_t opcode, const char= *opname) "cid %"PRIu16" sqid %"PRIu16" opc 0x%"PRIx8" opname '%s'" pci_nvme_rw(uint16_t cid, const char *verb, uint32_t nsid, uint32_t nlb, u= int64_t count, uint64_t lba) "cid %"PRIu16" opname '%s' nsid %"PRIu32" nlb = %"PRIu32" count %"PRIu64" lba 0x%"PRIx64"" pci_nvme_rw_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'" +pci_nvme_copy(uint16_t cid, uint32_t nsid, uint16_t nr, uint8_t format) "c= id %"PRIu16" nsid %"PRIu32" nr %"PRIu16" format 0x%"PRIx8"" +pci_nvme_copy_source_range(uint64_t slba, uint32_t nlb) "slba 0x%"PRIx64" = nlb %"PRIu32"" +pci_nvme_copy_in_complete(uint16_t cid) "cid %"PRIu16"" +pci_nvme_copy_cb(uint16_t cid) "cid %"PRIu16"" pci_nvme_write_zeroes(uint16_t cid, uint32_t nsid, uint64_t slba, uint32_t= nlb) "cid %"PRIu16" nsid %"PRIu32" slba %"PRIu64" nlb %"PRIu32"" pci_nvme_block_status(int64_t offset, int64_t bytes, int64_t pnum, int ret= , bool zeroed) "offset %"PRId64" bytes %"PRId64" pnum %"PRId64" ret 0x%x ze= roed %d" pci_nvme_dsm(uint16_t cid, uint32_t nsid, uint32_t nr, uint32_t attr) "cid= %"PRIu16" nsid %"PRIu32" nr %"PRIu32" attr 0x%"PRIx32"" pci_nvme_dsm_deallocate(uint16_t cid, uint32_t nsid, uint64_t slba, uint32= _t nlb) "cid %"PRIu16" nsid %"PRIu32" slba %"PRIu64" nlb %"PRIu32"" pci_nvme_aio_discard_cb(uint16_t cid) "cid %"PRIu16"" +pci_nvme_aio_copy_in_cb(uint16_t cid) "cid %"PRIu16"" pci_nvme_create_sq(uint64_t addr, uint16_t sqid, uint16_t cqid, uint16_t q= size, uint16_t qflags) "create submission queue, addr=3D0x%"PRIx64", sqid= =3D%"PRIu16", cqid=3D%"PRIu16", qsize=3D%"PRIu16", qflags=3D%"PRIu16"" pci_nvme_create_cq(uint64_t addr, uint16_t cqid, uint16_t vector, uint16_t= size, uint16_t qflags, int ien) "create completion queue, addr=3D0x%"PRIx6= 4", cqid=3D%"PRIu16", vector=3D%"PRIu16", qsize=3D%"PRIu16", qflags=3D%"PRI= u16", ien=3D%d" pci_nvme_del_sq(uint16_t qid) "deleting submission queue sqid=3D%"PRIu16"" @@ -97,6 +102,7 @@ pci_nvme_err_addr_read(uint64_t addr) "addr 0x%"PRIx64"" pci_nvme_err_addr_write(uint64_t addr) "addr 0x%"PRIx64"" pci_nvme_err_cfs(void) "controller fatal status" pci_nvme_err_aio(uint16_t cid, const char *errname, uint16_t status) "cid = %"PRIu16" err '%s' status 0x%"PRIx16"" +pci_nvme_err_copy_invalid_format(uint8_t format) "format 0x%"PRIx8"" pci_nvme_err_invalid_sgld(uint16_t cid, uint8_t typ) "cid %"PRIu16" type 0= x%"PRIx8"" pci_nvme_err_invalid_num_sgld(uint16_t cid, uint8_t typ) "cid %"PRIu16" ty= pe 0x%"PRIx8"" pci_nvme_err_invalid_sgl_excess_length(uint16_t cid) "cid %"PRIu16"" --=20 2.29.2