From patchwork Thu May 15 14:16:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 30263 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f72.google.com (mail-pa0-f72.google.com [209.85.220.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7991C20446 for ; Thu, 15 May 2014 14:18:41 +0000 (UTC) Received: by mail-pa0-f72.google.com with SMTP id rd3sf5652207pab.11 for ; Thu, 15 May 2014 07:18:40 -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=cmHabbiVxq/QLlP9rOuz/OnzfTmUwqbUIJ6H9T3yFf4=; b=AAjYqoMy5DBlTzOVVG7OzmExj809EMbatlR1M0d872ZfPmHKZJneEch8vPVZVYlcO+ ImHdlNhIYYI61Z5P5s+JF3GhXomIaQJnBtS8IsL1Zn2S3L/qvGw1tkAKpOx7VqRnfHSg ANC3E/J+2Pw03o9Zr/REG9OuRPHrJhkF6KJ/CDCtPW7PCk5dXMEtIi6G/kvjwvIOnOof Aw5tkR6exs5gl0aCVjmpg3c7dqcPKWDCA/sIKDL+rGkx2xhKKDV4kUwSKbeUXGWSy69d D/7+vLIpUfWo+mgPa7BVb42IsCPNqX9B3U7cRsHMqu8G7wrJIcSBUEDZBsCgeHqZMFYR K79A== X-Gm-Message-State: ALoCoQnmMFFm0lsrFkfR6x9Va3+nvxqAFTQNoidLA0oBOpk6XtYc3QRgGsWUB0yQFViLZen3OpoI X-Received: by 10.66.232.38 with SMTP id tl6mr2593615pac.33.1400163520787; Thu, 15 May 2014 07:18:40 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.21.85 with SMTP id 79ls248421qgk.41.gmail; Thu, 15 May 2014 07:18:40 -0700 (PDT) X-Received: by 10.220.116.136 with SMTP id m8mr86257vcq.77.1400163520626; Thu, 15 May 2014 07:18:40 -0700 (PDT) Received: from mail-ve0-f181.google.com (mail-ve0-f181.google.com [209.85.128.181]) by mx.google.com with ESMTPS id sn5si967620vdc.29.2014.05.15.07.18.40 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 15 May 2014 07:18:40 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.181 as permitted sender) client-ip=209.85.128.181; Received: by mail-ve0-f181.google.com with SMTP id pa12so1337741veb.40 for ; Thu, 15 May 2014 07:18:40 -0700 (PDT) X-Received: by 10.52.11.230 with SMTP id t6mr7338396vdb.27.1400163520520; Thu, 15 May 2014 07:18:40 -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 ib8csp326373vcb; Thu, 15 May 2014 07:18:40 -0700 (PDT) X-Received: by 10.224.13.72 with SMTP id b8mr897831qaa.4.1400163519358; Thu, 15 May 2014 07:18:39 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id y67si2620034qgd.190.2014.05.15.07.18.38 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 15 May 2014 07:18:39 -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 1WkwSY-0002g3-5A; Thu, 15 May 2014 14:16:34 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WkwSW-0002fs-Ay for xen-devel@lists.xenproject.org; Thu, 15 May 2014 14:16:32 +0000 Received: from [193.109.254.147:21772] by server-12.bemta-14.messagelabs.com id 79/AB-27473-F3CC4735; Thu, 15 May 2014 14:16:31 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-8.tower-27.messagelabs.com!1400163390!5069896!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 19966 invoked from network); 15 May 2014 14:16:30 -0000 Received: from mail-ee0-f44.google.com (HELO mail-ee0-f44.google.com) (74.125.83.44) by server-8.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 15 May 2014 14:16:30 -0000 Received: by mail-ee0-f44.google.com with SMTP id c41so711495eek.17 for ; Thu, 15 May 2014 07:16:30 -0700 (PDT) X-Received: by 10.14.108.198 with SMTP id q46mr14601004eeg.31.1400163390319; Thu, 15 May 2014 07:16:30 -0700 (PDT) Received: from belegaer.uk.xensource.com ([185.25.64.249]) by mx.google.com with ESMTPSA id x45sm12956780eee.37.2014.05.15.07.16.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 May 2014 07:16:29 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Thu, 15 May 2014 15:16:22 +0100 Message-Id: <1400163385-19863-2-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1400163385-19863-1-git-send-email-julien.grall@linaro.org> References: <1400163385-19863-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 v7 1/4] 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.128.181 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 function that will check if the IOMMU feature is enabled 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 Acked-by: Ian Campbell for the arm bit. Acked-by: Jan Beulich --- Changes in v7: - Add IOMMU_FEAT_count - Use DECLARE_BITMAP Changes in v6: - Rework the condition to flush cache for PT - Use {set,clear,test}_bit - Store features in hvm_iommu structure and add accessor - Don't specificed value in the enum 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 | 38 ++++++++++++++++++++++++++++++-------- xen/drivers/passthrough/iommu.c | 10 ++++++++++ xen/include/xen/hvm/iommu.h | 6 ++++++ xen/include/xen/iommu.h | 9 +++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 816da21..dd145c1 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 = iommu_enabled && !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; @@ -548,10 +568,12 @@ int p2m_alloc_table(struct domain *d) /* Clear both first level pages */ p = __map_domain_page(page); clear_page(p); + clean_xen_dcache_va_range(p, PAGE_SIZE); unmap_domain_page(p); p = __map_domain_page(page + 1); clear_page(p); + clean_xen_dcache_va_range(p, PAGE_SIZE); unmap_domain_page(p); p2m->first_level = page; diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 59f1c3e..cc12735 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -344,6 +344,16 @@ void iommu_crash_shutdown(void) iommu_enabled = iommu_intremap = 0; } +bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature) +{ + const struct hvm_iommu *hd = domain_hvm_iommu(d); + + if ( !iommu_enabled ) + return 0; + + return test_bit(feature, hd->features); +} + static void iommu_dump_p2m_table(unsigned char key) { struct domain *d; diff --git a/xen/include/xen/hvm/iommu.h b/xen/include/xen/hvm/iommu.h index 1259e16..693346c 100644 --- a/xen/include/xen/hvm/iommu.h +++ b/xen/include/xen/hvm/iommu.h @@ -34,6 +34,12 @@ struct hvm_iommu { /* List of DT devices assigned to this domain */ struct list_head dt_devices; #endif + + /* Features supported by the IOMMU */ + DECLARE_BITMAP(features, IOMMU_FEAT_count); }; +#define iommu_set_feature(d, f) set_bit((f), domain_hvm_iommu(d)->features) +#define iommu_clear_feature(d, f) clear_bit((f), domain_hvm_iommu(d)->features) + #endif /* __XEN_HVM_IOMMU_H__ */ diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index b7481dac..4c633bf 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -67,6 +67,15 @@ 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, + IOMMU_FEAT_count, +}; + +bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature); + + #ifdef HAS_PCI void pt_pci_init(void);