bitkeeper revision 1.835 (406d9481GqoZ_RrT3GukXhamv7rulA)
authoriap10@tetris.cl.cam.ac.uk <iap10@tetris.cl.cam.ac.uk>
Fri, 2 Apr 2004 16:27:45 +0000 (16:27 +0000)
committeriap10@tetris.cl.cam.ac.uk <iap10@tetris.cl.cam.ac.uk>
Fri, 2 Apr 2004 16:27:45 +0000 (16:27 +0000)
Delete shadow page tables when destroying domain

xen/common/domain.c
xen/common/memory.c
xen/common/schedule.c
xen/common/shadow.c
xen/include/xen/shadow.h

index 2db0331d89553ff2eac247cf6ba32885401c7f03..7b55ee89d4cc6dfa814c5d9ef1446a9724a74953 100644 (file)
@@ -19,6 +19,7 @@
 #include <xen/console.h>
 #include <xen/vbd.h>
 #include <asm/i387.h>
+#include <xen/shadow.h>
 
 #ifdef CONFIG_X86_64BITMODE
 #define ELFSIZE 64
@@ -382,6 +383,8 @@ void free_all_dom_mem(struct task_struct *p)
 
     INIT_LIST_HEAD(&zombies);
 
+    if ( p->mm.shadow_mode ) shadow_mode_disable(p);
+
     /* STEP 1. Drop the in-use reference to the page-table base. */
     put_page_and_type(&frame_table[pagetable_val(p->mm.pagetable) >>
                                   PAGE_SHIFT]);
index edba5c02de7f74b7cc823c303589e07643fe8151..b7896e3cfbccffc941d3148f242c0a195b6450a8 100644 (file)
@@ -770,7 +770,14 @@ void free_page_type(struct pfn_info *page, unsigned int type)
             (get_shadow_status(&current->mm, 
                                page-frame_table) & PSH_shadowed) )
        {
-           unshadow_table( page-frame_table, type );
+           /* using 'current-mm' is safe because page type changes only
+              occur within the context of the currently running domain as 
+              pagetable pages can not be shared across domains. The one
+              exception is when destroying a domain. However, we get away 
+              with this as there's no way the current domain can have this
+              mfn shadowed, so we won't get here... Phew! */
+
+           unshadow_table( page-frame_table, type );
            put_shadow_status(&current->mm);
         }
        return;
index fcdf8603518541bd3d7470dc87ebad408cb8c4e5..6692bacaa3c3aa094f395988a3d76fe6cf610c77 100644 (file)
@@ -283,7 +283,13 @@ long do_sched_op(unsigned long op)
 }
 
 
-/* sched_pause_sync - synchronously pause a domain's execution */
+/* sched_pause_sync - synchronously pause a domain's execution 
+
+XXXX This is horibly broken -- here just as a place holder at present,
+                               do not use.
+
+*/
+
 void sched_pause_sync(struct task_struct *p)
 {
     unsigned long flags;
@@ -293,7 +299,7 @@ void sched_pause_sync(struct task_struct *p)
 
     if ( schedule_data[cpu].curr != p )
         /* if not the current task, we can remove it from scheduling now */
-        SCHED_FN(pause, p);
+        SCHED_OP(pause, p);
 
     p->state = TASK_PAUSED;
     
index 8e7b53db8689e17a537bb737429aca772f5c5075..14d395cbf7f44a3fa43406608c1911ea96b6f4b2 100644 (file)
@@ -225,7 +225,7 @@ nomem:
     return -ENOMEM;
 }
 
-static void shadow_mode_disable( struct task_struct *p )
+void shadow_mode_disable( struct task_struct *p )
 {
     struct mm_struct *m = &p->mm;
     struct shadow_status *next;
@@ -353,144 +353,6 @@ static inline struct pfn_info *alloc_shadow_page( struct mm_struct *m )
     return alloc_domain_page( NULL );
 }
 
