From patchwork Mon Apr 3 10:53:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 96609 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp40094qgd; Mon, 3 Apr 2017 03:55:55 -0700 (PDT) X-Received: by 10.36.107.214 with SMTP id v205mr9173547itc.65.1491216955494; Mon, 03 Apr 2017 03:55:55 -0700 (PDT) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id p5si14458161iod.190.2017.04.03.03.55.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Apr 2017 03:55:55 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cuzcA-00088R-MS; Mon, 03 Apr 2017 10:53:38 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cuzc9-00088L-Ej for xen-devel@lists.xen.org; Mon, 03 Apr 2017 10:53:37 +0000 Received: from [85.158.143.35] by server-10.bemta-6.messagelabs.com id 6B/91-13192-0B922E85; Mon, 03 Apr 2017 10:53:36 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRWlGSWpSXmKPExsVysyfVTXeD5qM Ig3X3hCyWfFzM4sDocXT3b6YAxijWzLyk/IoE1oz395azFRzRrFhzbiZ7A+MaxS5GTg4hgY2M Es9fx3YxcgHZpxklGmbdZQdJsAloStz5/IkJxBYRkJa49vkyI4jNLJAv0Xl9OpgtLJAlMWv1J VYQm0VAVeJo7zEwm1fAQuLOr4tgvRIC8hK72i6yTmDkXMDIsIpRozi1qCy1SNfIQC+pKDM9oy Q3MTNH19DATC83tbg4MT01JzGpWC85P3cTI9BfDECwg/HXsoBDjJIcTEqivB8UHkUI8SXlp1R mJBZnxBeV5qQWH2KU4eBQkuAtVgfKCRalpqdWpGXmAAMHJi3BwaMkwjsbJM1bXJCYW5yZDpE6 xajLMWf27jdMQix5+XmpUuK8QhpARQIgRRmleXAjYEF8iVFWSpiXEegoIZ6C1KLczBJU+VeM4 hyMSsK8OSCreDLzSuA2vQI6ggnoiCd3HoIcUZKIkJJqYMz33yzxtE4tL9PK7Osjf7Pdm1tV30 7es/ObWf3no5v15nR5n9t74Jj9sV75CuldLFWXGOY/SptzhNFtS0XVmXBLlzBN3moWu4U7LMP DJ//JO8DYuvjG3LPim3MeJ2bFXNMo2v1HTJlHs1x7Q/WUQ0qNbftlOZdMy/tyoCXr3aRTNpOf 7GBhn6TEUpyRaKjFXFScCAA2leUUXQIAAA== X-Env-Sender: julien.grall@arm.com X-Msg-Ref: server-13.tower-21.messagelabs.com!1491216815!55896167!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 28429 invoked from network); 3 Apr 2017 10:53:36 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-13.tower-21.messagelabs.com with SMTP; 3 Apr 2017 10:53:36 -0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5F6C82B; Mon, 3 Apr 2017 03:53:35 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.218.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9C3DD3F23B; Mon, 3 Apr 2017 03:53:34 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Date: Mon, 3 Apr 2017 11:53:23 +0100 Message-Id: <20170403105323.7037-1-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 Cc: Julien Grall , sstabellini@kernel.org, Shanker Donthineni Subject: [Xen-devel] [PATCH for-4.9 v2] xen/arm: acpi: Map MMIO on fault in stage-2 page table for the hardware domain X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" When booting using ACPI, not all MMIOs can be discovered by parsing the static tables or the UEFI memory map. A lot of them will be described in the DSDT. However, Xen does not have an AML parser which requires us to find a different approach. During the first discussions on supporting ACPI (see design doc [1]), it was decided to rely on the hardware domain to make a request to the hypervisor to map the MMIO region in stage-2 page table before accessing it. This approach works fine if the OS has limited hooks to modify the page tables. In the case of Linux kernel, notifiers have been added to map the MMIO regions when adding a new AMBA/platform device. Whilst this is covering most of the MMIOs, some of them (e.g OpRegion, ECAM...) are not related to a specific device or the driver is not using the AMBA/platform API. So more hooks would need to be added in the code. Various approaches have been discussed (see [2]), one of them was to create stage-2 mappings seamlessly in Xen upon hardware memory faults. This approach was first ruled out because it relies on the hardware domain to probe the region before any use. So this would not work when DMA'ing to another device's MMIO region when the device is protected by an SMMU. It has been pointed out that this is a limited use case compare to DMA'ing between MMIO and RAM. This patch implements this approach. All MMIOs region will be mapped in stage-2 using p2m_mmio_direct_c (i.e normal memory outer and inner write-back cacheable). The stage-1 page table will be in control of the memory attribute. This is fine because the hardware domain is a trusted domain. Note that MMIO will only be mapped on a data abort fault. It is assumed that it will not be possible to execute code from MMIO (p2m_mmio_direct_c will forbid that). As mentioned above, this solution will cover most of the cases. If a platform requires to do DMA'ing to another device's MMIO region without any access performed by the OS. Then it will be expected to have specific platform code in the hypervisor to map the MMIO at boot time or the OS to use the existing hypercalls (i.e XENMEM_add_to_add_physmap{,_batch}) before any access. [1] https://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html [2] https://marc.info/?l=linux-arm-kernel&m=148469169210500&w=2 Signed-off-by: Julien Grall Tested-by: Shanker Donthineni Reviewed-by: Stefano Stabellini --- This patch is a candidate for Xen 4.9. Whilst the last posting date was few days ago, I think it would be good to have this patch in the next release. Although ACPI support for ARM64 is still a technical preview, it would help servers to test Xen upstream on their platform with ACPI and provide feedback on missing features. All the code is gated by !acpi_disabled and therefore will not be executed on when using Device Tree. RM hat on: I will leave the decision to Stefano. Changes in v2: - Use is_hardware_domain rather than open-coding it - Add Stefano's reviewed-by - Add Shanker's tested-by --- xen/arch/arm/traps.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 614501f761..89a5f3b7c7 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include /* The base of the stack must always be double-word aligned, which means * that both the kernel half of struct cpu_user_regs (which is pushed in @@ -2534,6 +2536,35 @@ static bool try_handle_mmio(struct cpu_user_regs *regs, return !!handle_mmio(info); } +/* + * When using ACPI, most of the MMIO regions will be mapped on-demand + * in stage-2 page tables for the hardware domain because Xen is not + * able to know from the EFI memory map the MMIO regions. + */ +static bool try_map_mmio(gfn_t gfn) +{ + struct domain *d = current->domain; + + /* For the hardware domain, all MMIOs are mapped with GFN == MFN */ + mfn_t mfn = _mfn(gfn_x(gfn)); + + /* + * Device-Tree should already have everything mapped when building + * the hardware domain. + */ + if ( acpi_disabled ) + return false; + + if ( !is_hardware_domain(d) ) + return false; + + /* The hardware domain can only map permitted MMIO regions */ + if ( !iomem_access_permitted(d, mfn_x(mfn), mfn_x(mfn) + 1) ) + return false; + + return !map_regions_p2mt(d, gfn, 1, mfn, p2m_mmio_direct_c); +} + static void do_trap_data_abort_guest(struct cpu_user_regs *regs, const union hsr hsr) { @@ -2611,6 +2642,9 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, if ( !mfn_eq(mfn, INVALID_MFN) ) return; + if ( try_map_mmio(_gfn(paddr_to_pfn(info.gpa))) ) + return; + break; default: gprintk(XENLOG_WARNING, "Unsupported DFSC: HSR=%#x DFSC=%#x\n",