# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1255679845 -3600
# Node ID b0442d0a52754a6b5154d29b2b01d44e2a5541e4
# Parent 9086d7e380e92c7af904e4bfafbb524c55b5ed09
x86: Fix ept and vt-d co-existence issue.
For vt-d's mmio address ranges, once ept enables, they should
be added to ept page tables with p2m lock held, and then guest can
access these ranges like conventional ram, but to change the ept
entries, it should take the p2m lock first.
Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
xen-unstable changeset: 20322:648c674fcc96
xen-unstable date: Fri Oct 16 08:25:17 2009 +0100
---
xen/arch/x86/mm/hap/p2m-ept.c | 2 +
xen/arch/x86/mm/p2m.c | 44 +++---------------------------------------
xen/include/asm-x86/p2m.h | 40 ++++++++++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 40 deletions(-)
diff -r 9086d7e380e9 -r b0442d0a5275 xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c Fri Oct 16 08:52:14 2009 +0100
+++ b/xen/arch/x86/mm/hap/p2m-ept.c Fri Oct 16 08:57:25 2009 +0100
@@ -421,6 +421,7 @@ void ept_change_entry_emt_with_range(str
unsigned long mfn;
uint8_t o_igmt, o_emt;
+ p2m_lock(d->arch.p2m);
for ( gfn = start_gfn; gfn <= end_gfn; gfn++ )
{
epte = ept_get_entry_content(d, gfn);
@@ -464,6 +465,7 @@ void ept_change_entry_emt_with_range(str
ept_set_entry(d, gfn, _mfn(mfn), order, p2mt);
}
}
+ p2m_unlock(d->arch.p2m);
}
/* Walk the whole p2m table, changing any entries of the old type
diff -r 9086d7e380e9 -r b0442d0a5275 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c Fri Oct 16 08:52:14 2009 +0100
+++ b/xen/arch/x86/mm/p2m.c Fri Oct 16 08:57:25 2009 +0100
@@ -33,46 +33,6 @@
/* Debugging and auditing of the P2M code? */
#define P2M_AUDIT 0
#define P2M_DEBUGGING 0
-
-/*
- * The P2M lock. This protects all updates to the p2m table.
- * Updates are expected to be safe against concurrent reads,
- * which do *not* require the lock.
- *
- * Locking discipline: always acquire this lock before the shadow or HAP one
- */
-
-#define p2m_lock_init(_p2m) \
- do { \
- spin_lock_init(&(_p2m)->lock); \
- (_p2m)->locker = -1; \
- (_p2m)->locker_function = "nobody"; \
- } while (0)
-
-#define p2m_lock(_p2m) \
- do { \
- if ( unlikely((_p2m)->locker == current->processor) ) \
- { \
- printk("Error: p2m lock held by %s\n", \
- (_p2m)->locker_function); \
- BUG(); \
- } \
- spin_lock(&(_p2m)->lock); \
- ASSERT((_p2m)->locker == -1); \
- (_p2m)->locker = current->processor; \
- (_p2m)->locker_function = __func__; \
- } while (0)
-
-#define p2m_unlock(_p2m) \
- do { \
- ASSERT((_p2m)->locker == current->processor); \
- (_p2m)->locker = -1; \
- (_p2m)->locker_function = "nobody"; \
- spin_unlock(&(_p2m)->lock); \
- } while (0)
-
-#define p2m_locked_by_me(_p2m) \
- (current->processor == (_p2m)->locker)
/* Printouts */
#define P2M_PRINTK(_f, _a...) \
@@ -2240,7 +2200,9 @@ set_mmio_p2m_entry(struct domain *d, uns
set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
}
+ p2m_lock(d->arch.p2m);
rc = set_p2m_entry(d, gfn, mfn, 0, p2m_mmio_direct);
+ p2m_unlock(d->arch.p2m);
if ( 0 == rc )
gdprintk(XENLOG_ERR,
"set_mmio_p2m_entry: set_p2m_entry failed! mfn=%08lx\n",
@@ -2264,7 +2226,9 @@ clear_mmio_p2m_entry(struct domain *d, u
"clear_mmio_p2m_entry: gfn_to_mfn failed! gfn=%08lx\n", gfn);
return 0;
}
+ p2m_lock(d->arch.p2m);
rc = set_p2m_entry(d, gfn, _mfn(INVALID_MFN), 0, 0);
+ p2m_unlock(d->arch.p2m);
return rc;
}
diff -r 9086d7e380e9 -r b0442d0a5275 xen/include/asm-x86/p2m.h
--- a/xen/include/asm-x86/p2m.h Fri Oct 16 08:52:14 2009 +0100
+++ b/xen/include/asm-x86/p2m.h Fri Oct 16 08:57:25 2009 +0100
@@ -158,6 +158,46 @@ struct p2m_domain {
} pod;
};
+/*
+ * The P2M lock. This protects all updates to the p2m table.
+ * Updates are expected to be safe against concurrent reads,
+ * which do *not* require the lock.
+ *
+ * Locking discipline: always acquire this lock before the shadow or HAP one
+ */
+
+#define p2m_lock_init(_p2m) \
+ do { \
+ spin_lock_init(&(_p2m)->lock); \
+ (_p2m)->locker = -1; \
+ (_p2m)->locker_function = "nobody"; \
+ } while (0)
+
+#define p2m_lock(_p2m) \
+ do { \
+ if ( unlikely((_p2m)->locker == current->processor) ) \
+ { \
+ printk("Error: p2m lock held by %s\n", \
+ (_p2m)->locker_function); \
+ BUG(); \
+ } \
+ spin_lock(&(_p2m)->lock); \
+ ASSERT((_p2m)->locker == -1); \
+ (_p2m)->locker = current->processor; \
+ (_p2m)->locker_function = __func__; \
+ } while (0)
+
+#define p2m_unlock(_p2m) \
+ do { \
+ ASSERT((_p2m)->locker == current->processor); \
+ (_p2m)->locker = -1; \
+ (_p2m)->locker_function = "nobody"; \
+ spin_unlock(&(_p2m)->lock); \
+ } while (0)
+
+#define p2m_locked_by_me(_p2m) \
+ (current->processor == (_p2m)->locker)
+
/* Extract the type from the PTE flags that store it */
static inline p2m_type_t p2m_flags_to_type(unsigned long flags)
{
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|