From patchwork Wed May 4 11:54:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 9012851 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 31A20BF29F for ; Wed, 4 May 2016 11:57:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1076D2039D for ; Wed, 4 May 2016 11:57:33 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0262720396 for ; Wed, 4 May 2016 11:57:32 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1axvPX-0005TT-Ab; Wed, 04 May 2016 11:56:11 +0000 Received: from mail-wm0-x22c.google.com ([2a00:1450:400c:c09::22c]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1axvOc-0003OX-2i for linux-arm-kernel@lists.infradead.org; Wed, 04 May 2016 11:55:16 +0000 Received: by mail-wm0-x22c.google.com with SMTP id e201so184510628wme.0 for ; Wed, 04 May 2016 04:54:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zzvAOQkwghmbZ23ZFQZiY61ZbF7jmjFMSX3KiJfeE9I=; b=YnPrffxHGSQcXFxdEALDnIKlMCd+d5zxHUscZ2evQNmF2wJEN6g3WEuZUqYXV1mhfM pTMgQGuuXRI3TDiGE/YGou83ues0Q36o6M/6mQGrRo1CR7NaqmTYqeKGq5jDVpQdUYrE GzIcW7qi7HNAvz9yB8giTRwNbsIhen92sTxWw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zzvAOQkwghmbZ23ZFQZiY61ZbF7jmjFMSX3KiJfeE9I=; b=b+NMykQCQA2tE2aZWxfcQ9xasBxDIMF2hr8/UkSzYuM+3a22khYgVFIqmZEGyJiBKh HAiBZqn9HgmwiLnn9nZBJDs/hEjkzeQCli4G5GJItBFfwmUZOzNCwav/ynFlERtDMWn4 t29MBATTY1sEoWXhCZPMC3rRiZnwAReaWr1UwOE2Syqnc5kDqaKQwyyNegV2r+BGBi/k qEANtGBPFm5gsE4at07XVtncAH0B5wTaDg01N5sTg2mBDR8c/XPxGY1obuQNt7WCwXNL Gu5+6J5gV7cW04Q2JpiwWFz7dbrPKp8CQz5BUYRcrM86n9pptokRNRGb3QJO623DEoFO 5axA== X-Gm-Message-State: AOPr4FUlf+U/5u8CdCzwxISrTeS3eSJF5QVQoQrXQZ1fRaHdlQ5tSdyFMXkf1LO+BbRrLkju X-Received: by 10.194.95.40 with SMTP id dh8mr8801117wjb.146.1462362896693; Wed, 04 May 2016 04:54:56 -0700 (PDT) Received: from new-host-61.home (LMontsouris-657-1-37-90.w80-11.abo.wanadoo.fr. [80.11.198.90]) by smtp.gmail.com with ESMTPSA id ck9sm3816623wjc.22.2016.05.04.04.54.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 May 2016 04:54:55 -0700 (PDT) From: Eric Auger To: eric.auger@st.com, eric.auger@linaro.org, robin.murphy@arm.com, alex.williamson@redhat.com, will.deacon@arm.com, joro@8bytes.org, tglx@linutronix.de, jason@lakedaemon.net, marc.zyngier@arm.com, christoffer.dall@linaro.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v9 7/7] vfio/type1: return MSI geometry through VFIO_IOMMU_GET_INFO capability chains Date: Wed, 4 May 2016 11:54:18 +0000 Message-Id: <1462362858-2925-8-git-send-email-eric.auger@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1462362858-2925-1-git-send-email-eric.auger@linaro.org> References: <1462362858-2925-1-git-send-email-eric.auger@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160504_045514_590831_F6034226 X-CRM114-Status: GOOD ( 22.75 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: julien.grall@arm.com, patches@linaro.org, Jean-Philippe.Brucker@arm.com, p.fedin@samsung.com, linux-kernel@vger.kernel.org, Bharat.Bhushan@freescale.com, iommu@lists.linux-foundation.org, pranav.sawargaonkar@gmail.com, yehuday@marvell.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch allows the user-space to retrieve the MSI geometry. The implementation is based on capability chains, now also added to VFIO_IOMMU_GET_INFO. The returned info comprise: - whether the MSI IOVA are constrained to a reserved range (x86 case) and in the positive, the start/end of the aperture, - or whether the IOVA aperture need to be set by the userspace. In that case, the size and alignment of the IOVA region to be provided are returned. In case the userspace must provide the IOVA range, we currently return an arbitrary number of IOVA pages (16), supposed to fulfill the needs of current ARM platforms. This may be deprecated by a more sophisticated computation later on. Signed-off-by: Eric Auger --- v8 -> v9: - use iommu_msi_supported flag instead of programmable - replace IOMMU_INFO_REQUIRE_MSI_MAP flag by a more sophisticated capability chain, reporting the MSI geometry v7 -> v8: - use iommu_domain_msi_geometry v6 -> v7: - remove the computation of the number of IOVA pages to be provisionned. This number depends on the domain/group/device topology which can dynamically change. Let's rely instead rely on an arbitrary max depending on the system v4 -> v5: - move msi_info and ret declaration within the conditional code v3 -> v4: - replace former vfio_domains_require_msi_mapping by more complex computation of MSI mapping requirements, especially the number of pages to be provided by the user-space. - reword patch title RFC v1 -> v1: - derived from [RFC PATCH 3/6] vfio: Extend iommu-info to return MSIs automap state - renamed allow_msi_reconfig into require_msi_mapping - fixed VFIO_IOMMU_GET_INFO --- drivers/vfio/vfio_iommu_type1.c | 69 +++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/vfio.h | 30 +++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 2fc8197..841360b 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1134,6 +1134,50 @@ static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu) return ret; } +static int compute_msi_geometry_caps(struct vfio_iommu *iommu, + struct vfio_info_cap *caps) +{ + struct vfio_iommu_type1_info_cap_msi_geometry *vfio_msi_geometry; + struct iommu_domain_msi_geometry msi_geometry; + struct vfio_info_cap_header *header; + struct vfio_domain *d; + bool mapping_required; + size_t size; + + mutex_lock(&iommu->lock); + /* All domains have same require_msi_map property, pick first */ + d = list_first_entry(&iommu->domain_list, struct vfio_domain, next); + iommu_domain_get_attr(d->domain, DOMAIN_ATTR_MSI_GEOMETRY, + &msi_geometry); + mapping_required = msi_geometry.iommu_msi_supported; + + mutex_unlock(&iommu->lock); + + size = sizeof(*vfio_msi_geometry); + header = vfio_info_cap_add(caps, size, + VFIO_IOMMU_TYPE1_INFO_CAP_MSI_GEOMETRY, 1); + + if (IS_ERR(header)) + return PTR_ERR(header); + + vfio_msi_geometry = container_of(header, + struct vfio_iommu_type1_info_cap_msi_geometry, + header); + + vfio_msi_geometry->reserved = !mapping_required; + if (vfio_msi_geometry->reserved) { + vfio_msi_geometry->aperture_start = msi_geometry.aperture_start; + vfio_msi_geometry->aperture_end = msi_geometry.aperture_end; + return 0; + } + + vfio_msi_geometry->alignment = 1 << __ffs(vfio_pgsize_bitmap(iommu)); + /* we currently report the need for an arbitray number of 16 pages */ + vfio_msi_geometry->size = 16 * vfio_msi_geometry->alignment; + + return 0; +} + static long vfio_iommu_type1_ioctl(void *iommu_data, unsigned int cmd, unsigned long arg) { @@ -1155,6 +1199,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, } } else if (cmd == VFIO_IOMMU_GET_INFO) { struct vfio_iommu_type1_info info; + struct vfio_info_cap caps = { .buf = NULL, .size = 0 }; + int ret; minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes); @@ -1168,6 +1214,29 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, info.iova_pgsizes = vfio_pgsize_bitmap(iommu); + ret = compute_msi_geometry_caps(iommu, &caps); + if (ret) + return ret; + + if (caps.size) { + info.flags |= VFIO_IOMMU_INFO_CAPS; + if (info.argsz < sizeof(info) + caps.size) { + info.argsz = sizeof(info) + caps.size; + info.cap_offset = 0; + } else { + vfio_info_cap_shift(&caps, sizeof(info)); + if (copy_to_user((void __user *)arg + + sizeof(info), caps.buf, + caps.size)) { + kfree(caps.buf); + return -EFAULT; + } + info.cap_offset = sizeof(info); + } + + kfree(caps.buf); + } + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 4a9dbc2..0ff6a8d 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -488,7 +488,33 @@ struct vfio_iommu_type1_info { __u32 argsz; __u32 flags; #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */ - __u64 iova_pgsizes; /* Bitmap of supported page sizes */ +#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */ + __u32 cap_offset; /* Offset within info struct of first cap */ + __u64 iova_pgsizes; /* Bitmap of supported page sizes */ +}; + +#define VFIO_IOMMU_TYPE1_INFO_CAP_MSI_GEOMETRY 1 + +/* + * The MSI geometry capability allows to report the MSI IOVA geometry: + * - either the MSI IOVAs are constrained within a reserved IOVA aperture + * whose boundaries are given by [@aperture_start, @aperture_end]. + * this is typically the case on x86 host. The userspace is not allowed + * to map userspace memory at IOVAs intersecting this range using + * VFIO_IOMMU_MAP_DMA. + * - or the MSI IOVAs are not requested to belong to any reserved range; + * in that case the userspace must provide an IOVA window characterized by + * @size and @alignment using VFIO_IOMMU_MAP_DMA with RESERVED_MSI_IOVA flag. + */ +struct vfio_iommu_type1_info_cap_msi_geometry { + struct vfio_info_cap_header header; + bool reserved; /* Are MSI IOVAs within a reserved aperture? */ + /* reserved */ + __u64 aperture_start; + __u64 aperture_end; + /* not reserved */ + __u64 size; /* IOVA aperture size in bytes the userspace must provide */ + __u64 alignment; /* alignment of the window, in bytes */ }; #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) @@ -503,6 +529,8 @@ struct vfio_iommu_type1_info { * IOVA region that will be used on some platforms to map the host MSI frames. * In that specific case, vaddr is ignored. Once registered, an MSI reserved * IOVA region stays until the container is closed. + * The requirement for provisioning such reserved IOVA range can be checked by + * checking the VFIO_IOMMU_TYPE1_INFO_CAP_MSI_GEOMETRY capability. */ struct vfio_iommu_type1_dma_map { __u32 argsz;