From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44C50C2BA2B for ; Wed, 15 Apr 2020 06:06:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1925320737 for ; Wed, 15 Apr 2020 06:06:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1925320737 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=irrelevant.dk Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:43742 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jObBv-00028K-6I for qemu-devel@archiver.kernel.org; Wed, 15 Apr 2020 02:06:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35545) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jOaz0-0002qD-Lu for qemu-devel@nongnu.org; Wed, 15 Apr 2020 01:53:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jOayy-0002px-Ox for qemu-devel@nongnu.org; Wed, 15 Apr 2020 01:53:10 -0400 Received: from charlie.dont.surf ([128.199.63.193]:47568) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jOayv-0002Zs-2A; Wed, 15 Apr 2020 01:53:05 -0400 Received: from apples.local (80-167-98-190-cable.dk.customer.tdc.net [80.167.98.190]) by charlie.dont.surf (Postfix) with ESMTPSA id 07A86BFD9F; Wed, 15 Apr 2020 05:52:28 +0000 (UTC) From: Klaus Jensen To: qemu-block@nongnu.org Subject: [PATCH v7 30/48] nvme: verify validity of prp lists in the cmb Date: Wed, 15 Apr 2020 07:51:22 +0200 Message-Id: <20200415055140.466900-31-its@irrelevant.dk> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200415055140.466900-1-its@irrelevant.dk> References: <20200415055140.466900-1-its@irrelevant.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 128.199.63.193 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 , Beata Michalska , Klaus Jensen , qemu-devel@nongnu.org, Max Reitz , Klaus Jensen , Keith Busch , Javier Gonzalez , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Klaus Jensen Before this patch the device already supported this, but it did not check for the validity of it nor announced the support in the LISTS field. If some of the PRPs in a PRP list are in the CMB, then ALL entries must be there. This patch makes sure that is verified as well as properly announcing support for PRP lists in the CMB. Signed-off-by: Klaus Jensen Reviewed-by: Maxim Levitsky --- hw/block/nvme.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 1f4ce48b9cbb..3e5e99644a4e 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -218,6 +218,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, QEMUSGList = *qsg, QEMUIOVector *iov, trans_len =3D MIN(len, trans_len); int num_prps =3D (len >> n->page_bits) + 1; uint16_t status; + bool prp_list_in_cmb =3D false; =20 trace_nvme_dev_map_prp(nvme_cid(req), trans_len, len, prp1, prp2, num_prps); @@ -245,11 +246,16 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, QEMUSGLis= t *qsg, QEMUIOVector *iov, status =3D NVME_INVALID_FIELD | NVME_DNR; goto unmap; } + if (len > n->page_size) { uint64_t prp_list[n->max_prp_ents]; uint32_t nents, prp_trans; int i =3D 0; =20 + if (nvme_addr_is_cmb(n, prp2)) { + prp_list_in_cmb =3D true; + } + nents =3D (len + n->page_size - 1) >> n->page_bits; prp_trans =3D MIN(n->max_prp_ents, nents) * sizeof(uint64_t)= ; nvme_addr_read(n, prp2, (void *)prp_list, prp_trans); @@ -263,6 +269,11 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, QEMUSGList= *qsg, QEMUIOVector *iov, goto unmap; } =20 + if (prp_list_in_cmb !=3D nvme_addr_is_cmb(n, prp_ent= )) { + status =3D NVME_INVALID_USE_OF_CMB | NVME_DNR; + goto unmap; + } + i =3D 0; nents =3D (len + n->page_size - 1) >> n->page_bits; prp_trans =3D MIN(n->max_prp_ents, nents) * sizeof(u= int64_t); @@ -282,6 +293,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, QEMUSGList = *qsg, QEMUIOVector *iov, if (status) { goto unmap; } + len -=3D trans_len; i++; } @@ -1953,7 +1965,7 @@ static void nvme_init_cmb(NvmeCtrl *n, PCIDevice *p= ci_dev) =20 NVME_CMBSZ_SET_SQS(n->bar.cmbsz, 1); NVME_CMBSZ_SET_CQS(n->bar.cmbsz, 0); - NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 0); + NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 1); NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 1); NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 1); NVME_CMBSZ_SET_SZU(n->bar.cmbsz, 2); --=20 2.26.0