WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86: Clean up PV guest LDT handling.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Clean up PV guest LDT handling.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 05 Feb 2009 08:00:48 -0800
Delivery-date: Thu, 05 Feb 2009 08:00:49 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1233760126 0
# Node ID 13a0272c8c024fca83bc991c7e2da992d07bc8eb
# Parent  271697e6d9b2b85ce348548f99166be450d1cf5a
x86: Clean up PV guest LDT handling.
 1. Do not touch deferred_ops in invalidate_shadow_ldt(), as we may
 not always be in a context where deferred_ops is valid.
 2. Protected the shadow LDT with a lock, now that mmu updates are not
 protected by the per-domain lock.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c        |    2 ++
 xen/arch/x86/mm.c            |   40 +++++++++++++++++++++++-----------------
 xen/include/asm-x86/domain.h |    1 +
 3 files changed, 26 insertions(+), 17 deletions(-)

diff -r 271697e6d9b2 -r 13a0272c8c02 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Feb 04 14:46:47 2009 +0000
+++ b/xen/arch/x86/domain.c     Wed Feb 04 15:08:46 2009 +0000
@@ -352,6 +352,8 @@ int vcpu_initialise(struct vcpu *v)
     v->arch.perdomain_ptes =
         d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT);
 
+    spin_lock_init(&v->arch.shadow_ldt_lock);
+
     return (is_pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0);
 }
 
diff -r 271697e6d9b2 -r 13a0272c8c02 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Feb 04 14:46:47 2009 +0000
+++ b/xen/arch/x86/mm.c Wed Feb 04 15:08:46 2009 +0000
@@ -179,12 +179,6 @@ l2_pgentry_t *compat_idle_pg_table_l2 = 
 #define l3_disallow_mask(d) L3_DISALLOW_MASK
 #endif
 
-static void queue_deferred_ops(struct domain *d, unsigned int ops)
-{
-    ASSERT(d == current->domain);
-    this_cpu(percpu_mm_info).deferred_ops |= ops;
-}
-
 void __init init_frametable(void)
 {
     unsigned long nr_pages, page_step, i, mfn;
@@ -464,14 +458,18 @@ void update_cr3(struct vcpu *v)
 }
 
 
-static void invalidate_shadow_ldt(struct vcpu *v)
+static void invalidate_shadow_ldt(struct vcpu *v, int flush)
 {
     int i;
     unsigned long pfn;
     struct page_info *page;
 
+    BUG_ON(unlikely(in_irq()));
+
+    spin_lock(&v->arch.shadow_ldt_lock);
+
     if ( v->arch.shadow_ldt_mapcnt == 0 )
-        return;
+        goto out;
 
     v->arch.shadow_ldt_mapcnt = 0;
 
@@ -486,11 +484,12 @@ static void invalidate_shadow_ldt(struct
         put_page_and_type(page);
     }
 
-    /* Dispose of the (now possibly invalid) mappings from the TLB.  */
-    if ( v == current )
-        queue_deferred_ops(v->domain, DOP_FLUSH_TLB | DOP_RELOAD_LDT);
-    else
-        flush_tlb_mask(v->domain->domain_dirty_cpumask);
+    /* Rid TLBs of stale mappings (guest mappings and shadow mappings). */
+    if ( flush )
+        flush_tlb_mask(v->vcpu_dirty_cpumask);
+
+ out:
+    spin_unlock(&v->arch.shadow_ldt_lock);
 }
 
 
@@ -541,8 +540,10 @@ int map_ldt_shadow_page(unsigned int off
 
     nl1e = l1e_from_pfn(mfn, l1e_get_flags(l1e) | _PAGE_RW);
 
+    spin_lock(&v->arch.shadow_ldt_lock);
     l1e_write(&v->arch.perdomain_ptes[off + 16], nl1e);
     v->arch.shadow_ldt_mapcnt++;
+    spin_unlock(&v->arch.shadow_ldt_lock);
 
     return 1;
 }
@@ -989,7 +990,7 @@ void put_page_from_l1e(l1_pgentry_t l1e,
              (d == e) )
         {
             for_each_vcpu ( d, v )
-                invalidate_shadow_ldt(v);
+                invalidate_shadow_ldt(v, 1);
         }
         put_page(page);
     }
@@ -2375,7 +2376,7 @@ int new_guest_cr3(unsigned long mfn)
             return 0;
         }
 
-        invalidate_shadow_ldt(curr);
+        invalidate_shadow_ldt(curr, 0);
         write_ptbase(curr);
 
         return 1;
@@ -2390,7 +2391,7 @@ int new_guest_cr3(unsigned long mfn)
         return 0;
     }
 
-    invalidate_shadow_ldt(curr);
+    invalidate_shadow_ldt(curr, 0);
 
     old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
 
@@ -2427,6 +2428,10 @@ static void process_deferred_ops(void)
             flush_tlb_local();
     }
 
+    /*
+     * Do this after flushing TLBs, to ensure we see fresh LDT mappings
+     * via the linear pagetable mapping.
+     */
     if ( deferred_ops & DOP_RELOAD_LDT )
         (void)map_ldt_shadow_page(0);
 
@@ -2799,7 +2804,8 @@ int do_mmuext_op(
             else if ( (curr->arch.guest_context.ldt_ents != ents) || 
                       (curr->arch.guest_context.ldt_base != ptr) )
             {
-                invalidate_shadow_ldt(curr);
+                invalidate_shadow_ldt(curr, 0);
+                this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_TLB;
                 curr->arch.guest_context.ldt_base = ptr;
                 curr->arch.guest_context.ldt_ents = ents;
                 load_LDT(curr);
diff -r 271697e6d9b2 -r 13a0272c8c02 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Feb 04 14:46:47 2009 +0000
+++ b/xen/include/asm-x86/domain.h      Wed Feb 04 15:08:46 2009 +0000
@@ -352,6 +352,7 @@ struct arch_vcpu
 
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
+    spinlock_t shadow_ldt_lock;
 
     struct paging_vcpu paging;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: Clean up PV guest LDT handling., Xen patchbot-unstable <=