-/************************************************************************/
-
-static inline void mark_dirty( struct mm_struct *m, unsigned int mfn )
-{
-       unsigned int pfn = machine_to_phys_mapping[mfn];
-       ASSERT(m->shadow_dirty_bitmap);
-       if( likely(pfn<m->shadow_dirty_bitmap_size) )
-       {
-               // XXX use setbit
-               m->shadow_dirty_bitmap[pfn/(sizeof(int)*8)] |= 
-                       (1<<(pfn%(sizeof(int)*8)));
-       }
-       else
-       {
-               printk("XXXX mark dirty overflow!");
-       }
-
-}
-
-/************************************************************************/
-
-static inline void l1pte_write_fault( struct mm_struct *m, 
-                                                                         unsigned long *gpte_p, unsigned long *spte_p )
-{ 
-    unsigned long gpte = *gpte_p;
-    unsigned long spte = *spte_p;
-
-    switch( m->shadow_mode )
-    {
-    case SHM_test:
-               spte = gpte;
-               gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
-               spte |= _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;                        
-               break;
-
-    case SHM_logdirty:
-               spte = gpte;
-               gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
-               spte |= _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;                        
-               mark_dirty( m, gpte >> PAGE_SHIFT );
-               break;
-    }
-
-    *gpte_p = gpte;
-    *spte_p = spte;
-}
-
-static inline void l1pte_read_fault( struct mm_struct *m, 
-                                                                        unsigned long *gpte_p, unsigned long *spte_p )
-{ 
-    unsigned long gpte = *gpte_p;
-    unsigned long spte = *spte_p;
-
-    switch( m->shadow_mode )
-    {
-    case SHM_test:
-               spte = gpte;
-               gpte |= _PAGE_ACCESSED;
-               spte |= _PAGE_ACCESSED;                         
-               if ( ! (gpte & _PAGE_DIRTY ) )
-                       spte &= ~ _PAGE_RW;
-               break;
-
-    case SHM_logdirty:
-               spte = gpte;
-               gpte |= _PAGE_ACCESSED;
-               spte |= _PAGE_ACCESSED;                         
-               spte &= ~ _PAGE_RW;
-               break;
-    }
-
-    *gpte_p = gpte;
-    *spte_p = spte;
-}
-
-static inline void l1pte_no_fault( struct mm_struct *m, 
-                                                                  unsigned long *gpte_p, unsigned long *spte_p )
-{ 
-    unsigned long gpte = *gpte_p;
-    unsigned long spte = *spte_p;
-
-    switch( m->shadow_mode )
-    {
-    case SHM_test:
-               spte = 0;
-               if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
-                        (_PAGE_PRESENT|_PAGE_ACCESSED) )
-               {
-                       spte = gpte;
-                       if ( ! (gpte & _PAGE_DIRTY ) )
-                               spte &= ~ _PAGE_RW;
-               }
-               break;
-
-    case SHM_logdirty:
-               spte = 0;
-               if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
-                        (_PAGE_PRESENT|_PAGE_ACCESSED) )
-               {
-                       spte = gpte;
-                       spte &= ~ _PAGE_RW;
-               }
-
-               break;
-    }
-
-    *gpte_p = gpte;
-    *spte_p = spte;
-}
-
-static inline void l2pde_general( struct mm_struct *m, 
-                          unsigned long *gpde_p, unsigned long *spde_p,
-                          unsigned long sl1pfn)
-{
-    unsigned long gpde = *gpde_p;
-    unsigned long spde = *spde_p;
-
-       spde = 0;
-
-       if ( sl1pfn )
-       {
-               spde = (gpde & ~PAGE_MASK) | (sl1pfn<<PAGE_SHIFT) | 
-                       _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
-               gpde = gpde | _PAGE_ACCESSED | _PAGE_DIRTY;
-
-               if ( unlikely( (sl1pfn<<PAGE_SHIFT) == (gpde & PAGE_MASK)  ) )
-               {   
-                       // detect linear map, and keep pointing at guest
-                       SH_VLOG("4c: linear mapping ( %08lx )",sl1pfn);
-                       spde = gpde & ~_PAGE_RW;
-               }
-       }
-
-    *gpde_p = gpde;
-    *spde_p = spde;
-}
-
-/*********************************************************************/
 
 void unshadow_table( unsigned long gpfn, unsigned int type )
 {
index 0f4e2e19d46bb35f3e07ee3a0fcbe6b44d22a22d..f5c0d5327aff8fdf44693d172d4dd9e486358249 100644 (file)
@@ -31,6 +31,7 @@ extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte,
 extern void shadow_l2_normal_pt_update( unsigned long pa, unsigned long gpte );
 extern void unshadow_table( unsigned long gpfn, unsigned int type );
 extern int shadow_mode_enable( struct task_struct *p, unsigned int mode );
+extern void shadow_mode_disable( struct task_struct *p );
 extern unsigned long shadow_l2_table( 
                      struct mm_struct *m, unsigned long gpfn );
 
@@ -73,6 +74,146 @@ struct shadow_status {
 
 
 
+/************************************************************************/
+
+static inline void mark_dirty( struct mm_struct *m, unsigned int mfn )
+{
+       unsigned int pfn = machine_to_phys_mapping[mfn];
+       ASSERT(m->shadow_dirty_bitmap);
+       if( likely(pfn<m->shadow_dirty_bitmap_size) )
+       {
+               // use setbit to be smp guest safe
+               set_bit( pfn, m->shadow_dirty_bitmap );
+       }
+       else
+       {
+               SH_LOG("mark_dirty pfn out of range attempt!");
+       }
+
+}
+
+/************************************************************************/
+
+static inline void l1pte_write_fault( struct mm_struct *m, 
+                                                                         unsigned long *gpte_p, unsigned long *spte_p )
+{ 
+    unsigned long gpte = *gpte_p;
+    unsigned long spte = *spte_p;
+
+    switch( m->shadow_mode )
+    {
+    case SHM_test:
+               spte = gpte;
+               gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
+               spte |= _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;                        
+               break;
+
+    case SHM_logdirty:
+               spte = gpte;
+               gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
+               spte |= _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;                        
+               mark_dirty( m, gpte >> PAGE_SHIFT );
+               break;
+    }
+
+    *gpte_p = gpte;
+    *spte_p = spte;
+}
+
+static inline void l1pte_read_fault( struct mm_struct *m, 
+                                                                        unsigned long *gpte_p, unsigned long *spte_p )
+{ 
+    unsigned long gpte = *gpte_p;
+    unsigned long spte = *spte_p;
+
+    switch( m->shadow_mode )
+    {
+    case SHM_test:
+               spte = gpte;
+               gpte |= _PAGE_ACCESSED;
+               spte |= _PAGE_ACCESSED;                         
+               if ( ! (gpte & _PAGE_DIRTY ) )
+                       spte &= ~ _PAGE_RW;
+               break;
+
+    case SHM_logdirty:
+               spte = gpte;
+               gpte |= _PAGE_ACCESSED;
+               spte |= _PAGE_ACCESSED;                         
+               spte &= ~ _PAGE_RW;
+               break;
+    }
+
+    *gpte_p = gpte;
+    *spte_p = spte;
+}
+
+static inline void l1pte_no_fault( struct mm_struct *m, 
+                                                                  unsigned long *gpte_p, unsigned long *spte_p )
+{ 
+    unsigned long gpte = *gpte_p;
+    unsigned long spte = *spte_p;
+
+    switch( m->shadow_mode )
+    {
+    case SHM_test:
+               spte = 0;
+               if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
+                        (_PAGE_PRESENT|_PAGE_ACCESSED) )
+               {
+                       spte = gpte;
+                       if ( ! (gpte & _PAGE_DIRTY ) )
+                               spte &= ~ _PAGE_RW;
+               }
+               break;
+
+    case SHM_logdirty:
+               spte = 0;
+               if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
+                        (_PAGE_PRESENT|_PAGE_ACCESSED) )
+               {
+                       spte = gpte;
+                       spte &= ~ _PAGE_RW;
+               }
+
+               break;
+    }
+
+    *gpte_p = gpte;
+    *spte_p = spte;
+}
+
+static inline void l2pde_general( struct mm_struct *m, 
+                          unsigned long *gpde_p, unsigned long *spde_p,
+                          unsigned long sl1pfn)
+{
+    unsigned long gpde = *gpde_p;
+    unsigned long spde = *spde_p;
+
+       spde = 0;
+
+       if ( sl1pfn )
+       {
+               spde = (gpde & ~PAGE_MASK) | (sl1pfn<<PAGE_SHIFT) | 
+                       _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
+               gpde = gpde | _PAGE_ACCESSED | _PAGE_DIRTY;
+
+               if ( unlikely( (sl1pfn<<PAGE_SHIFT) == (gpde & PAGE_MASK)  ) )
+               {   
+                       // detect linear map, and keep pointing at guest
+                       SH_VLOG("4c: linear mapping ( %08lx )",sl1pfn);
+                       spde = gpde & ~_PAGE_RW;
+               }
+       }
+
+    *gpde_p = gpde;
+    *spde_p = spde;
+}
+
+/*********************************************************************/
+
+
+
 #if SHADOW_HASH_DEBUG
 static void shadow_audit(struct mm_struct *m, int print)
 {