From: Julien Grall <julien.grall@linaro.org>
To: xen-devel@lists.xenproject.org
Cc: ian.campbell@citrix.com, Julien Grall <julien.grall@linaro.org>,
tim@xen.org, stefano.stabellini@citrix.com,
Jan Beulich <jbeulich@suse.com>,
Xiantao Zhang <xiantao.zhang@intel.com>
Subject: [PATCH v7 1/4] xen/arm: p2m: Clean cache PT when the IOMMU doesn't support coherent walk
Date: Thu, 15 May 2014 15:16:22 +0100 [thread overview]
Message-ID: <1400163385-19863-2-git-send-email-julien.grall@linaro.org> (raw)
In-Reply-To: <1400163385-19863-1-git-send-email-julien.grall@linaro.org>
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 <julien.grall@linaro.org>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Xiantao Zhang <xiantao.zhang@intel.com>
---
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);
--
1.7.10.4
next prev parent reply other threads:[~2014-05-15 14:16 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-15 14:16 [PATCH v7 0/4] IOMMU support for ARM Julien Grall
2014-05-15 14:16 ` Julien Grall [this message]
2014-05-15 15:20 ` [PATCH v7 1/4] xen/arm: p2m: Clean cache PT when the IOMMU doesn't support coherent walk Ian Campbell
2014-05-15 15:24 ` Julien Grall
2014-05-15 15:51 ` Ian Campbell
2014-05-15 16:05 ` Jan Beulich
2014-05-15 16:04 ` Jan Beulich
2014-05-15 17:06 ` Julien Grall
2014-05-16 10:00 ` Ian Campbell
2014-05-15 14:16 ` [PATCH v7 2/4] xen/arm: grant: Add another entry to map MFN 1:1 in dom0 p2m Julien Grall
2014-05-17 18:12 ` Julien Grall
2014-05-19 9:45 ` Ian Campbell
2014-05-19 14:20 ` Julien Grall
2014-05-20 7:30 ` Roger Pau Monné
2014-05-20 8:51 ` Ian Campbell
2014-05-20 11:19 ` Julien Grall
2014-05-20 11:25 ` Ian Campbell
2014-05-20 11:53 ` Julien Grall
2014-05-15 14:16 ` [PATCH v7 3/4] xen: iommu: Define PAGE_{SHIFT, SIZE, ALIGN, MASK)_64K Julien Grall
2014-05-15 14:16 ` [PATCH v7 4/4] drivers/passthrough: arm: Add support for SMMU drivers Julien Grall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1400163385-19863-2-git-send-email-julien.grall@linaro.org \
--to=julien.grall@linaro.org \
--cc=ian.campbell@citrix.com \
--cc=jbeulich@suse.com \
--cc=stefano.stabellini@citrix.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xenproject.org \
--cc=xiantao.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).