ia64/xen-unstable

changeset 2599:0dfd459518e4

bitkeeper revision 1.1159.1.205 (4162aff3DKXHUIthGYqb0hkSmWnxQw)

Clean up memory auditing, and always an audit a domain before
destroying it. (debug builds only)
author kaf24@freefall.cl.cam.ac.uk
date Tue Oct 05 14:30:11 2004 +0000 (2004-10-05)
parents 92fff25bf21e
children 04af8bd15884
files xen/arch/x86/domain.c xen/arch/x86/memory.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Tue Oct 05 10:47:20 2004 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Tue Oct 05 14:30:11 2004 +0000
     1.3 @@ -529,6 +529,8 @@ static void relinquish_list(struct domai
     1.4  
     1.5  void domain_relinquish_memory(struct domain *d)
     1.6  {
     1.7 +    audit_domain(d);
     1.8 +
     1.9      /* Ensure that noone is running over the dead domain's page tables. */
    1.10      synchronise_pagetables(~0UL);
    1.11  
     2.1 --- a/xen/arch/x86/memory.c	Tue Oct 05 10:47:20 2004 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Tue Oct 05 14:30:11 2004 +0000
     2.3 @@ -1864,10 +1864,11 @@ void ptwr_status(void)
     2.4  /************************************************************************/
     2.5  
     2.6  
     2.7 -void audit_domain( struct domain *d)
     2.8 +void audit_domain(struct domain *d)
     2.9  {
    2.10      int ttot=0, ctot=0, io_mappings=0, lowmem_mappings=0;
    2.11 -    void adjust ( struct pfn_info *page, int dir, int adjtype )
    2.12 +
    2.13 +    void adjust (struct pfn_info *page, int dir, int adjtype)
    2.14      {
    2.15          int count = page->count_info & PGC_count_mask;
    2.16  
    2.17 @@ -1881,8 +1882,9 @@ void audit_domain( struct domain *d)
    2.18  
    2.19              if ( tcount < 0 )
    2.20              {
    2.21 -		// This will only come out once
    2.22 -                printk("Audit %d: type count whent below zero pfn=%x taf=%x otaf=%x\n",
    2.23 +		/* This will only come out once. */
    2.24 +                printk("Audit %d: type count whent below zero pfn=%x "
    2.25 +                       "taf=%x otaf=%x\n",
    2.26                         d->domain, page-frame_table,
    2.27                         page->u.inuse.type_info,
    2.28                         page->tlbflush_timestamp);
    2.29 @@ -1897,8 +1899,9 @@ void audit_domain( struct domain *d)
    2.30          count += dir;
    2.31          if ( count < 0 )
    2.32          {
    2.33 -	    // This will only come out once
    2.34 -            printk("Audit %d: general count whent below zero pfn=%x taf=%x otaf=%x\n",
    2.35 +	    /* This will only come out once. */
    2.36 +            printk("Audit %d: general count whent below zero pfn=%x "
    2.37 +                   "taf=%x otaf=%x\n",
    2.38                     d->domain, page-frame_table,
    2.39                     page->u.inuse.type_info,
    2.40                     page->tlbflush_timestamp);
    2.41 @@ -1910,41 +1913,30 @@ void audit_domain( struct domain *d)
    2.42  
    2.43      }
    2.44  
    2.45 -    void scan_for_pfn( struct domain *d, unsigned long xpfn )
    2.46 +    void scan_for_pfn(struct domain *d, unsigned long xpfn)
    2.47      {
    2.48 -        unsigned long pfn;
    2.49 +        unsigned long pfn, *pt;
    2.50          struct list_head *list_ent;
    2.51 +        struct pfn_info *page;
    2.52          int i;
    2.53  
    2.54          list_ent = d->page_list.next;
    2.55          for ( i = 0; (list_ent != &d->page_list); i++ )
    2.56          {
    2.57 -            unsigned long * pt;
    2.58 -            struct pfn_info *page;
    2.59              pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
    2.60              page = &frame_table[pfn];
    2.61              
    2.62 -            if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table ||
    2.63 -                 (page->u.inuse.type_info & PGT_type_mask) == PGT_l2_page_table )
    2.64 +            switch ( page->u.inuse.type_info & PGT_type_mask )
    2.65              {
    2.66 -                pt = map_domain_mem( pfn<<PAGE_SHIFT );
    2.67 -
    2.68 +            case PGT_l1_page_table:
    2.69 +            case PGT_l2_page_table:
    2.70 +                pt = map_domain_mem(pfn<<PAGE_SHIFT);
    2.71                  for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
    2.72 -                {
    2.73 -                    if ( pt[i] & _PAGE_PRESENT )
    2.74 -                    {
    2.75 -                        unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
    2.76 -                        
    2.77 -                        if ( l1pfn == xpfn )
    2.78 -                        {
    2.79 -                            printk("        found dom=%d i=%x pfn=%lx t=%x c=%x\n",
    2.80 -                                   d->domain,
    2.81 -                                   i,pfn,page->u.inuse.type_info,
    2.82 -                                   page->count_info);
    2.83 -                        }
    2.84 -                    }
    2.85 -                }
    2.86 -
    2.87 +                    if ( (pt[i] & _PAGE_PRESENT) &&
    2.88 +                         ((pt[i] >> PAGE_SHIFT) == xpfn) )
    2.89 +                        printk("     found dom=%d i=%x pfn=%lx t=%x c=%x\n",
    2.90 +                               d->domain, i, pfn, page->u.inuse.type_info,
    2.91 +                               page->count_info);
    2.92                  unmap_domain_mem(pt);           
    2.93              }
    2.94  
    2.95 @@ -1953,19 +1945,17 @@ void audit_domain( struct domain *d)
    2.96  
    2.97      }
    2.98  
    2.99 -    void scan_for_pfn_remote( unsigned long xpfn )
   2.100 +    void scan_for_pfn_remote(unsigned long xpfn)
   2.101      {
   2.102          struct domain *e;
   2.103 -
   2.104          for_each_domain ( e )
   2.105 -        {
   2.106              scan_for_pfn( e, xpfn );            
   2.107 -        }
   2.108      }   
   2.109  
   2.110      int i;
   2.111      unsigned long pfn;
   2.112      struct list_head *list_ent;
   2.113 +    struct pfn_info *page;
   2.114  
   2.115      if ( d != current )
   2.116          domain_pause(d);
   2.117 @@ -1977,12 +1967,11 @@ void audit_domain( struct domain *d)
   2.118             
   2.119      spin_lock(&d->page_alloc_lock);
   2.120  
   2.121 -    /* phase 0 */
   2.122 +    /* PHASE 0 */
   2.123  
   2.124      list_ent = d->page_list.next;
   2.125      for ( i = 0; (list_ent != &d->page_list); i++ )
   2.126      {
   2.127 -        struct pfn_info *page;
   2.128          pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;       
   2.129          page = &frame_table[pfn];
   2.130  
   2.131 @@ -1994,7 +1983,7 @@ void audit_domain( struct domain *d)
   2.132              printk("taf > caf %x %x pfn=%lx\n",
   2.133                     page->u.inuse.type_info, page->count_info, pfn );
   2.134   
   2.135 -#if 0   // SYSV shared memory pages plus writeable files
   2.136 +#if 0   /* SYSV shared memory pages plus writeable files. */
   2.137          if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page && 
   2.138               (page->u.inuse.type_info & PGT_count_mask) > 1 )
   2.139          {
   2.140 @@ -2014,22 +2003,21 @@ void audit_domain( struct domain *d)
   2.141                    page->count_info );
   2.142          }
   2.143  
   2.144 -        // use tlbflush_timestamp to store original type_info
   2.145 +        /* Use tlbflush_timestamp to store original type_info. */
   2.146          page->tlbflush_timestamp = page->u.inuse.type_info;
   2.147  
   2.148          list_ent = frame_table[pfn].list.next;
   2.149      }
   2.150  
   2.151  
   2.152 -    /* phase 1 */
   2.153 +    /* PHASE 1 */
   2.154  
   2.155 -    adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1 );
   2.156 +    adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1);
   2.157  
   2.158      list_ent = d->page_list.next;
   2.159      for ( i = 0; (list_ent != &d->page_list); i++ )
   2.160      {
   2.161 -        unsigned long * pt;
   2.162 -        struct pfn_info *page;
   2.163 +        unsigned long *pt;
   2.164          pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;       
   2.165          page = &frame_table[pfn];
   2.166  
   2.167 @@ -2061,42 +2049,26 @@ void audit_domain( struct domain *d)
   2.168  
   2.169                      if ( l1page->u.inuse.domain != d )
   2.170                      {
   2.171 -                        printk("L2: Skip bizare page belowing to other dom %p\n",
   2.172 -                               l1page->u.inuse.domain);    
   2.173 +                        printk("L2: Skip bizarre page belonging to other "
   2.174 +                               "dom %p\n", l1page->u.inuse.domain);    
   2.175                          continue;
   2.176                      }
   2.177 +                    
   2.178 +                    if ( (l1page->u.inuse.type_info & PGT_type_mask) ==
   2.179 +                         PGT_l2_page_table )
   2.180 +                        printk("Audit %d: [%x] Found %s Linear PT "
   2.181 +                               "t=%x pfn=%lx\n", d->domain, i, 
   2.182 +                               (l1pfn==pfn) ? "Self" : "Other",
   2.183 +                               l1page->u.inuse.type_info,
   2.184 +                               l1pfn);
   2.185 +                    else if ( (l1page->u.inuse.type_info & PGT_type_mask) !=
   2.186 +                              PGT_l1_page_table )
   2.187 +                        printk("Audit %d: [%x] Expected L1 t=%x pfn=%lx\n",
   2.188 +                               d->domain, i,
   2.189 +                               l1page->u.inuse.type_info,
   2.190 +                               l1pfn);
   2.191  
   2.192 -                    if ( (l1page->u.inuse.type_info & PGT_type_mask) !=
   2.193 -                         PGT_l1_page_table )
   2.194 -		    {
   2.195 -			if( (l1page->u.inuse.type_info & PGT_type_mask) ==
   2.196 -			    PGT_l2_page_table )
   2.197 -			{
   2.198 -			    if( l1pfn == pfn )			    
   2.199 -			    {
   2.200 -				printk("Audit %d: [%x] Found Self Linear PT t=%x pfn=%lx\n",
   2.201 -				       d->domain, i,
   2.202 -				       l1page->u.inuse.type_info,
   2.203 -				       l1pfn);
   2.204 -			    }
   2.205 -			    else
   2.206 -			    {
   2.207 -				printk("Audit %d: [%x] Found Other Linear PT t=%x pfn=%lx\n",
   2.208 -				       d->domain, i,
   2.209 -				       l1page->u.inuse.type_info,
   2.210 -				       l1pfn);
   2.211 -			    }
   2.212 -			}
   2.213 -			else
   2.214 -			{
   2.215 -			    printk("Audit %d: [%x] Expected L1 t=%x pfn=%lx\n",
   2.216 -				   d->domain, i,
   2.217 -				   l1page->u.inuse.type_info,
   2.218 -				   l1pfn);
   2.219 -			}
   2.220 -
   2.221 -		    }
   2.222 -                    adjust( l1page, -1, 1 );
   2.223 +                    adjust(l1page, -1, 1);
   2.224                  }
   2.225              }
   2.226  
   2.227 @@ -2108,10 +2080,7 @@ void audit_domain( struct domain *d)
   2.228          case PGT_l1_page_table:
   2.229              
   2.230              if ( (page->u.inuse.type_info & PGT_pinned) == PGT_pinned )
   2.231 -            {
   2.232 -                //printk("L1 is pinned\n");
   2.233                  adjust( page, -1, 1 );
   2.234 -            }
   2.235  
   2.236              if ( (page->u.inuse.type_info & PGT_validated) != PGT_validated )
   2.237                  printk("Audit %d: L1 not validated %x\n",
   2.238 @@ -2158,7 +2127,8 @@ void audit_domain( struct domain *d)
   2.239  
   2.240                      if ( l1page->u.inuse.domain != d )
   2.241                      {
   2.242 -                        printk("Audit %d: [%lx,%x] Skip foreign page dom=%lx pfn=%lx c=%08x t=%08x m2p=%lx\n",
   2.243 +                        printk("Audit %d: [%lx,%x] Skip foreign page dom=%lx "
   2.244 +                               "pfn=%lx c=%08x t=%08x m2p=%lx\n",
   2.245  			       d->domain, pfn, i,
   2.246                                 (unsigned long)l1page->u.inuse.domain,
   2.247  			       l1pfn,
   2.248 @@ -2168,7 +2138,7 @@ void audit_domain( struct domain *d)
   2.249                          continue;
   2.250                      }
   2.251  
   2.252 -                    adjust( l1page, -1, 0 );
   2.253 +                    adjust(l1page, -1, 0);
   2.254                  }
   2.255              }
   2.256  
   2.257 @@ -2180,22 +2150,19 @@ void audit_domain( struct domain *d)
   2.258          list_ent = frame_table[pfn].list.next;
   2.259      }
   2.260  
   2.261 -    if ( io_mappings>0 || lowmem_mappings>0 )
   2.262 +    if ( (io_mappings > 0) || (lowmem_mappings > 0) )
   2.263  	printk("Audit %d: Found %d lowmem mappings and %d io mappings\n",
   2.264  	       d->domain, lowmem_mappings, io_mappings);
   2.265  
   2.266 -    /* phase 2 */
   2.267 +    /* PHASE 2 */
   2.268  
   2.269      ctot = ttot = 0;
   2.270      list_ent = d->page_list.next;
   2.271      for ( i = 0; (list_ent != &d->page_list); i++ )
   2.272      {
   2.273 -        struct pfn_info *page;
   2.274          pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
   2.275 -        
   2.276          page = &frame_table[pfn];
   2.277  
   2.278 -
   2.279          switch ( page->u.inuse.type_info & PGT_type_mask)
   2.280          {
   2.281          case PGT_l1_page_table:
   2.282 @@ -2211,7 +2178,7 @@ void audit_domain( struct domain *d)
   2.283          default:
   2.284              if ( (page->count_info & PGC_count_mask) != 1 )
   2.285              {
   2.286 -                printk("Audit %d: general count!=1 (c=%x) t=%x ot=%x pfn=%lx\n",
   2.287 +                printk("Audit %d: gen count!=1 (c=%x) t=%x ot=%x pfn=%lx\n",
   2.288                         d->domain, 
   2.289                         page->count_info,
   2.290                         page->u.inuse.type_info, 
   2.291 @@ -2224,15 +2191,13 @@ void audit_domain( struct domain *d)
   2.292          list_ent = frame_table[pfn].list.next;
   2.293      }
   2.294  
   2.295 -    /* phase 3 */
   2.296 +    /* PHASE 3 */
   2.297  
   2.298      list_ent = d->page_list.next;
   2.299      for ( i = 0; (list_ent != &d->page_list); i++ )
   2.300      {
   2.301 -        unsigned long * pt;
   2.302 -        struct pfn_info *page;
   2.303 +        unsigned long *pt;
   2.304          pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
   2.305 -        
   2.306          page = &frame_table[pfn];
   2.307  
   2.308          switch ( page->u.inuse.type_info & PGT_type_mask )
   2.309 @@ -2251,7 +2216,7 @@ void audit_domain( struct domain *d)
   2.310                      struct pfn_info *l1page = &frame_table[l1pfn];
   2.311  
   2.312                      if ( l1page->u.inuse.domain == d)
   2.313 -                        adjust( l1page, 1, 1 );
   2.314 +                        adjust(l1page, 1, 1);
   2.315                  }
   2.316              }
   2.317  
   2.318 @@ -2268,17 +2233,14 @@ void audit_domain( struct domain *d)
   2.319              {
   2.320                  if ( pt[i] & _PAGE_PRESENT )
   2.321                  {
   2.322 -#if 1
   2.323 -
   2.324                      unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
   2.325                      struct pfn_info *l1page = &frame_table[l1pfn];
   2.326  
   2.327 -                    if ( l1page->u.inuse.domain != d) continue;
   2.328 -		    if ( l1pfn < 0x100 ) continue;
   2.329 -		    if ( l1pfn > max_page ) continue;
   2.330 +                    if ( (l1page->u.inuse.domain != d) ||
   2.331 +                         (l1pfn < 0x100) || (l1pfn > max_page) )
   2.332 +                        continue;
   2.333  
   2.334 -		    adjust( l1page, 1, 0 );
   2.335 -#endif
   2.336 +		    adjust(l1page, 1, 0);
   2.337                  }
   2.338              }
   2.339  
   2.340 @@ -2287,15 +2249,14 @@ void audit_domain( struct domain *d)
   2.341          }
   2.342  
   2.343  
   2.344 -        page->tlbflush_timestamp = 0; // put back
   2.345 -
   2.346 +        page->tlbflush_timestamp = 0;
   2.347  
   2.348          list_ent = frame_table[pfn].list.next;
   2.349      }
   2.350  
   2.351      spin_unlock(&d->page_alloc_lock);
   2.352  
   2.353 -    adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1 );
   2.354 +    adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1);
   2.355  
   2.356      printk("Audit %d: Done. ctot=%d ttot=%d\n",d->domain, ctot, ttot );
   2.357  
   2.358 @@ -2303,22 +2264,18 @@ void audit_domain( struct domain *d)
   2.359          domain_unpause(d);
   2.360  }
   2.361  
   2.362 -
   2.363  void audit_domains(void)
   2.364  {
   2.365      struct domain *d;
   2.366 -
   2.367      for_each_domain ( d )
   2.368 -    {
   2.369  	audit_domain(d);
   2.370 -    }
   2.371  }
   2.372  
   2.373  void audit_domains_key(unsigned char key, void *dev_id,
   2.374                         struct pt_regs *regs)
   2.375  {
   2.376 -    open_softirq( MEMAUDIT_SOFTIRQ, audit_domains );
   2.377 -    raise_softirq( MEMAUDIT_SOFTIRQ );
   2.378 +    open_softirq(MEMAUDIT_SOFTIRQ, audit_domains);
   2.379 +    raise_softirq(MEMAUDIT_SOFTIRQ);
   2.380  }
   2.381  
   2.382  
     3.1 --- a/xen/include/asm-x86/mm.h	Tue Oct 05 10:47:20 2004 +0000
     3.2 +++ b/xen/include/asm-x86/mm.h	Tue Oct 05 14:30:11 2004 +0000
     3.3 @@ -290,4 +290,12 @@ do {                                    
     3.4          __cleanup_writable_pagetable(_w);                                 \
     3.5      } while ( 0 )
     3.6  
     3.7 +#ifndef NDEBUG
     3.8 +void audit_domain(struct domain *d);
     3.9 +void audit_domains(void);
    3.10 +#else
    3.11 +#define audit_domain(_d) ((void)0)
    3.12 +#define audit_domains()  ((void)0)
    3.13 +#endif
    3.14 +
    3.15  #endif /* __ASM_X86_MM_H__ */