[IA64] Fix SMP-unsafe with XENMEM_add_to_physmap on HVM
authorIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 8 Jul 2008 02:41:43 +0000 (11:41 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 8 Jul 2008 02:41:43 +0000 (11:41 +0900)
XENMEM_add_to_physmap hypercall on HVM is SMP-unsafe
and may cause a xen crash.
Actually I've met:

(XEN) ia64_fault, vector=0x18, ifa=0xe0000165c98814f0, iip=0xf0000000040a1b80, ipsr=0x0000121008226010, isr=0x0000008000000030
(XEN) General Exception: IA-64 Reserved Register/Field fault (data access).
...
(XEN) ****************************************
(XEN) Panic on CPU 2:
(XEN) Fault in Xen.
(XEN) ****************************************

This patch fixes it.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/ia64/vmx/vtlb.c
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/vmmu.h

index b1d5e25f46f181faeb316d77167ddae69196dd5d..da8f877764c7ad9a070031e3dd0fbcdb08a35a5e 100644 (file)
@@ -623,6 +623,30 @@ void thash_purge_all(VCPU *v)
     local_flush_tlb_all();
 }
 
+static void __thash_purge_all(void *arg)
+{
+    struct vcpu *v = arg;
+
+    BUG_ON(vcpu_runnable(v) || v->is_running);
+    thash_purge_all(v);
+}
+
+void vmx_vcpu_flush_vtlb_all(VCPU *v)
+{
+    if (v == current) {
+        thash_purge_all(v);
+        return;
+    }
+
+    /* SMP safe */
+    vcpu_pause(v);
+    if (v->processor == smp_processor_id())
+        __thash_purge_all(v);
+    else
+        smp_call_function_single(v->processor, __thash_purge_all, v, 1, 1);
+    vcpu_unpause(v);
+}
+
 
 /*
  * Lookup the hash table and its collision chain to find an entry
index 19d91f5505592c46e9511ff8b96af3da3f4e9e6b..6e89f0d44fc569cedd59ee026f018ac1a284914e 100644 (file)
@@ -249,31 +249,20 @@ domain_purge_swtc_entries_vcpu_dirty_mask(struct domain* d,
 // (e.g. vcpu == current), smp_mb() is unnecessary.
 void vcpu_flush_vtlb_all(struct vcpu *v)
 {
-       if (VMX_DOMAIN(v)) {
-               /* This code may be call for remapping shared_info and
-                  grant_table share page from guest_physmap_remove_page()
-                  in arch_memory_op() XENMEM_add_to_physmap to realize
-                  PV-on-HVM feature. */
-               /* FIXME: This is not SMP-safe yet about p2m table */
-               /* Purge vTLB for VT-i domain */
-               thash_purge_all(v);
-       }
-       else {
-               /* First VCPU tlb.  */
-               vcpu_purge_tr_entry(&PSCBX(v,dtlb));
-               vcpu_purge_tr_entry(&PSCBX(v,itlb));
-               smp_mb();
+       /* First VCPU tlb.  */
+       vcpu_purge_tr_entry(&PSCBX(v,dtlb));
+       vcpu_purge_tr_entry(&PSCBX(v,itlb));
+       smp_mb();
 
-               /* Then VHPT.  */
-               if (HAS_PERVCPU_VHPT(v->domain))
-                       vcpu_vhpt_flush(v);
-               else
-                       local_vhpt_flush();
-               smp_mb();
+       /* Then VHPT.  */
+       if (HAS_PERVCPU_VHPT(v->domain))
+               vcpu_vhpt_flush(v);
+       else
+               local_vhpt_flush();
+       smp_mb();
 
-               /* Then mTLB.  */
-               local_flush_tlb_all();
-       }
+       /* Then mTLB.  */
+       local_flush_tlb_all();
 
        /* We could clear bit in d->domain_dirty_cpumask only if domain d in
           not running on this processor.  There is currently no easy way to
@@ -297,6 +286,15 @@ void domain_flush_vtlb_all(struct domain* d)
                if (!v->is_initialised)
                        continue;
 
+               if (VMX_DOMAIN(v)) {
+                       // This code may be called for remapping shared_info
+                       // and grant_table from guest_physmap_remove_page()
+                       // in arch_memory_op() XENMEM_add_to_physmap to realize
+                       // PV-on-HVM feature.
+                       vmx_vcpu_flush_vtlb_all(v);
+                       continue;
+               }
+
                if (v->processor == cpu)
                        vcpu_flush_vtlb_all(v);
                else
index 31eb76e11570a6c623a859efcc051fd203498334..7f950112efa6c2e9acfbb1a49edf2873cea28516 100644 (file)
@@ -175,6 +175,7 @@ extern int thash_purge_and_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa, in
  *
  */
 extern void thash_purge_all(struct vcpu *v);
+extern void vmx_vcpu_flush_vtlb_all(struct vcpu *v);
 
 /*
  * Lookup the hash table and its collision chain to find an entry