File 20322-vtd-ept-coexistance.patch of Package xen

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1255677917 -3600
# Node ID 648c674fcc96b09fc8fb9428843fec08c8d2fc4e
# Parent  7a69f773548e7fc88f13bf59db4ac73208ec32c5
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@intel.com>

--- 2009-11-09.orig/xen/arch/x86/mm/hap/p2m-ept.c	2009-11-09 00:00:00.000000000 +0100
+++ 2009-11-09/xen/arch/x86/mm/hap/p2m-ept.c	2009-11-09 00:00:00.000000000 +0100
@@ -401,6 +401,7 @@ void ept_change_entry_emt_with_range(str
     int order = 0;
     unsigned long mfn;
 
+    p2m_lock(d->arch.p2m);
     for ( gfn = start_gfn; gfn <= end_gfn; gfn++ )
     {
         epte = ept_get_entry_content(d, gfn);
@@ -446,6 +447,7 @@ void ept_change_entry_emt_with_range(str
              */
             _ept_set_entry(d, gfn, _mfn(mfn), order, p2mt, 0);
     }
+    p2m_unlock(d->arch.p2m);
 }
 
 /* Walk the whole p2m table, changing any entries of the old type
--- 2009-11-09.orig/xen/arch/x86/mm/p2m.c	2009-11-09 00:00:00.000000000 +0100
+++ 2009-11-09/xen/arch/x86/mm/p2m.c	2009-11-09 14:19:29.000000000 +0100
@@ -34,46 +34,6 @@
 #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...)                                \
     debugtrace_printk("p2m: %s(): " _f, __func__, ##_a)
@@ -1154,7 +1114,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",
@@ -1178,7 +1140,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;
 }
--- 2009-11-09.orig/xen/include/asm-x86/p2m.h	2009-11-09 00:00:00.000000000 +0100
+++ 2009-11-09/xen/include/asm-x86/p2m.h	2009-11-09 14:21:06.000000000 +0100
@@ -116,6 +116,46 @@ struct p2m_domain {
     unsigned long max_mapped_pfn;
 };
 
+/*
+ * 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)
 {
openSUSE Build Service is sponsored by