ia64/xen-unstable

changeset 2441:2bbaf6d19a35

bitkeeper revision 1.1159.69.21 (413c9be3ZggtSn3FWCDWCAl_6chs9w)

keyhandler to perform a debug audit of domain memory, checking the page type and
counts are consistent with the pagetable state. Its quite verbose and
prints out details of all interesting pages.
(e.g. pages shared between domains or used for LDT/GDTs).
author iap10@labyrinth.cl.cam.ac.uk
date Mon Sep 06 17:18:27 2004 +0000 (2004-09-06)
parents f084fe1dc76b
children d9439135569e
files xen/Rules.mk xen/arch/x86/memory.c xen/arch/x86/traps.c xen/common/keyhandler.c xen/common/page_alloc.c xen/include/xen/softirq.h
line diff
     1.1 --- a/xen/Rules.mk	Mon Sep 06 14:46:01 2004 +0000
     1.2 +++ b/xen/Rules.mk	Mon Sep 06 17:18:27 2004 +0000
     1.3 @@ -1,4 +1,5 @@
     1.4  
     1.5 +verbose     ?= n
     1.6  debug       ?= n
     1.7  debugger    ?= n
     1.8  perfc       ?= n
     2.1 --- a/xen/arch/x86/memory.c	Mon Sep 06 14:46:01 2004 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Mon Sep 06 17:18:27 2004 +0000
     2.3 @@ -92,6 +92,7 @@
     2.4  #include <xen/errno.h>
     2.5  #include <xen/perfc.h>
     2.6  #include <xen/irq.h>
     2.7 +#include <xen/softirq.h>
     2.8  #include <asm/shadow.h>
     2.9  #include <asm/page.h>
    2.10  #include <asm/flushtlb.h>
    2.11 @@ -779,6 +780,9 @@ int alloc_page_type(struct pfn_info *pag
    2.12      case PGT_ldt_page:
    2.13          return alloc_segdesc_page(page);
    2.14      default:
    2.15 +	printk("Bad type in alloc_page_type %x t=%x c=%x\n", 
    2.16 +	       type, page->u.inuse.type_info,
    2.17 +	       page->count_info);
    2.18          BUG();
    2.19      }
    2.20  
    2.21 @@ -1789,4 +1793,420 @@ void ptwr_status(void)
    2.22                   frame_table[pfn].u.inuse.type_info,
    2.23                   frame_table[pfn].u.inuse.domain->domain));
    2.24  }
    2.25 +
    2.26 +
    2.27 +/************************************************************************/
    2.28 +
    2.29 +
    2.30 +void audit_domain( struct domain *d)
    2.31 +{
    2.32 +    int ttot=0, ctot=0;
    2.33 +    void adjust ( struct pfn_info *page, int dir, int adjtype )
    2.34 +    {
    2.35 +	int count = page->count_info & PGC_count_mask;
    2.36 +
    2.37 +	if (adjtype)
    2.38 +	{
    2.39 +	    int tcount = page->u.inuse.type_info & PGT_count_mask;
    2.40 +	    
    2.41 +	    ttot++;
    2.42 +
    2.43 +	    tcount += dir;
    2.44 +
    2.45 +	    if (tcount <0 )
    2.46 +	    {
    2.47 +		printk("Audit %d: type count whent below zero pfn=%x taf=%x otaf=%x\n",
    2.48 +		       d->domain, page-frame_table,
    2.49 +		       page->u.inuse.type_info,
    2.50 +		       page->tlbflush_timestamp);
    2.51 +		return;
    2.52 +	    }
    2.53 +	    
    2.54 +	    page->u.inuse.type_info =
    2.55 +		(page->u.inuse.type_info & ~PGT_count_mask) | tcount;	    
    2.56 +	}
    2.57 +
    2.58 +	ctot++;
    2.59 +	count += dir;
    2.60 +	if (count <0 )
    2.61 +	{
    2.62 +	    printk("Audit %d: general count whent below zero pfn=%x taf=%x otaf=%x\n",
    2.63 +		   d->domain, page-frame_table,
    2.64 +		   page->u.inuse.type_info,
    2.65 +		   page->tlbflush_timestamp);
    2.66 +	    return;
    2.67 +	}
    2.68 +	    
    2.69 +	page->count_info =
    2.70 +	    (page->count_info & ~PGC_count_mask) | count;	    
    2.71 +
    2.72 +    }
    2.73 +
    2.74 +    void scan_for_pfn( struct domain *d, unsigned long xpfn )
    2.75 +    {
    2.76 +	unsigned long pfn;
    2.77 +	struct list_head *list_ent;
    2.78 +	int i;
    2.79 +
    2.80 +        list_ent = d->page_list.next;
    2.81 +	for ( i = 0; (list_ent != &d->page_list); i++ )
    2.82 +	{
    2.83 +	    unsigned long * pt;
    2.84 +	    struct pfn_info *page;
    2.85 +	    pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
    2.86 +	    page = &frame_table[pfn];
    2.87 +	    
    2.88 +	    if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table ||
    2.89 +		 (page->u.inuse.type_info & PGT_type_mask) == PGT_l2_page_table )
    2.90 +	    {
    2.91 +		pt = map_domain_mem( pfn<<PAGE_SHIFT );
    2.92 +
    2.93 +		for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
    2.94 +		{
    2.95 +		    if ( pt[i] & _PAGE_PRESENT )
    2.96 +		    {
    2.97 +			unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
    2.98 +			
    2.99 +			if( l1pfn == xpfn )
   2.100 +			{
   2.101 +			    printk("        found dom=%d i=%x pfn=%lx t=%x c=%x\n",
   2.102 +				   d->domain,
   2.103 +				   i,pfn,page->u.inuse.type_info,
   2.104 +				   page->count_info);
   2.105 +			}
   2.106 +		    }
   2.107 +		}
   2.108 +
   2.109 +		unmap_domain_mem(pt);	   
   2.110 +	    }
   2.111 +
   2.112 +	    list_ent = frame_table[pfn].list.next;
   2.113 +	}
   2.114 +
   2.115 +    }
   2.116 +
   2.117 +    void scan_for_pfn_remote( unsigned long xpfn )
   2.118 +    {
   2.119 +	struct domain *e;
   2.120 +
   2.121 +	for_each_domain ( e )
   2.122 +	{
   2.123 +	    scan_for_pfn( e, xpfn );	    
   2.124 +	}
   2.125 +    }   
   2.126 +
   2.127 +    int i;
   2.128 +    unsigned long pfn;
   2.129 +    struct list_head *list_ent;
   2.130 +
   2.131 +    if(d!=current)domain_pause(d);
   2.132 +    synchronise_pagetables(~0UL);
   2.133 +
   2.134 +    printk("pt base=%lx sh_info=%x\n",
   2.135 +	   pagetable_val(d->mm.pagetable)>>PAGE_SHIFT,
   2.136 +	   virt_to_page(d->shared_info)-frame_table);
   2.137 +	   
   2.138 +    spin_lock(&d->page_alloc_lock);
   2.139 +
   2.140 +    /* phase 0 */
   2.141 +
   2.142 +    list_ent = d->page_list.next;
   2.143 +    for ( i = 0; (list_ent != &d->page_list); i++ )
   2.144 +    {
   2.145 +	struct pfn_info *page;
   2.146 +	pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;       
   2.147 +	page = &frame_table[pfn];
   2.148 +
   2.149 +	if ( page->u.inuse.domain != d )
   2.150 +	    BUG();
   2.151 +
   2.152 +	if ( (page->u.inuse.type_info & PGT_count_mask) >
   2.153 +	     (page->count_info & PGC_count_mask) )
   2.154 +	    printk("taf > caf %x %x pfn=%lx\n",
   2.155 +		   page->u.inuse.type_info, page->count_info, pfn );
   2.156 + 
   2.157 +#if 0   // SYSV shared memory pages plus writeable files
   2.158 +	if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page && 
   2.159 +	     (page->u.inuse.type_info & PGT_count_mask) > 1 )
   2.160 +	{
   2.161 +	    printk("writeable page with type count >1: pfn=%lx t=%x c=%x\n",
   2.162 +		  pfn,
   2.163 +		  page->u.inuse.type_info,
   2.164 +		  page->count_info );
   2.165 +	    scan_for_pfn_remote(pfn);
   2.166 +	}
   2.167  #endif
   2.168 +	if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_none && 
   2.169 +	     (page->u.inuse.type_info & PGT_count_mask) > 1 )
   2.170 +	{
   2.171 +	    printk("normal page with type count >1: pfn=%lx t=%x c=%x\n",
   2.172 +		  pfn,
   2.173 +		  page->u.inuse.type_info,
   2.174 +		  page->count_info );
   2.175 +	}
   2.176 +
   2.177 +	// use tlbflush_timestamp to store original type_info
   2.178 +	page->tlbflush_timestamp = page->u.inuse.type_info;
   2.179 +
   2.180 +	list_ent = frame_table[pfn].list.next;
   2.181 +    }
   2.182 +
   2.183 +
   2.184 +    /* phase 1 */
   2.185 +
   2.186 +    adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1 );
   2.187 +
   2.188 +    list_ent = d->page_list.next;
   2.189 +    for ( i = 0; (list_ent != &d->page_list); i++ )
   2.190 +    {
   2.191 +	unsigned long * pt;
   2.192 +	struct pfn_info *page;
   2.193 +	pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;       
   2.194 +	page = &frame_table[pfn];
   2.195 +
   2.196 +	if ( page->u.inuse.domain != d )
   2.197 +	    BUG();
   2.198 +
   2.199 +	switch ( page->u.inuse.type_info & PGT_type_mask )
   2.200 +	{
   2.201 +	case PGT_l2_page_table:
   2.202 +
   2.203 +	    if ((page->u.inuse.type_info & PGT_validated) != PGT_validated )
   2.204 +		printk("Audit %d: L2 not validated %x\n",
   2.205 +		       d->domain, page->u.inuse.type_info);
   2.206 +
   2.207 +	    if ((page->u.inuse.type_info & PGT_pinned) != PGT_pinned )
   2.208 +		printk("Audit %d: L2 not pinned %x\n",
   2.209 +		       d->domain, page->u.inuse.type_info);
   2.210 +	    else
   2.211 +		adjust( page, -1, 1 );
   2.212 +	   
   2.213 +	    pt = map_domain_mem( pfn<<PAGE_SHIFT );
   2.214 +
   2.215 +	    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
   2.216 +	    {
   2.217 +		if ( pt[i] & _PAGE_PRESENT )
   2.218 +		{
   2.219 +		    unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
   2.220 +		    struct pfn_info *l1page = &frame_table[l1pfn];
   2.221 +
   2.222 +		    if (l1page->u.inuse.domain != d)
   2.223 +		    {
   2.224 +			printk("Skip page belowing to other dom %p\n",
   2.225 +			       l1page->u.inuse.domain);    
   2.226 +			continue;
   2.227 +		    }
   2.228 +
   2.229 +		    if ((l1page->u.inuse.type_info & PGT_type_mask) !=
   2.230 +			PGT_l1_page_table )
   2.231 +			printk("Audit %d: [%x] Expected L1 t=%x pfn=%lx\n",
   2.232 +			       d->domain, i,
   2.233 +			       l1page->u.inuse.type_info,
   2.234 +			       l1pfn);
   2.235 +
   2.236 +		    adjust( l1page, -1, 1 );
   2.237 +		}
   2.238 +	    }
   2.239 +
   2.240 +	    unmap_domain_mem(pt);
   2.241 +
   2.242 +	    break;
   2.243 +
   2.244 +
   2.245 +	case PGT_l1_page_table:
   2.246 +	    
   2.247 +	    if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned )
   2.248 +	    {
   2.249 +		//printk("L1 is pinned\n");
   2.250 +		adjust( page, -1, 1 );
   2.251 +	    }
   2.252 +
   2.253 +	    if ((page->u.inuse.type_info & PGT_validated) != PGT_validated )
   2.254 +		printk("Audit %d: L1 not validated %x\n",
   2.255 +		       d->domain, page->u.inuse.type_info);
   2.256 +#if 0
   2.257 +	    if ((page->u.inuse.type_info & PGT_pinned) != PGT_pinned )
   2.258 +		printk("Audit %d: L1 not pinned %x\n",
   2.259 +		       d->domain, page->u.inuse.type_info);
   2.260 +#endif
   2.261 +	    pt = map_domain_mem( pfn<<PAGE_SHIFT );
   2.262 +
   2.263 +	    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
   2.264 +	    {
   2.265 +		if ( pt[i] & _PAGE_PRESENT )
   2.266 +		{
   2.267 +		    unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
   2.268 +		    struct pfn_info *l1page = &frame_table[l1pfn];
   2.269 +
   2.270 +		    if ( pt[i] & _PAGE_RW )
   2.271 +		    {
   2.272 +
   2.273 +			if ((l1page->u.inuse.type_info & PGT_type_mask) ==
   2.274 +			    PGT_l1_page_table ||
   2.275 +			    (l1page->u.inuse.type_info & PGT_type_mask) ==
   2.276 +			    PGT_l2_page_table )
   2.277 +			    printk("Audit %d: [%x] Ilegal RW t=%x pfn=%lx\n",
   2.278 +				   d->domain, i,
   2.279 +				   l1page->u.inuse.type_info,
   2.280 +				   l1pfn);
   2.281 +
   2.282 +		    }
   2.283 +
   2.284 +		    if (l1page->u.inuse.domain != d)
   2.285 +		    {
   2.286 +			printk("Skip page belowing to other dom %p\n",
   2.287 +			       l1page->u.inuse.domain);    
   2.288 +			continue;
   2.289 +		    }
   2.290 +
   2.291 +		    adjust( l1page, -1, 0 );
   2.292 +		}
   2.293 +	    }
   2.294 +
   2.295 +	    unmap_domain_mem(pt);
   2.296 +
   2.297 +	    break;
   2.298 +	}
   2.299 +	
   2.300 +
   2.301 +
   2.302 +	list_ent = frame_table[pfn].list.next;
   2.303 +    }
   2.304 +
   2.305 +    /* phase 2 */
   2.306 +
   2.307 +    ctot = ttot = 0;
   2.308 +    list_ent = d->page_list.next;
   2.309 +    for ( i = 0; (list_ent != &d->page_list); i++ )
   2.310 +    {
   2.311 +	struct pfn_info *page;
   2.312 +	pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
   2.313 +	
   2.314 +	page = &frame_table[pfn];
   2.315 +
   2.316 +
   2.317 +	switch ( page->u.inuse.type_info & PGT_type_mask)
   2.318 +	{
   2.319 +	case PGT_l1_page_table:
   2.320 +	case PGT_l2_page_table:
   2.321 +	    if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
   2.322 +	    {
   2.323 +		printk("Audit %d: type count!=0 t=%x ot=%x c=%x pfn=%lx\n",
   2.324 +		       d->domain, page->u.inuse.type_info, 
   2.325 +		       page->tlbflush_timestamp,
   2.326 +		       page->count_info, pfn );
   2.327 +		scan_for_pfn_remote(pfn);
   2.328 +	    }
   2.329 +	default:
   2.330 +	    if ( (page->count_info & PGC_count_mask) != 1 )
   2.331 +	    {
   2.332 +		printk("Audit %d: general count!=1 (c=%x) t=%x ot=%x pfn=%lx\n",
   2.333 +		       d->domain, 
   2.334 +		       page->count_info,
   2.335 +		       page->u.inuse.type_info, 
   2.336 +		       page->tlbflush_timestamp, pfn );
   2.337 +		scan_for_pfn_remote(pfn);
   2.338 +	    }
   2.339 +	    break;
   2.340 +	}
   2.341 +
   2.342 +	list_ent = frame_table[pfn].list.next;
   2.343 +    }
   2.344 +
   2.345 +    /* phase 3 */
   2.346 +
   2.347 +    list_ent = d->page_list.next;
   2.348 +    for ( i = 0; (list_ent != &d->page_list); i++ )
   2.349 +    {
   2.350 +	unsigned long * pt;
   2.351 +	struct pfn_info *page;
   2.352 +	pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
   2.353 +	
   2.354 +	page = &frame_table[pfn];
   2.355 +
   2.356 +	switch ( page->u.inuse.type_info & PGT_type_mask )
   2.357 +	{
   2.358 +	case PGT_l2_page_table:
   2.359 +	    if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned )
   2.360 +		adjust( page, 1, 1 );	  
   2.361 +
   2.362 +	    pt = map_domain_mem( pfn<<PAGE_SHIFT );
   2.363 +
   2.364 +	    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
   2.365 +	    {
   2.366 +		if ( pt[i] & _PAGE_PRESENT )
   2.367 +		{
   2.368 +		    unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
   2.369 +		    struct pfn_info *l1page = &frame_table[l1pfn];
   2.370 +
   2.371 +		    if ( l1page->u.inuse.domain == d)
   2.372 +			adjust( l1page, 1, 1 );
   2.373 +		}
   2.374 +	    }
   2.375 +
   2.376 +	    unmap_domain_mem(pt);
   2.377 +	    break;
   2.378 +
   2.379 +	case PGT_l1_page_table:
   2.380 +	    if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned )
   2.381 +		adjust( page, 1, 1 );
   2.382 +
   2.383 +	    pt = map_domain_mem( pfn<<PAGE_SHIFT );
   2.384 +
   2.385 +	    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
   2.386 +	    {
   2.387 +		if ( pt[i] & _PAGE_PRESENT )
   2.388 +		{
   2.389 +#if 1
   2.390 +
   2.391 +		    unsigned long l1pfn = pt[i]>>PAGE_SHIFT;
   2.392 +		    struct pfn_info *l1page = &frame_table[l1pfn];
   2.393 +
   2.394 +		    if ( l1page->u.inuse.domain == d)
   2.395 +			adjust( l1page, 1, 0 );
   2.396 +#endif
   2.397 +		}
   2.398 +	    }
   2.399 +
   2.400 +	    unmap_domain_mem(pt);
   2.401 +	    break;
   2.402 +	}
   2.403 +
   2.404 +
   2.405 +	page->tlbflush_timestamp = 0; // put back
   2.406 +
   2.407 +
   2.408 +	list_ent = frame_table[pfn].list.next;
   2.409 +    }
   2.410 +
   2.411 +    spin_unlock(&d->page_alloc_lock);
   2.412 +
   2.413 +    adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1 );
   2.414 +
   2.415 +    printk("Audit %d: Done. ctot=%d ttot=%d\n",d->domain, ctot, ttot );
   2.416 +
   2.417 +    if(d!=current)domain_unpause(d);
   2.418 +
   2.419 +}
   2.420 +
   2.421 +
   2.422 +void audit_domains( void )
   2.423 +{
   2.424 +    struct domain *d;
   2.425 +
   2.426 +    for_each_domain ( d )
   2.427 +    {
   2.428 +	if ( d->domain > 0 )
   2.429 +	    audit_domain(d);
   2.430 +    }
   2.431 +}
   2.432 +
   2.433 +void audit_domains_key (unsigned char key, void *dev_id,
   2.434 +                           struct pt_regs *regs)
   2.435 +{
   2.436 +    open_softirq( MEMAUDIT_SOFTIRQ, audit_domains );
   2.437 +    raise_softirq( MEMAUDIT_SOFTIRQ );
   2.438 +}
   2.439 +
   2.440 +
   2.441 +#endif
     3.1 --- a/xen/arch/x86/traps.c	Mon Sep 06 14:46:01 2004 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Mon Sep 06 17:18:27 2004 +0000
     3.3 @@ -102,6 +102,25 @@ static inline int kernel_text_address(un
     3.4  
     3.5  }
     3.6  
     3.7 +void show_guest_stack()
     3.8 +{
     3.9 +    int i;
    3.10 +    execution_context_t *ec = get_execution_context();
    3.11 +    unsigned long *stack = (unsigned long *)ec->esp;
    3.12 +    printk("Guest EIP is %lx\n",ec->eip);
    3.13 +
    3.14 +    for ( i = 0; i < kstack_depth_to_print; i++ )
    3.15 +    {
    3.16 +        if ( ((long)stack & (STACK_SIZE-1)) == 0 )
    3.17 +            break;
    3.18 +        if ( i && ((i % 8) == 0) )
    3.19 +            printk("\n       ");
    3.20 +            printk("%08lx ", *stack++);            
    3.21 +    }
    3.22 +    printk("\n");
    3.23 +    
    3.24 +}
    3.25 +
    3.26  void show_stack(unsigned long *esp)
    3.27  {
    3.28      unsigned long *stack, addr;
     4.1 --- a/xen/common/keyhandler.c	Mon Sep 06 14:46:01 2004 +0000
     4.2 +++ b/xen/common/keyhandler.c	Mon Sep 06 17:18:27 2004 +0000
     4.3 @@ -108,6 +108,11 @@ extern void print_sched_histo(unsigned c
     4.4                                struct pt_regs *regs);
     4.5  extern void reset_sched_histo(unsigned char key, void *dev_id, 
     4.6                                struct pt_regs *regs);
     4.7 +#ifndef NDEBUG
     4.8 +extern void audit_domains_key(unsigned char key, void *dev_id,
     4.9 +                           struct pt_regs *regs);
    4.10 +#endif
    4.11 +
    4.12  #ifdef PERF_COUNTERS
    4.13  extern void perfc_printall(unsigned char key, void *dev_id,
    4.14                             struct pt_regs *regs);
    4.15 @@ -124,6 +129,11 @@ void initialize_keytable(void)
    4.16      add_key_handler('q', do_task_queues, "dump task queues + guest state");
    4.17      add_key_handler('r', dump_runq,      "dump run queues");
    4.18      add_key_handler('R', halt_machine,   "reboot machine"); 
    4.19 +
    4.20 +#ifndef NDEBUG
    4.21 +    add_key_handler('o', audit_domains_key,  "audit domains >0 EXPERIMENTAL"); 
    4.22 +#endif
    4.23 +
    4.24  #ifdef PERF_COUNTERS
    4.25      add_key_handler('p', perfc_printall, "print performance counters"); 
    4.26      add_key_handler('P', perfc_reset,    "reset performance counters"); 
     5.1 --- a/xen/common/page_alloc.c	Mon Sep 06 14:46:01 2004 +0000
     5.2 +++ b/xen/common/page_alloc.c	Mon Sep 06 17:18:27 2004 +0000
     5.3 @@ -448,6 +448,11 @@ void free_domheap_pages(struct pfn_info 
     5.4  
     5.5          for ( i = 0; i < (1 << order); i++ )
     5.6          {
     5.7 +#ifndef NDEBUG
     5.8 +	    if ( pg[i].u.inuse.type_info & PGT_count_mask )
     5.9 +		printk("ERROR: type count not zero on free %x\n",
    5.10 +		       pg[i].u.inuse.type_info );
    5.11 +#endif
    5.12              pg[i].tlbflush_timestamp  = tlbflush_clock;
    5.13              pg[i].u.free.cpu_mask     = 1 << d->processor;
    5.14              list_del(&pg[i].list);
     6.1 --- a/xen/include/xen/softirq.h	Mon Sep 06 14:46:01 2004 +0000
     6.2 +++ b/xen/include/xen/softirq.h	Mon Sep 06 17:18:27 2004 +0000
     6.3 @@ -6,7 +6,8 @@
     6.4  #define DEBUGGER_SOFTIRQ                  2
     6.5  #define NMI_SOFTIRQ                       3
     6.6  #define SCHEDULE_SOFTIRQ                  4
     6.7 -#define NR_SOFTIRQS                       5
     6.8 +#define MEMAUDIT_SOFTIRQ                  5
     6.9 +#define NR_SOFTIRQS                       6
    6.10  
    6.11  #ifndef __ASSEMBLY__
    6.12