From patchwork Sun Feb 14 14:35:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 12087235 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=-16.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,GUARANTEED_100_PERCENT,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,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 4FC70C433DB for ; Sun, 14 Feb 2021 14:35:19 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (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 05D9C64DC3 for ; Sun, 14 Feb 2021 14:35:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 05D9C64DC3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=xen.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.84920.159186 (Exim 4.92) (envelope-from ) id 1lBIUQ-0007Br-Db; Sun, 14 Feb 2021 14:35:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 84920.159186; Sun, 14 Feb 2021 14:35:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lBIUQ-0007Bk-AU; Sun, 14 Feb 2021 14:35:10 +0000 Received: by outflank-mailman (input) for mailman id 84920; Sun, 14 Feb 2021 14:35:08 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lBIUO-0007Be-Q4 for xen-devel@lists.xenproject.org; Sun, 14 Feb 2021 14:35:08 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lBIUO-0004DK-9b; Sun, 14 Feb 2021 14:35:08 +0000 Received: from 54-240-197-235.amazon.com ([54.240.197.235] helo=ufe34d9ed68d054.ant.amazon.com) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lBIUN-00057D-WE; Sun, 14 Feb 2021 14:35:08 +0000 X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Message-Id:Date:Subject:Cc:To:From; bh=m/LlNL0TamjvVVErh/pPovK2MwMDVTxbRIY3ju8BM/k=; b=4DbgDOufF2y1YcJUTFqmEFkZkM APBxrcLN5LfRljx07JdtnDU0WjYWeC11Cr2DMH+Xha6Ru0FegqY3c6RJHHCJW7LUqamltDQ9YgAso rigAa87oBUkROeFUb4djd9/CcFPFLVa2ZMqCCrdmrMdBrpEXkY3JT/BjKasggs6Iu+AI=; From: Julien Grall To: xen-devel@lists.xenproject.org Cc: julien@xen.org, Julien Grall , Stefano Stabellini , Volodymyr Babchuk , Rahul Singh Subject: [PATCH] xen/iommu: arm: Don't insert an IOMMU mapping when the grantee and granter... Date: Sun, 14 Feb 2021 14:35:04 +0000 Message-Id: <20210214143504.23099-1-julien@xen.org> X-Mailer: git-send-email 2.17.1 From: Julien Grall ... are the same. When the IOMMU is enabled and the domain is direct mapped (e.g. Dom0), Xen will insert a 1:1 mapping for each grant mapping in the P2M to allow DMA. This works quite well when the grantee and granter and not the same because the GFN in the P2M should not be mapped. However, if they are the same, we will overwrite the mapping. Worse, it will be completely removed when the grant is unmapped. As the domain is direct mapped, a 1:1 mapping should always present in the P2M. This is not 100% guaranteed if the domain decides to mess with the P2M. However, such domain would already end up in trouble as the page would be soon be freed (when the last reference dropped). Add an additional check in arm_iommu_{,un}map_page() to check whether the page belongs to the domain. If it is belongs to it, then ignore the request. Note that we don't need to hold an extra reference on the page because the grant code will already do it for us. Reported-by: Rahul Singh Fixes: 552710b38863 ("xen/arm: grant: Add another entry to map MFN 1:1 in dom0 p2m") Signed-off-by: Julien Grall Reviewed-by: Rahul Singh Tested-by: Rahul Singh --- This is a candidate for 4.15. Without the patch, it would not be possible to get the frontend and backend in the same domain (useful when trying to map the guest block device in dom0). --- xen/drivers/passthrough/arm/iommu_helpers.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/xen/drivers/passthrough/arm/iommu_helpers.c b/xen/drivers/passthrough/arm/iommu_helpers.c index a36e2b8e6c42..35a813308b8c 100644 --- a/xen/drivers/passthrough/arm/iommu_helpers.c +++ b/xen/drivers/passthrough/arm/iommu_helpers.c @@ -53,6 +53,17 @@ int __must_check arm_iommu_map_page(struct domain *d, dfn_t dfn, mfn_t mfn, t = (flags & IOMMUF_writable) ? p2m_iommu_map_rw : p2m_iommu_map_ro; + /* + * The granter and grantee can be the same domain. In normal + * condition, the 1:1 mapping should already present in the P2M so + * we want to avoid overwriting it. + * + * Note that there is no guarantee the 1:1 mapping will be present + * if the domain decides to mess with the P2M. + */ + if ( page_get_owner(mfn_to_page(mfn)) == d ) + return 0; + /* * The function guest_physmap_add_entry replaces the current mapping * if there is already one... @@ -71,6 +82,13 @@ int __must_check arm_iommu_unmap_page(struct domain *d, dfn_t dfn, if ( !is_domain_direct_mapped(d) ) return -EINVAL; + /* + * When the granter and grantee are the same, we didn't insert a + * mapping. So ignore the unmap request. + */ + if ( page_get_owner(mfn_to_page(_mfn(dfn_x(dfn)))) == d ) + return 0; + return guest_physmap_remove_page(d, _gfn(dfn_x(dfn)), _mfn(dfn_x(dfn)), 0); }