ia64/xen-unstable

changeset 2806:b7f0cff13881

bitkeeper revision 1.1159.1.321 (41865777v0w5qC8-c7u-6_0V0D6bGg)

tasklist_lock -> domlist_lock.
domlist_lock and heap_lock no longer disable interrupts.
This means that find_domain_by_id(), put_domain(), alloc_domheap_pages()
and others are not interrupt-safe.
alloc_xenheap_pages(), xmalloc() and friends *are* still safe to use
in interrupt context.
author kaf24@freefall.cl.cam.ac.uk
date Mon Nov 01 15:34:15 2004 +0000 (2004-11-01)
parents d301dd777023
children 61a55dee09d8
files xen/arch/x86/pdb-stub.c xen/arch/x86/traps.c xen/arch/x86/x86_32/domain_page.c xen/common/dom0_ops.c xen/common/domain.c xen/common/kernel.c xen/common/keyhandler.c xen/common/page_alloc.c xen/common/sched_bvt.c xen/common/trace.c xen/drivers/char/console.c xen/include/xen/mm.h xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/x86/pdb-stub.c	Mon Nov 01 14:33:53 2004 +0000
     1.2 +++ b/xen/arch/x86/pdb-stub.c	Mon Nov 01 15:34:15 2004 +0000
     1.3 @@ -99,7 +99,6 @@ pdb_process_query (char *ptr)
     1.4      {
     1.5  #ifdef PDB_PAST
     1.6          struct domain *p;
     1.7 -        u_long flags;
     1.8  #endif /* PDB_PAST */
     1.9  
    1.10          int buf_idx = 0;
    1.11 @@ -114,7 +113,7 @@ pdb_process_query (char *ptr)
    1.12  	{
    1.13  	    int count = 0;
    1.14  
    1.15 -	    read_lock_irqsave (&tasklist_lock, flags);
    1.16 +	    read_lock(&domlist_lock);
    1.17  
    1.18  	    pdb_out_buffer[buf_idx++] = 'm';
    1.19  	    for_each_domain ( p )
    1.20 @@ -134,7 +133,7 @@ pdb_process_query (char *ptr)
    1.21  	    }
    1.22  	    pdb_out_buffer[buf_idx++] = 0;
    1.23  
    1.24 -	    read_unlock_irqrestore(&tasklist_lock, flags);
    1.25 +	    read_unlock(&domlist_lock);
    1.26  	    break;
    1.27  	}
    1.28  	case PDB_LVL_GUESTOS:                  /* return a list of processes */
    1.29 @@ -197,9 +196,7 @@ pdb_process_query (char *ptr)
    1.30  	char message[16];
    1.31  	struct domain *p;
    1.32  
    1.33 -	p = find_domain_by_id(pdb_ctx[pdb_level].info);
    1.34 -	strncpy (message, p->name, 16);
    1.35 -	put_domain(p);
    1.36 +	strncpy (message, dom0->name, 16);
    1.37  
    1.38  	ptr += 16;
    1.39          if (hexToInt (&ptr, &thread))
    1.40 @@ -914,11 +911,9 @@ int pdb_change_values_one_page(u_char *b
    1.41  	}
    1.42  	else
    1.43  	{
    1.44 -	    struct domain *p = find_domain_by_id(0);
    1.45  	    printk ("pdb error: cr3: 0x%lx    dom0cr3:  0x%lx\n",  cr3,
    1.46 -		    p->mm.shadow_mode ? pagetable_val(p->mm.shadow_table)
    1.47 -		    : pagetable_val(p->mm.pagetable));
    1.48 -	    put_domain(p);
    1.49 +		    dom0->mm.shadow_mode ? pagetable_val(dom0->mm.shadow_table)
    1.50 +		    : pagetable_val(dom0->mm.pagetable));
    1.51  	    printk ("pdb error: L2:0x%p (0x%lx)\n", 
    1.52  		    l2_table, l2_pgentry_val(*l2_table));
    1.53  	}
     2.1 --- a/xen/arch/x86/traps.c	Mon Nov 01 14:33:53 2004 +0000
     2.2 +++ b/xen/arch/x86/traps.c	Mon Nov 01 15:34:15 2004 +0000
     2.3 @@ -578,18 +578,14 @@ asmlinkage void do_nmi(struct pt_regs * 
     2.4  unsigned long nmi_softirq_reason;
     2.5  static void nmi_softirq(void)
     2.6  {
     2.7 -    struct domain *d = find_domain_by_id(0);
     2.8 -
     2.9 -    if ( d == NULL )
    2.10 +    if ( dom0 == NULL )
    2.11          return;
    2.12  
    2.13      if ( test_and_clear_bit(0, &nmi_softirq_reason) )
    2.14 -        send_guest_virq(d, VIRQ_PARITY_ERR);
    2.15 +        send_guest_virq(dom0, VIRQ_PARITY_ERR);
    2.16  
    2.17      if ( test_and_clear_bit(1, &nmi_softirq_reason) )
    2.18 -        send_guest_virq(d, VIRQ_IO_ERR);
    2.19 -
    2.20 -    put_domain(d);
    2.21 +        send_guest_virq(dom0, VIRQ_IO_ERR);
    2.22  }
    2.23  
    2.24  asmlinkage void math_state_restore(struct pt_regs *regs, long error_code)
     3.1 --- a/xen/arch/x86/x86_32/domain_page.c	Mon Nov 01 14:33:53 2004 +0000
     3.2 +++ b/xen/arch/x86/x86_32/domain_page.c	Mon Nov 01 15:34:15 2004 +0000
     3.3 @@ -17,6 +17,7 @@
     3.4  #include <xen/perfc.h>
     3.5  #include <asm/domain_page.h>
     3.6  #include <asm/flushtlb.h>
     3.7 +#include <asm/hardirq.h>
     3.8  
     3.9  unsigned long *mapcache;
    3.10  static unsigned int map_idx, epoch, shadow_epoch[NR_CPUS];
    3.11 @@ -43,11 +44,11 @@ void *map_domain_mem(unsigned long pa)
    3.12      unsigned long va;
    3.13      unsigned int idx, cpu = smp_processor_id();
    3.14      unsigned long *cache = mapcache;
    3.15 -    unsigned long flags;
    3.16  
    3.17 +    ASSERT(!in_irq());
    3.18      perfc_incrc(map_domain_mem_count);
    3.19  
    3.20 -    spin_lock_irqsave(&map_lock, flags);
    3.21 +    spin_lock(&map_lock);
    3.22  
    3.23      /* Has some other CPU caused a wrap? We must flush if so. */
    3.24      if ( epoch != shadow_epoch[cpu] )
    3.25 @@ -71,7 +72,7 @@ void *map_domain_mem(unsigned long pa)
    3.26  
    3.27      cache[idx] = (pa & PAGE_MASK) | __PAGE_HYPERVISOR;
    3.28  
    3.29 -    spin_unlock_irqrestore(&map_lock, flags);
    3.30 +    spin_unlock(&map_lock);
    3.31  
    3.32      va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT) + (pa & ~PAGE_MASK);
    3.33      return (void *)va;
     4.1 --- a/xen/common/dom0_ops.c	Mon Nov 01 14:33:53 2004 +0000
     4.2 +++ b/xen/common/dom0_ops.c	Mon Nov 01 15:34:15 2004 +0000
     4.3 @@ -180,10 +180,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     4.4              struct domain *d;
     4.5              unsigned int i, cnt[NR_CPUS] = { 0 };
     4.6  
     4.7 -            read_lock_irq(&tasklist_lock);
     4.8 +            read_lock(&domlist_lock);
     4.9              for_each_domain ( d )
    4.10                  cnt[d->processor]++;
    4.11 -            read_unlock_irq(&tasklist_lock);
    4.12 +            read_unlock(&domlist_lock);
    4.13  
    4.14              for ( i = 0; i < smp_num_cpus; i++ )
    4.15                  if ( cnt[i] < cnt[pro] )
    4.16 @@ -321,9 +321,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    4.17      { 
    4.18          full_execution_context_t *c;
    4.19          struct domain            *d;
    4.20 -        unsigned long             flags;
    4.21  
    4.22 -        read_lock_irqsave(&tasklist_lock, flags);
    4.23 +        read_lock(&domlist_lock);
    4.24  
    4.25          for_each_domain ( d )
    4.26          {
    4.27 @@ -333,12 +332,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    4.28  
    4.29          if ( (d == NULL) || !get_domain(d) )
    4.30          {
    4.31 -            read_unlock_irqrestore(&tasklist_lock, flags);
    4.32 +            read_unlock(&domlist_lock);
    4.33              ret = -ESRCH;
    4.34              break;
    4.35          }
    4.36  
    4.37 -        read_unlock_irqrestore(&tasklist_lock, flags);
    4.38 +        read_unlock(&domlist_lock);
    4.39  
    4.40          op->u.getdomaininfo.domain = d->id;
    4.41          
     5.1 --- a/xen/common/domain.c	Mon Nov 01 14:33:53 2004 +0000
     5.2 +++ b/xen/common/domain.c	Mon Nov 01 15:34:15 2004 +0000
     5.3 @@ -17,15 +17,14 @@
     5.4  #include <public/dom0_ops.h>
     5.5  #include <asm/domain_page.h>
     5.6  
     5.7 -/* Both these structures are protected by the tasklist_lock. */
     5.8 -rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
     5.9 -struct domain *task_hash[TASK_HASH_SIZE];
    5.10 -struct domain *task_list;
    5.11 +/* Both these structures are protected by the domlist_lock. */
    5.12 +rwlock_t domlist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
    5.13 +struct domain *domain_hash[DOMAIN_HASH_SIZE];
    5.14 +struct domain *domain_list;
    5.15  
    5.16  struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
    5.17  {
    5.18      struct domain *d, **pd;
    5.19 -    unsigned long flags;
    5.20  
    5.21      if ( (d = alloc_domain_struct()) == NULL )
    5.22          return NULL;
    5.23 @@ -62,16 +61,16 @@ struct domain *do_createdomain(domid_t d
    5.24  
    5.25          sched_add_domain(d);
    5.26  
    5.27 -        write_lock_irqsave(&tasklist_lock, flags);
    5.28 -        pd = &task_list; /* NB. task_list is maintained in order of dom_id. */
    5.29 -        for ( pd = &task_list; *pd != NULL; pd = &(*pd)->next_list )
    5.30 +        write_lock(&domlist_lock);
    5.31 +        pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */
    5.32 +        for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list )
    5.33              if ( (*pd)->id > d->id )
    5.34                  break;
    5.35          d->next_list = *pd;
    5.36          *pd = d;
    5.37 -        d->next_hash = task_hash[TASK_HASH(dom_id)];
    5.38 -        task_hash[TASK_HASH(dom_id)] = d;
    5.39 -        write_unlock_irqrestore(&tasklist_lock, flags);
    5.40 +        d->next_hash = domain_hash[DOMAIN_HASH(dom_id)];
    5.41 +        domain_hash[DOMAIN_HASH(dom_id)] = d;
    5.42 +        write_unlock(&domlist_lock);
    5.43      }
    5.44      else
    5.45      {
    5.46 @@ -85,10 +84,9 @@ struct domain *do_createdomain(domid_t d
    5.47  struct domain *find_domain_by_id(domid_t dom)
    5.48  {
    5.49      struct domain *d;
    5.50 -    unsigned long flags;
    5.51  
    5.52 -    read_lock_irqsave(&tasklist_lock, flags);
    5.53 -    d = task_hash[TASK_HASH(dom)];
    5.54 +    read_lock(&domlist_lock);
    5.55 +    d = domain_hash[DOMAIN_HASH(dom)];
    5.56      while ( d != NULL )
    5.57      {
    5.58          if ( d->id == dom )
    5.59 @@ -99,7 +97,7 @@ struct domain *find_domain_by_id(domid_t
    5.60          }
    5.61          d = d->next_hash;
    5.62      }
    5.63 -    read_unlock_irqrestore(&tasklist_lock, flags);
    5.64 +    read_unlock(&domlist_lock);
    5.65  
    5.66      return d;
    5.67  }
    5.68 @@ -109,10 +107,9 @@ struct domain *find_domain_by_id(domid_t
    5.69  struct domain *find_last_domain(void)
    5.70  {
    5.71      struct domain *d, *dlast;
    5.72 -    unsigned long flags;
    5.73  
    5.74 -    read_lock_irqsave(&tasklist_lock, flags);
    5.75 -    dlast = task_list;
    5.76 +    read_lock(&domlist_lock);
    5.77 +    dlast = domain_list;
    5.78      d = dlast->next_list;
    5.79      while ( d != NULL )
    5.80      {
    5.81 @@ -122,7 +119,7 @@ struct domain *find_last_domain(void)
    5.82      }
    5.83      if ( !get_domain(dlast) )
    5.84          dlast = NULL;
    5.85 -    read_unlock_irqrestore(&tasklist_lock, flags);
    5.86 +    read_unlock(&domlist_lock);
    5.87  
    5.88      return dlast;
    5.89  }
    5.90 @@ -142,16 +139,12 @@ void domain_kill(struct domain *d)
    5.91  
    5.92  void domain_crash(void)
    5.93  {
    5.94 -    struct domain *d;
    5.95 -
    5.96      if ( current->id == 0 )
    5.97          BUG();
    5.98  
    5.99      set_bit(DF_CRASHED, &current->flags);
   5.100  
   5.101 -    d = find_domain_by_id(0);
   5.102 -    send_guest_virq(d, VIRQ_DOM_EXC);
   5.103 -    put_domain(d);
   5.104 +    send_guest_virq(dom0, VIRQ_DOM_EXC);
   5.105      
   5.106      __enter_scheduler();
   5.107      BUG();
   5.108 @@ -159,8 +152,6 @@ void domain_crash(void)
   5.109  
   5.110  void domain_shutdown(u8 reason)
   5.111  {
   5.112 -    struct domain *d;
   5.113 -
   5.114      if ( current->id == 0 )
   5.115      {
   5.116          extern void machine_restart(char *);
   5.117 @@ -181,9 +172,7 @@ void domain_shutdown(u8 reason)
   5.118      current->shutdown_code = reason;
   5.119      set_bit(DF_SHUTDOWN, &current->flags);
   5.120  
   5.121 -    d = find_domain_by_id(0);
   5.122 -    send_guest_virq(d, VIRQ_DOM_EXC);
   5.123 -    put_domain(d);
   5.124 +    send_guest_virq(dom0, VIRQ_DOM_EXC);
   5.125  
   5.126      __enter_scheduler();
   5.127  }
   5.128 @@ -217,7 +206,6 @@ unsigned int alloc_new_dom_mem(struct do
   5.129  void domain_destruct(struct domain *d)
   5.130  {
   5.131      struct domain **pd;
   5.132 -    unsigned long flags;
   5.133      atomic_t      old, new;
   5.134  
   5.135      if ( !test_bit(DF_DYING, &d->flags) )
   5.136 @@ -231,16 +219,16 @@ void domain_destruct(struct domain *d)
   5.137          return;
   5.138  
   5.139      /* Delete from task list and task hashtable. */
   5.140 -    write_lock_irqsave(&tasklist_lock, flags);
   5.141 -    pd = &task_list;
   5.142 +    write_lock(&domlist_lock);
   5.143 +    pd = &domain_list;
   5.144      while ( *pd != d ) 
   5.145          pd = &(*pd)->next_list;
   5.146      *pd = d->next_list;
   5.147 -    pd = &task_hash[TASK_HASH(d->id)];
   5.148 +    pd = &domain_hash[DOMAIN_HASH(d->id)];
   5.149      while ( *pd != d ) 
   5.150          pd = &(*pd)->next_hash;
   5.151      *pd = d->next_hash;
   5.152 -    write_unlock_irqrestore(&tasklist_lock, flags);
   5.153 +    write_unlock(&domlist_lock);
   5.154  
   5.155      destroy_event_channels(d);
   5.156      grant_table_destroy(d);
     6.1 --- a/xen/common/kernel.c	Mon Nov 01 14:33:53 2004 +0000
     6.2 +++ b/xen/common/kernel.c	Mon Nov 01 15:34:15 2004 +0000
     6.3 @@ -29,6 +29,7 @@
     6.4  unsigned long xenheap_phys_end;
     6.5  
     6.6  xmem_cache_t *domain_struct_cachep;
     6.7 +struct domain *dom0;
     6.8  
     6.9  vm_assist_info_t vm_assist_info[MAX_VMASST_TYPE + 1];
    6.10  
    6.11 @@ -132,7 +133,6 @@ static struct {
    6.12  
    6.13  void cmain(multiboot_info_t *mbi)
    6.14  {
    6.15 -    struct domain *new_dom;
    6.16      unsigned long max_page;
    6.17      unsigned char *cmdline;
    6.18      module_t *mod = (module_t *)__va(mbi->mods_addr);
    6.19 @@ -308,11 +308,11 @@ void cmain(multiboot_info_t *mbi)
    6.20      grant_table_init();
    6.21  
    6.22      /* Create initial domain 0. */
    6.23 -    new_dom = do_createdomain(0, 0);
    6.24 -    if ( new_dom == NULL )
    6.25 +    dom0 = do_createdomain(0, 0);
    6.26 +    if ( dom0 == NULL )
    6.27          panic("Error creating domain 0\n");
    6.28  
    6.29 -    set_bit(DF_PRIVILEGED, &new_dom->flags);
    6.30 +    set_bit(DF_PRIVILEGED, &dom0->flags);
    6.31  
    6.32      shadow_mode_init();
    6.33  
    6.34 @@ -329,7 +329,7 @@ void cmain(multiboot_info_t *mbi)
    6.35       * We're going to setup domain0 using the module(s) that we stashed safely
    6.36       * above our heap. The second module, if present, is an initrd ramdisk.
    6.37       */
    6.38 -    if ( construct_dom0(new_dom, dom0_memory_start, dom0_memory_end,
    6.39 +    if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
    6.40                          (char *)initial_images_start, 
    6.41                          mod[0].mod_end-mod[0].mod_start,
    6.42                          (mbi->mods_count == 1) ? 0 :
    6.43 @@ -349,7 +349,7 @@ void cmain(multiboot_info_t *mbi)
    6.44      init_trace_bufs();
    6.45  
    6.46      domain_unpause_by_systemcontroller(current);
    6.47 -    domain_unpause_by_systemcontroller(new_dom);
    6.48 +    domain_unpause_by_systemcontroller(dom0);
    6.49      startup_cpu_idle_loop();
    6.50  }
    6.51  
     7.1 --- a/xen/common/keyhandler.c	Mon Nov 01 14:33:53 2004 +0000
     7.2 +++ b/xen/common/keyhandler.c	Mon Nov 01 15:34:15 2004 +0000
     7.3 @@ -66,7 +66,6 @@ static void halt_machine(unsigned char k
     7.4  
     7.5  void do_task_queues(unsigned char key)
     7.6  {
     7.7 -    unsigned long  flags;
     7.8      struct domain *d;
     7.9      s_time_t       now = NOW();
    7.10      struct list_head *ent;
    7.11 @@ -75,7 +74,7 @@ void do_task_queues(unsigned char key)
    7.12      printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key,
    7.13             (u32)(now>>32), (u32)now); 
    7.14  
    7.15 -    read_lock_irqsave(&tasklist_lock, flags); 
    7.16 +    read_lock(&domlist_lock);
    7.17  
    7.18      for_each_domain ( d )
    7.19      {
    7.20 @@ -108,7 +107,7 @@ void do_task_queues(unsigned char key)
    7.21          send_guest_virq(d, VIRQ_DEBUG);
    7.22      }
    7.23  
    7.24 -    read_unlock_irqrestore(&tasklist_lock, flags); 
    7.25 +    read_unlock(&domlist_lock);
    7.26  }
    7.27  
    7.28  extern void dump_runq(unsigned char key);
     8.1 --- a/xen/common/page_alloc.c	Mon Nov 01 14:33:53 2004 +0000
     8.2 +++ b/xen/common/page_alloc.c	Mon Nov 01 15:34:15 2004 +0000
     8.3 @@ -44,7 +44,6 @@ static unsigned long *alloc_bitmap;
     8.4  #define allocated_in_map(_pn) \
     8.5  (alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & (1<<((_pn)&(PAGES_PER_MAPWORD-1))))
     8.6  
     8.7 -
     8.8  /*
     8.9   * Hint regarding bitwise arithmetic in map_{alloc,free}:
    8.10   *  -(1<<n)  sets all bits >= n. 
    8.11 @@ -134,7 +133,6 @@ static unsigned long avail[NR_ZONES];
    8.12  
    8.13  static spinlock_t heap_lock = SPIN_LOCK_UNLOCKED;
    8.14  
    8.15 -
    8.16  /* Initialise allocator to handle up to @max_pages. */
    8.17  unsigned long init_heap_allocator(
    8.18      unsigned long bitmap_start, unsigned long max_pages)
    8.19 @@ -184,6 +182,7 @@ unsigned long init_heap_allocator(
    8.20      return bitmap_start + bitmap_size;
    8.21  }
    8.22  
    8.23 +
    8.24  /* Hand the specified arbitrary page range to the specified heap zone. */
    8.25  void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages)
    8.26  {
    8.27 @@ -203,12 +202,11 @@ struct pfn_info *alloc_heap_pages(int zo
    8.28  {
    8.29      int i;
    8.30      struct pfn_info *pg;
    8.31 -    unsigned long flags;
    8.32  
    8.33      if ( unlikely(order < MIN_ORDER) || unlikely(order > MAX_ORDER) )
    8.34          return NULL;
    8.35  
    8.36 -    spin_lock_irqsave(&heap_lock, flags);
    8.37 +    spin_lock(&heap_lock);
    8.38  
    8.39      /* Find smallest order which can satisfy the request. */
    8.40      for ( i = order; i < NR_ORDERS; i++ )
    8.41 @@ -232,12 +230,12 @@ struct pfn_info *alloc_heap_pages(int zo
    8.42      map_alloc(page_to_pfn(pg), 1 << order);
    8.43      avail[zone] -= 1 << order;
    8.44  
    8.45 -    spin_unlock_irqrestore(&heap_lock, flags);
    8.46 +    spin_unlock(&heap_lock);
    8.47  
    8.48      return pg;
    8.49  
    8.50   no_memory:
    8.51 -    spin_unlock_irqrestore(&heap_lock, flags);
    8.52 +    spin_unlock(&heap_lock);
    8.53      return NULL;
    8.54  }
    8.55  
    8.56 @@ -246,9 +244,8 @@ struct pfn_info *alloc_heap_pages(int zo
    8.57  void free_heap_pages(int zone, struct pfn_info *pg, int order)
    8.58  {
    8.59      unsigned long mask;
    8.60 -    unsigned long flags;
    8.61  
    8.62 -    spin_lock_irqsave(&heap_lock, flags);
    8.63 +    spin_lock(&heap_lock);
    8.64  
    8.65      map_free(page_to_pfn(pg), 1 << order);
    8.66      avail[zone] += 1 << order;
    8.67 @@ -282,7 +279,7 @@ void free_heap_pages(int zone, struct pf
    8.68      PFN_ORDER(pg) = order;
    8.69      list_add_tail(&pg->list, &heap[zone][order]);
    8.70  
    8.71 -    spin_unlock_irqrestore(&heap_lock, flags);
    8.72 +    spin_unlock(&heap_lock);
    8.73  }
    8.74  
    8.75  
    8.76 @@ -324,19 +321,31 @@ void scrub_heap_pages(void)
    8.77  
    8.78  void init_xenheap_pages(unsigned long ps, unsigned long pe)
    8.79  {
    8.80 +    unsigned long flags;
    8.81 +
    8.82      ps = round_pgup(ps);
    8.83      pe = round_pgdown(pe);
    8.84 +
    8.85      memguard_guard_range(__va(ps), pe - ps);
    8.86 +
    8.87 +    local_irq_save(flags);
    8.88      init_heap_pages(MEMZONE_XEN, phys_to_page(ps), (pe - ps) >> PAGE_SHIFT);
    8.89 +    local_irq_restore(flags);
    8.90  }
    8.91  
    8.92 +
    8.93  unsigned long alloc_xenheap_pages(int order)
    8.94  {
    8.95 +    unsigned long flags;
    8.96      struct pfn_info *pg;
    8.97      int i, attempts = 0;
    8.98  
    8.99   retry:
   8.100 -    if ( unlikely((pg = alloc_heap_pages(MEMZONE_XEN, order)) == NULL) )
   8.101 +    local_irq_save(flags);
   8.102 +    pg = alloc_heap_pages(MEMZONE_XEN, order);
   8.103 +    local_irq_restore(flags);
   8.104 +
   8.105 +    if ( unlikely(pg == NULL) )
   8.106          goto no_memory;
   8.107  
   8.108      memguard_unguard_range(page_to_virt(pg), 1 << (order + PAGE_SHIFT));
   8.109 @@ -362,10 +371,16 @@ unsigned long alloc_xenheap_pages(int or
   8.110      return 0;
   8.111  }
   8.112  
   8.113 +
   8.114  void free_xenheap_pages(unsigned long p, int order)
   8.115  {
   8.116 +    unsigned long flags;
   8.117 +
   8.118      memguard_guard_range((void *)p, 1 << (order + PAGE_SHIFT));    
   8.119 +
   8.120 +    local_irq_save(flags);
   8.121      free_heap_pages(MEMZONE_XEN, virt_to_page(p), order);
   8.122 +    local_irq_restore(flags);
   8.123  }
   8.124  
   8.125  
   8.126 @@ -376,11 +391,15 @@ void free_xenheap_pages(unsigned long p,
   8.127  
   8.128  void init_domheap_pages(unsigned long ps, unsigned long pe)
   8.129  {
   8.130 +    ASSERT(!in_irq());
   8.131 +
   8.132      ps = round_pgup(ps);
   8.133      pe = round_pgdown(pe);
   8.134 +
   8.135      init_heap_pages(MEMZONE_DOM, phys_to_page(ps), (pe - ps) >> PAGE_SHIFT);
   8.136  }
   8.137  
   8.138 +
   8.139  struct pfn_info *alloc_domheap_pages(struct domain *d, int order)
   8.140  {
   8.141      struct pfn_info *pg;
   8.142 @@ -456,12 +475,15 @@ struct pfn_info *alloc_domheap_pages(str
   8.143      return pg;
   8.144  }
   8.145  
   8.146 +
   8.147  void free_domheap_pages(struct pfn_info *pg, int order)
   8.148  {
   8.149      int            i, drop_dom_ref;
   8.150      struct domain *d = pg->u.inuse.domain;
   8.151      void          *p;
   8.152  
   8.153 +    ASSERT(!in_irq());
   8.154 +
   8.155      if ( unlikely(IS_XEN_HEAP_FRAME(pg)) )
   8.156      {
   8.157          /* NB. May recursively lock from domain_relinquish_memory(). */
   8.158 @@ -518,8 +540,8 @@ void free_domheap_pages(struct pfn_info 
   8.159          put_domain(d);
   8.160  }
   8.161  
   8.162 +
   8.163  unsigned long avail_domheap_pages(void)
   8.164  {
   8.165      return avail[MEMZONE_DOM];
   8.166  }
   8.167 -
     9.1 --- a/xen/common/sched_bvt.c	Mon Nov 01 14:33:53 2004 +0000
     9.2 +++ b/xen/common/sched_bvt.c	Mon Nov 01 15:34:15 2004 +0000
     9.3 @@ -440,7 +440,7 @@ static task_slice_t bvt_do_schedule(s_ti
     9.4      {
     9.5          ASSERT(!local_irq_is_enabled());
     9.6  
     9.7 -        write_lock(&tasklist_lock);
     9.8 +        write_lock(&domlist_lock);
     9.9          
    9.10          for_each_domain ( p )
    9.11          {
    9.12 @@ -452,7 +452,7 @@ static task_slice_t bvt_do_schedule(s_ti
    9.13              }
    9.14          } 
    9.15          
    9.16 -        write_unlock(&tasklist_lock);
    9.17 +        write_unlock(&domlist_lock);
    9.18          
    9.19          CPU_SVT(cpu) -= 0xe0000000;
    9.20      }
    10.1 --- a/xen/common/trace.c	Mon Nov 01 14:33:53 2004 +0000
    10.2 +++ b/xen/common/trace.c	Mon Nov 01 15:34:15 2004 +0000
    10.3 @@ -48,7 +48,6 @@ void init_trace_bufs(void)
    10.4      unsigned long nr_pages;
    10.5      char         *rawbuf;
    10.6      struct t_buf *buf;
    10.7 -    struct domain *dom0;
    10.8      
    10.9      if ( opt_tbuf_size == 0 )
   10.10      {
   10.11 @@ -67,13 +66,9 @@ void init_trace_bufs(void)
   10.12  
   10.13      /* Share pages so that xentrace can map them. */
   10.14  
   10.15 -    dom0 = find_domain_by_id(0);
   10.16 -
   10.17 -    for( i = 0; i < nr_pages; i++)
   10.18 +    for ( i = 0; i < nr_pages; i++ )
   10.19          SHARE_PFN_WITH_DOMAIN(virt_to_page(rawbuf+(i*PAGE_SIZE)), dom0);
   10.20      
   10.21 -    put_domain(dom0);
   10.22 -
   10.23      for ( i = 0; i < smp_num_cpus; i++ )
   10.24      {
   10.25          buf = t_bufs[i] = (struct t_buf *)&rawbuf[i*opt_tbuf_size*PAGE_SIZE];
    11.1 --- a/xen/drivers/char/console.c	Mon Nov 01 14:33:53 2004 +0000
    11.2 +++ b/xen/drivers/char/console.c	Mon Nov 01 15:34:15 2004 +0000
    11.3 @@ -245,8 +245,6 @@ static void switch_serial_input(void)
    11.4  
    11.5  static void __serial_rx(unsigned char c, struct pt_regs *regs)
    11.6  {
    11.7 -    struct domain *d;
    11.8 -
    11.9      if ( xen_rx )
   11.10      {
   11.11          handle_keypress(c);
   11.12 @@ -255,11 +253,7 @@ static void __serial_rx(unsigned char c,
   11.13      {
   11.14          serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod)] = c;
   11.15          if ( serial_rx_prod++ == serial_rx_cons )
   11.16 -        {
   11.17 -            d = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
   11.18 -            send_guest_virq(d, VIRQ_CONSOLE);
   11.19 -            put_domain(d);
   11.20 -        }
   11.21 +            send_guest_virq(dom0, VIRQ_CONSOLE);
   11.22      }
   11.23  }
   11.24  
    12.1 --- a/xen/include/xen/mm.h	Mon Nov 01 14:33:53 2004 +0000
    12.2 +++ b/xen/include/xen/mm.h	Mon Nov 01 15:34:15 2004 +0000
    12.3 @@ -5,7 +5,7 @@
    12.4  struct domain;
    12.5  struct pfn_info;
    12.6  
    12.7 -/* Generic allocator */
    12.8 +/* Generic allocator. These functions are *not* interrupt-safe. */
    12.9  unsigned long init_heap_allocator(
   12.10      unsigned long bitmap_start, unsigned long max_pages);
   12.11  void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages);
   12.12 @@ -13,14 +13,14 @@ struct pfn_info *alloc_heap_pages(int zo
   12.13  void free_heap_pages(int zone, struct pfn_info *pg, int order);
   12.14  void scrub_heap_pages(void);
   12.15  
   12.16 -/* Xen suballocator */
   12.17 +/* Xen suballocator. These functions are interrupt-safe. */
   12.18  void init_xenheap_pages(unsigned long ps, unsigned long pe);
   12.19  unsigned long alloc_xenheap_pages(int order);
   12.20  void free_xenheap_pages(unsigned long p, int order);
   12.21  #define alloc_xenheap_page() (alloc_xenheap_pages(0))
   12.22  #define free_xenheap_page(_p) (free_xenheap_pages(_p,0))
   12.23  
   12.24 -/* Domain suballocator */
   12.25 +/* Domain suballocator. These functions are *not* interrupt-safe.*/
   12.26  void init_domheap_pages(unsigned long ps, unsigned long pe);
   12.27  struct pfn_info *alloc_domheap_pages(struct domain *d, int order);
   12.28  void free_domheap_pages(struct pfn_info *pg, int order);
    13.1 --- a/xen/include/xen/sched.h	Mon Nov 01 14:33:53 2004 +0000
    13.2 +++ b/xen/include/xen/sched.h	Mon Nov 01 15:34:15 2004 +0000
    13.3 @@ -22,10 +22,13 @@
    13.4  #include <xen/grant_table.h>
    13.5  
    13.6  extern unsigned long volatile jiffies;
    13.7 -extern rwlock_t tasklist_lock;
    13.8 +extern rwlock_t domlist_lock;
    13.9  
   13.10  struct domain;
   13.11  
   13.12 +/* A global pointer to the initial domain (DOM0). */
   13.13 +extern struct domain *dom0;
   13.14 +
   13.15  typedef struct event_channel_st
   13.16  {
   13.17  #define ECS_FREE         0 /* Channel is available for use.                  */
   13.18 @@ -251,14 +254,14 @@ void continue_cpu_idle_loop(void);
   13.19  
   13.20  void continue_nonidle_task(void);
   13.21  
   13.22 -/* This task_hash and task_list are protected by the tasklist_lock. */
   13.23 -#define TASK_HASH_SIZE 256
   13.24 -#define TASK_HASH(_id) ((int)(_id)&(TASK_HASH_SIZE-1))
   13.25 -extern struct domain *task_hash[TASK_HASH_SIZE];
   13.26 -extern struct domain *task_list;
   13.27 +/* This domain_hash and domain_list are protected by the domlist_lock. */
   13.28 +#define DOMAIN_HASH_SIZE 256
   13.29 +#define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))
   13.30 +extern struct domain *domain_hash[DOMAIN_HASH_SIZE];
   13.31 +extern struct domain *domain_list;
   13.32  
   13.33  #define for_each_domain(_p) \
   13.34 - for ( (_p) = task_list; (_p) != NULL; (_p) = (_p)->next_list )
   13.35 + for ( (_p) = domain_list; (_p) != NULL; (_p) = (_p)->next_list )
   13.36  
   13.37  #define DF_DONEFPUINIT  0 /* Has the FPU been initialised for this task?    */
   13.38  #define DF_USEDFPU      1 /* Has this task used the FPU since last save?    */