From nobody Wed Nov 5 22:33:20 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153751909001724.822780547145385; Fri, 21 Sep 2018 01:38:10 -0700 (PDT) Received: from localhost ([::1]:54468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g3Gwy-0004RV-QJ for importer@patchew.org; Fri, 21 Sep 2018 04:38:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47636) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g3Gf8-0004BU-Ju for qemu-devel@nongnu.org; Fri, 21 Sep 2018 04:19:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g3Gf3-0003X9-Hh for qemu-devel@nongnu.org; Fri, 21 Sep 2018 04:19:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52752) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g3Gex-0003DK-3A; Fri, 21 Sep 2018 04:19:31 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5105330022E8; Fri, 21 Sep 2018 08:19:30 +0000 (UTC) Received: from laptop.redhat.com (ovpn-117-87.ams2.redhat.com [10.36.117.87]) by smtp.corp.redhat.com (Postfix) with ESMTP id 041CB7D665; Fri, 21 Sep 2018 08:19:27 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org Date: Fri, 21 Sep 2018 10:17:58 +0200 Message-Id: <20180921081819.9203-8-eric.auger@redhat.com> In-Reply-To: <20180921081819.9203-1-eric.auger@redhat.com> References: <20180921081819.9203-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 21 Sep 2018 08:19:30 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v2 07/28] hw/vfio/common: Refactor container initialization 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: yi.l.liu@intel.com, cdall@kernel.org, mst@redhat.com, jean-philippe.brucker@arm.com, peterx@redhat.com, alex.williamson@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" To prepare for testing yet another extension, let's refactor the code. We introduce vfio_iommu_get_type() helper which selects the richest API (v2 first). Then vfio_init_container() does the SET_CONTAINER and SET_IOMMU ioctl calls. So we end up with a switch/case on the iommu_type which should be a little bit more readable when introducing the NESTING extension check. Also ioctl's get called once per iommu_type. Signed-off-by: Eric Auger Reviewed-by: Greg Kurz --- hw/vfio/common.c | 102 ++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 7c185e5a2e..53b8f773cc 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1036,12 +1036,58 @@ static void vfio_put_address_space(VFIOAddressSpace= *space) } } =20 +/* + * vfio_iommu_get_type - selects the richest iommu_type (v2 first) + * nested only is selected if requested by @force_nested + */ +static int vfio_iommu_get_type(VFIOContainer *container, + Error **errp) +{ + int fd =3D container->fd; + + if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) { + return VFIO_TYPE1v2_IOMMU; + } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) { + return VFIO_TYPE1_IOMMU; + } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) { + return VFIO_SPAPR_TCE_v2_IOMMU; + } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) { + return VFIO_SPAPR_TCE_IOMMU; + } else { + error_setg(errp, "No available IOMMU models"); + return -EINVAL; + } +} + +static int vfio_init_container(VFIOContainer *container, int group_fd, + int iommu_type, Error **errp) +{ + int ret; + + ret =3D ioctl(group_fd, VFIO_GROUP_SET_CONTAINER, &container->fd); + if (ret) { + error_setg_errno(errp, errno, "failed to set group container"); + return -errno; + } + + ret =3D ioctl(container->fd, VFIO_SET_IOMMU, iommu_type); + if (ret) { + error_setg_errno(errp, errno, "failed to set iommu for container"); + return -errno; + } + container->iommu_type =3D iommu_type; + return 0; +} + static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, Error **errp) { VFIOContainer *container; int ret, fd; VFIOAddressSpace *space; + int iommu_type; + bool v2 =3D false; + =20 space =3D vfio_get_address_space(as); =20 @@ -1101,23 +1147,20 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as, container->fd =3D fd; QLIST_INIT(&container->giommu_list); QLIST_INIT(&container->hostwin_list); - if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) || - ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) { - bool v2 =3D !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU); + + iommu_type =3D vfio_iommu_get_type(container, errp); + if (iommu_type < 0) { + goto free_container_exit; + } + + switch (iommu_type) { + case VFIO_TYPE1v2_IOMMU: + case VFIO_TYPE1_IOMMU: + { struct vfio_iommu_type1_info info; =20 - ret =3D ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd); + ret =3D vfio_init_container(container, group->fd, iommu_type, errp= ); if (ret) { - error_setg_errno(errp, errno, "failed to set group container"); - ret =3D -errno; - goto free_container_exit; - } - - container->iommu_type =3D v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOM= MU; - ret =3D ioctl(fd, VFIO_SET_IOMMU, container->iommu_type); - if (ret) { - error_setg_errno(errp, errno, "failed to set iommu for contain= er"); - ret =3D -errno; goto free_container_exit; } =20 @@ -1137,28 +1180,16 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as, } vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes); container->pgsizes =3D info.iova_pgsizes; - } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) || - ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) { + break; + } + case VFIO_SPAPR_TCE_v2_IOMMU: + v2 =3D true; + case VFIO_SPAPR_TCE_IOMMU: + { struct vfio_iommu_spapr_tce_info info; - bool v2 =3D !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IO= MMU); =20 - ret =3D ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd); + ret =3D vfio_init_container(container, group->fd, iommu_type, errp= ); if (ret) { - error_setg_errno(errp, errno, "failed to set group container"); - ret =3D -errno; - goto free_container_exit; - } - container->iommu_type =3D - v2 ? VFIO_SPAPR_TCE_v2_IOMMU : VFIO_SPAPR_TCE_IOMMU; - ret =3D ioctl(fd, VFIO_SET_IOMMU, container->iommu_type); - if (ret) { - container->iommu_type =3D VFIO_SPAPR_TCE_IOMMU; - v2 =3D false; - ret =3D ioctl(fd, VFIO_SET_IOMMU, container->iommu_type); - } - if (ret) { - error_setg_errno(errp, errno, "failed to set iommu for contain= er"); - ret =3D -errno; goto free_container_exit; } =20 @@ -1222,10 +1253,7 @@ static int vfio_connect_container(VFIOGroup *group, = AddressSpace *as, info.dma32_window_size - 1, 0x1000); } - } else { - error_setg(errp, "No available IOMMU models"); - ret =3D -EINVAL; - goto free_container_exit; + } } =20 vfio_kvm_device_add_group(group); --=20 2.17.1