From patchwork Tue May 27 11:11:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 30952 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f72.google.com (mail-pb0-f72.google.com [209.85.160.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E024B203C3 for ; Tue, 27 May 2014 11:13:47 +0000 (UTC) Received: by mail-pb0-f72.google.com with SMTP id ma3sf43239551pbc.3 for ; Tue, 27 May 2014 04:13:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list :list-archive:content-type:content-transfer-encoding; bh=ZS9umF+bdePALMgYQJwjr4wuIIjoTVucDmswhXYSQHE=; b=bIVDpdqqin2t84p8o9u3+gxiMLczOSWhc/75wE/OMBYju9+wSuteRXudZy2gGGeeHF vS+gwF+vi76STCKfncrxowreQ7Mf49ozm4IQvxgnVkzC9UCKBK1Vt/FI8OI3w6TNH6FE NF99XbGfMKjVrvMVHnVRQ5xeb4X+muHNwywG0mlPNfqcjM2ZVKMp+Oj0StNYpEgbTcFz pCSCxd/KLMOUKZgsQS2TmlNnfkS6YTiBZV2Q5Zu76DRYCWXGkRo9upJs652jMzdABVQW PEo9WE5WIPWWzIy+C6a0PtpmiHv5rIXhWNssF4/le1nPb7QPJi3H9MFuyM2LBgL8TjE1 o2IQ== X-Gm-Message-State: ALoCoQmwN0XZd7F/IhdfAjCvx2tye1y0B3VzOgk7zbrBNtrqczr3KDNYbfiU+3RE650e1dLURmsW X-Received: by 10.66.142.9 with SMTP id rs9mr5479149pab.47.1401189226601; Tue, 27 May 2014 04:13:46 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.81.145 with SMTP id f17ls3002915qgd.95.gmail; Tue, 27 May 2014 04:13:46 -0700 (PDT) X-Received: by 10.58.209.233 with SMTP id mp9mr17942238vec.30.1401189226479; Tue, 27 May 2014 04:13:46 -0700 (PDT) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id b8si7905065vcf.7.2014.05.27.04.13.46 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 27 May 2014 04:13:46 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id im17so10463140vcb.10 for ; Tue, 27 May 2014 04:13:46 -0700 (PDT) X-Received: by 10.220.139.198 with SMTP id f6mr54848vcu.47.1401189226347; Tue, 27 May 2014 04:13:46 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp110119vcb; Tue, 27 May 2014 04:13:45 -0700 (PDT) X-Received: by 10.140.87.5 with SMTP id q5mr39940762qgd.43.1401189225020; Tue, 27 May 2014 04:13:45 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id j91si16404480qgf.81.2014.05.27.04.13.44 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 27 May 2014 04:13:45 -0700 (PDT) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WpFIQ-0003Lc-DS; Tue, 27 May 2014 11:11:54 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WpFIO-0003LE-IR for xen-devel@lists.xenproject.org; Tue, 27 May 2014 11:11:52 +0000 Received: from [85.158.143.35:21621] by server-1.bemta-4.messagelabs.com id 5D/D6-09853-7F274835; Tue, 27 May 2014 11:11:51 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-3.tower-21.messagelabs.com!1401189110!7127345!1 X-Originating-IP: [209.85.212.180] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 6.11.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 25392 invoked from network); 27 May 2014 11:11:50 -0000 Received: from mail-wi0-f180.google.com (HELO mail-wi0-f180.google.com) (209.85.212.180) by server-3.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 27 May 2014 11:11:50 -0000 Received: by mail-wi0-f180.google.com with SMTP id hi2so1452206wib.1 for ; Tue, 27 May 2014 04:11:49 -0700 (PDT) X-Received: by 10.194.108.5 with SMTP id hg5mr39693224wjb.57.1401189109098; Tue, 27 May 2014 04:11:49 -0700 (PDT) Received: from belegaer.uk.xensource.com ([185.25.64.249]) by mx.google.com with ESMTPSA id ed6sm7473124wib.20.2014.05.27.04.11.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 May 2014 04:11:47 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 27 May 2014 12:11:41 +0100 Message-Id: <1401189101-13211-3-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1401189101-13211-1-git-send-email-julien.grall@linaro.org> References: <1401189101-13211-1-git-send-email-julien.grall@linaro.org> Cc: stefano.stabellini@citrix.com, Julien Grall , tim@xen.org, ian.campbell@citrix.com, Jan Beulich Subject: [Xen-devel] [PATCH v9 2/2] xen/arm: grant: Add another entry to map MFN 1:1 in dom0 p2m X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: Grant mappings can be used for DMA requests. Currently the dev_bus_addr returned by the hypercall is the MFN (not the IPA). Guest expects to be able the returned address for DMA. When the device is protected by IOMMU the request will fail. Therefore, we have to add 1:1 mapping in the domain p2m to allow DMA request to work. This is valid because DOM0 has its memory mapped 1:1 and therefore we know that RAM and devices cannot clash. If the guest only owns protected device, the return dev_bus_addr should be an IPA. This will allow us to remove safely the 1:1 mapping and make grant mapping works correctly in the guest. For now, this is not addressed by this patch. The grant mapping code does the reference counting on every MFN and will call iommu_{map,unmap}_page when necessary. This was already handle for x86 PV guests, so we can reuse the same code path for ARM guest. Signed-off-by: Julien Grall Cc: Jan Beulich Acked-by: Jan Beulich --- The patch has been heavily rework to use iommu_{,un}map_page. I dropped all the acks. Changes in v9: - Move need_iommu in each gnttab_need_iommu - Add missing parentheses in the macros - Update comment and commit message - Add BUG_ON as we should never reach this path Changes in v8: - Rework differently the 1:1 mapping by using iommu_{,un}map_page helpers. Changes in v5: - Update commit message Changes in v4: - Patch added --- xen/arch/arm/p2m.c | 2 ++ xen/common/grant_table.c | 4 ++-- xen/drivers/passthrough/arm/smmu.c | 42 ++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/grant_table.h | 3 +++ xen/include/asm-arm/p2m.h | 3 +++ xen/include/asm-x86/grant_table.h | 3 +++ 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 96bc0ef..810459a 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -227,6 +227,7 @@ static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr, e.p2m.write = 0; break; + case p2m_iommu_map_rw: case p2m_map_foreign: case p2m_grant_map_rw: case p2m_mmio_direct: @@ -234,6 +235,7 @@ static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr, e.p2m.write = 1; break; + case p2m_iommu_map_ro: case p2m_grant_map_ro: case p2m_invalid: e.p2m.xn = 1; diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 2c93d9c..c08e957 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -727,7 +727,7 @@ __gnttab_map_grant_ref( double_gt_lock(lgt, rgt); - if ( !paging_mode_translate(ld) && need_iommu(ld) ) + if ( gnttab_need_iommu_mapping(ld) ) { unsigned int wrc, rdc; int err = 0; @@ -935,7 +935,7 @@ __gnttab_unmap_common( act->pin -= GNTPIN_hstw_inc; } - if ( !paging_mode_translate(ld) && need_iommu(ld) ) + if ( gnttab_need_iommu_mapping(ld) ) { unsigned int wrc, rdc; int err = 0; diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 21b4572..f4eb2a2 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -1536,6 +1536,46 @@ static void arm_smmu_iommu_domain_teardown(struct domain *d) xfree(smmu_domain); } +static int arm_smmu_map_page(struct domain *d, unsigned long gfn, + unsigned long mfn, unsigned int flags) +{ + p2m_type_t t; + + /* Grant mappings can be used for DMA requests. The dev_bus_addr returned by + * the hypercall is the MFN (not the IPA). For device protected by + * an IOMMU, Xen needs to add a 1:1 mapping in the domain p2m to + * allow DMA request to work. + * This is only valid when the domain is directed mapped. Hence this + * function should only be used by gnttab code with gfn == mfn. + */ + BUG_ON(!is_domain_direct_mapped(d)); + BUG_ON(mfn != gfn); + + /* We only support readable and writable flags */ + if ( !(flags & (IOMMUF_readable | IOMMUF_writable)) ) + return -EINVAL; + + t = (flags & IOMMUF_writable) ? p2m_iommu_map_rw : p2m_iommu_map_ro; + + /* The function guest_physmap_add_entry replaces the current mapping + * if there is already one... + */ + return guest_physmap_add_entry(d, gfn, mfn, 0, t); +} + +static int arm_smmu_unmap_page(struct domain *d, unsigned long gfn) +{ + /* This function should only be used by gnttab code when the domain + * is direct mapped + */ + if ( !is_domain_direct_mapped(d) ) + return -EINVAL; + + guest_physmap_remove_page(d, gfn, gfn, 0); + + return 0; +} + static const struct iommu_ops arm_smmu_iommu_ops = { .init = arm_smmu_iommu_domain_init, .hwdom_init = arm_smmu_iommu_hwdom_init, @@ -1544,6 +1584,8 @@ static const struct iommu_ops arm_smmu_iommu_ops = { .iotlb_flush_all = arm_smmu_iotlb_flush_all, .assign_dt_device = arm_smmu_attach_dev, .reassign_dt_device = arm_smmu_reassign_dt_dev, + .map_page = arm_smmu_map_page, + .unmap_page = arm_smmu_unmap_page, }; static int __init smmu_init(struct dt_device_node *dev, diff --git a/xen/include/asm-arm/grant_table.h b/xen/include/asm-arm/grant_table.h index 6e0cc59..cd344ae 100644 --- a/xen/include/asm-arm/grant_table.h +++ b/xen/include/asm-arm/grant_table.h @@ -33,6 +33,9 @@ static inline int replace_grant_supported(void) ( ((i >= nr_grant_frames(d->grant_table)) && \ (i < max_nr_grant_frames)) ? 0 : (d->arch.grant_table_gpfn[i])) +#define gnttab_need_iommu_mapping(d) \ + (is_domain_direct_mapped(d) && need_iommu(ld)) + #endif /* __ASM_GRANT_TABLE_H__ */ /* * Local variables: diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index bd71abe..911d32d 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -45,6 +45,9 @@ typedef enum { p2m_map_foreign, /* Ram pages from foreign domain */ p2m_grant_map_rw, /* Read/write grant mapping */ p2m_grant_map_ro, /* Read-only grant mapping */ + /* The types below are only used to decide the page attribute in the P2M */ + p2m_iommu_map_rw, /* Read/write iommu mapping */ + p2m_iommu_map_ro, /* Read-only iommu mapping */ p2m_max_real_type, /* Types after this won't be store in the p2m */ } p2m_type_t; diff --git a/xen/include/asm-x86/grant_table.h b/xen/include/asm-x86/grant_table.h index 3013869..93b81f7 100644 --- a/xen/include/asm-x86/grant_table.h +++ b/xen/include/asm-x86/grant_table.h @@ -65,6 +65,9 @@ static inline void gnttab_clear_flag(unsigned int nr, uint16_t *st) /* Done implicitly when page tables are destroyed. */ #define gnttab_release_host_mappings(domain) ( paging_mode_external(domain) ) +#define gnttab_need_iommu_mapping(d) \ + (!paging_mode_translate(d) && need_iommu(ld)) + static inline int replace_grant_supported(void) { return 1;