From patchwork Tue May 13 15:50:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 30081 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f71.google.com (mail-pa0-f71.google.com [209.85.220.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CC0E920446 for ; Tue, 13 May 2014 15:52:02 +0000 (UTC) Received: by mail-pa0-f71.google.com with SMTP id kq14sf2423161pab.2 for ; Tue, 13 May 2014 08:52:01 -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=BKyU9UwlX0RWBEw6H8yOqkaRVriMTQoMY6i1oY9KJEg=; b=F9ctV+K4o0IB0vG1GoNBrLRMyL7JOIZRSb4SZP8ilJX512p3WWnp4hEDass4CaCGCn euqhon5GxyoI6MfZXtH0yCYC6SuR984us7CquuJVwFo8GHy2H8gPvOaQT3oiBS24EVZy mO18s4l1SOYb+0Xr+eMRXupEWonKbHuAEZiNazFCljy0JQjANvTQlMcIX50keN34KBjb SoMVvp4mupknoVV7xwwl2/Vl6/cmEjP2oMsyo36/jB5ufnCQYenWvDjGlgmVWsypjav+ is55RUfgv7fG7TZibhxBN+1bo/jzywXVZTEQTndkEfkzbq1PaDtyT7yOixnglYAxHo6Q mbAg== X-Gm-Message-State: ALoCoQkpvP6qRSrUhYGBmYY3AIlB8aBYz13f7zBJpkAyr3UjZRIyWZL34ZNShLcy9xfiW6CleLnD X-Received: by 10.66.216.161 with SMTP id or1mr5030845pac.38.1399996321713; Tue, 13 May 2014 08:52:01 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.96.72 with SMTP id j66ls1874478qge.99.gmail; Tue, 13 May 2014 08:52:01 -0700 (PDT) X-Received: by 10.52.232.161 with SMTP id tp1mr7104251vdc.33.1399996321495; Tue, 13 May 2014 08:52:01 -0700 (PDT) Received: from mail-vc0-f172.google.com (mail-vc0-f172.google.com [209.85.220.172]) by mx.google.com with ESMTPS id sq9si2714298vdc.35.2014.05.13.08.52.01 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 13 May 2014 08:52:01 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.172 as permitted sender) client-ip=209.85.220.172; Received: by mail-vc0-f172.google.com with SMTP id hr9so704199vcb.31 for ; Tue, 13 May 2014 08:52:01 -0700 (PDT) X-Received: by 10.220.7.131 with SMTP id d3mr940817vcd.45.1399996321401; Tue, 13 May 2014 08:52:01 -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 ib8csp162070vcb; Tue, 13 May 2014 08:52:00 -0700 (PDT) X-Received: by 10.50.45.102 with SMTP id l6mr57075955igm.16.1399996320201; Tue, 13 May 2014 08:52:00 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id i15si16943061igf.48.2014.05.13.08.51.59 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 13 May 2014 08:52:00 -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 1WkEyq-0000Bo-4t; Tue, 13 May 2014 15:51:00 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WkEyn-000082-O1 for xen-devel@lists.xenproject.org; Tue, 13 May 2014 15:50:58 +0000 Received: from [85.158.139.211:60980] by server-11.bemta-5.messagelabs.com id 9D/3D-30804-06F32735; Tue, 13 May 2014 15:50:56 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-12.tower-206.messagelabs.com!1399996255!4010322!1 X-Originating-IP: [74.125.83.44] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.11.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4552 invoked from network); 13 May 2014 15:50:55 -0000 Received: from mail-ee0-f44.google.com (HELO mail-ee0-f44.google.com) (74.125.83.44) by server-12.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 13 May 2014 15:50:55 -0000 Received: by mail-ee0-f44.google.com with SMTP id c41so556497eek.17 for ; Tue, 13 May 2014 08:50:55 -0700 (PDT) X-Received: by 10.14.207.199 with SMTP id n47mr14265110eeo.49.1399996255705; Tue, 13 May 2014 08:50:55 -0700 (PDT) Received: from belegaer.uk.xensource.com ([185.25.64.249]) by mx.google.com with ESMTPSA id m44sm41054917eeh.14.2014.05.13.08.50.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 May 2014 08:50:54 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 13 May 2014 16:50:28 +0100 Message-Id: <1399996230-18201-13-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1399996230-18201-1-git-send-email-julien.grall@linaro.org> References: <1399996230-18201-1-git-send-email-julien.grall@linaro.org> Cc: ian.campbell@citrix.com, Julien Grall , tim@xen.org, stefano.stabellini@citrix.com, Jan Beulich , Xiantao Zhang Subject: [Xen-devel] [PATCH v5 12/14] xen/arm: p2m: Clean cache PT when the IOMMU doesn't support coherent walk 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.172 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: Some IOMMU don't suppport coherent PT walk. When the p2m is shared with the CPU, Xen has to make sure the PT changes have reached the memory. Introduce new IOMMU callback that will retrieve the IOMMU feature for a specified domain. On ARM, the platform can contain multiple IOMMUs. Each of them may not have the same set of feature. The domain parameter will be used to get the set of features for IOMMUs used by this domain. Signed-off-by: Julien Grall Cc: Jan Beulich Cc: Xiantao Zhang --- Changes in v5: - Flush on every write_pte instead of unmap page. This will avoid to flush a whole page when only few bytes are modified - Only get iommu feature once. - Add bits to flush cache when a new table is created - Fix typoes in commit message and comment - Use an enum to describe the feature. Each items are a bit position Changes in v4: - Patch added --- xen/arch/arm/p2m.c | 36 ++++++++++++++++++++++++++++-------- xen/drivers/passthrough/iommu.c | 11 +++++++++++ xen/include/xen/iommu.h | 9 +++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 816da21..4331866 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -253,9 +253,15 @@ static lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr, return e; } +static inline void p2m_write_pte(lpae_t *p, lpae_t pte, bool_t flush_cache) +{ + write_pte(p, pte); + if ( flush_cache ) + clean_xen_dcache(*p); +} + /* Allocate a new page table page and hook it in via the given entry */ -static int p2m_create_table(struct domain *d, - lpae_t *entry) +static int p2m_create_table(struct domain *d, lpae_t *entry, bool_t flush_cache) { struct p2m_domain *p2m = &d->arch.p2m; struct page_info *page; @@ -272,11 +278,13 @@ static int p2m_create_table(struct domain *d, p = __map_domain_page(page); clear_page(p); + if ( flush_cache ) + clean_xen_dcache_va_range(p, PAGE_SIZE); unmap_domain_page(p); pte = mfn_to_p2m_entry(page_to_mfn(page), MATTR_MEM, p2m_invalid); - write_pte(entry, pte); + p2m_write_pte(entry, pte, flush_cache); return 0; } @@ -308,6 +316,13 @@ static int apply_p2m_changes(struct domain *d, unsigned int flush = 0; bool_t populate = (op == INSERT || op == ALLOCATE); lpae_t pte; + bool_t flush_pt; + + /* Some IOMMU don't support coherent PT walk. When the p2m is + * shared with the CPU, Xen has to make sure that the PT changes have + * reached the memory + */ + flush_pt = need_iommu(d) && !iommu_has_feature(d, IOMMU_FEAT_COHERENT_WALK); spin_lock(&p2m->lock); @@ -334,7 +349,8 @@ static int apply_p2m_changes(struct domain *d, continue; } - rc = p2m_create_table(d, &first[first_table_offset(addr)]); + rc = p2m_create_table(d, &first[first_table_offset(addr)], + flush_pt); if ( rc < 0 ) { printk("p2m_populate_ram: L1 failed\n"); @@ -360,7 +376,8 @@ static int apply_p2m_changes(struct domain *d, continue; } - rc = p2m_create_table(d, &second[second_table_offset(addr)]); + rc = p2m_create_table(d, &second[second_table_offset(addr)], + flush_pt); if ( rc < 0 ) { printk("p2m_populate_ram: L2 failed\n"); goto out; @@ -411,13 +428,15 @@ static int apply_p2m_changes(struct domain *d, pte = mfn_to_p2m_entry(page_to_mfn(page), mattr, t); - write_pte(&third[third_table_offset(addr)], pte); + p2m_write_pte(&third[third_table_offset(addr)], + pte, flush_pt); } break; case INSERT: { pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t); - write_pte(&third[third_table_offset(addr)], pte); + p2m_write_pte(&third[third_table_offset(addr)], + pte, flush_pt); maddr += PAGE_SIZE; } break; @@ -433,7 +452,8 @@ static int apply_p2m_changes(struct domain *d, count += 0x10; memset(&pte, 0x00, sizeof(pte)); - write_pte(&third[third_table_offset(addr)], pte); + p2m_write_pte(&third[third_table_offset(addr)], + pte, flush_pt); count++; } break; diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 59f1c3e..2faab48 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -344,6 +344,17 @@ void iommu_crash_shutdown(void) iommu_enabled = iommu_intremap = 0; } +bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature) +{ + const struct iommu_ops *ops = domain_hvm_iommu(d)->platform_ops; + uint32_t features = 0; + + if ( iommu_enabled && ops && ops->features ) + features = ops->features(d); + + return !!(features & (1 << feature)); +} + static void iommu_dump_p2m_table(unsigned char key) { struct domain *d; diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index b7481dac..2a763ae 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -67,6 +67,14 @@ int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn, unsigned int flags); int iommu_unmap_page(struct domain *d, unsigned long gfn); +enum iommu_feature +{ + IOMMU_FEAT_COHERENT_WALK = 1, +}; + +bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature); + + #ifdef HAS_PCI void pt_pci_init(void); @@ -139,6 +147,7 @@ struct iommu_ops { void (*iotlb_flush)(struct domain *d, unsigned long gfn, unsigned int page_count); void (*iotlb_flush_all)(struct domain *d); void (*dump_p2m_table)(struct domain *d); + uint32_t (*features)(struct domain *d); }; void iommu_suspend(void);