ia64/xen-unstable

changeset 103:0ecf87d4739a

bitkeeper revision 1.19 (3e36a209mfpjizEZbVJpJezr-nUFLQ)
author bd240@boulderdash.cl.cam.ac.uk
date Tue Jan 28 15:30:17 2003 +0000 (2003-01-28)
parents d59292c8dcab
children bbabb540b450
files xen-2.4.16/common/domain.c xen-2.4.16/common/memory.c xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/dom0_core.c xenolinux-2.4.16-sparse/arch/xeno/kernel/setup.c
line diff
     1.1 --- a/xen-2.4.16/common/domain.c	Sun Jan 26 11:30:21 2003 +0000
     1.2 +++ b/xen-2.4.16/common/domain.c	Tue Jan 28 15:30:17 2003 +0000
     1.3 @@ -17,7 +17,7 @@
     1.4  #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
     1.5  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
     1.6  
     1.7 -extern int new_do_process_page_updates(page_update_request_t *, int);
     1.8 +extern int do_process_page_updates_bh(page_update_request_t *, int);
     1.9  
    1.10  extern int nr_mods;
    1.11  extern module_t *mod;
    1.12 @@ -383,6 +383,24 @@ unsigned int alloc_new_dom_mem(struct ta
    1.13  
    1.14      return 0;
    1.15  }
    1.16 + 
    1.17 +/* final_setup_guestos is used for final setup and launching of domains other
    1.18 + * than domain 0. ie. the domains that are being built by the userspace dom0
    1.19 + * domain builder.
    1.20 + *
    1.21 + * Initial load map:
    1.22 + *  start_address:
    1.23 + *     OS image
    1.24 + *      ....
    1.25 + *  stack_start:
    1.26 + *  start_info:
    1.27 + *      <one page>
    1.28 + *  page tables:
    1.29 + *      <enough pages>
    1.30 + *  end_address:
    1.31 + *  shared_info:
    1.32 + *      <one page>
    1.33 + */
    1.34  
    1.35  int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
    1.36  {
    1.37 @@ -393,6 +411,7 @@ int final_setup_guestos(struct task_stru
    1.38      unsigned long long time;
    1.39      unsigned long phys_l1tab, phys_l2tab;
    1.40      page_update_request_t * pgt_updates;
    1.41 +    unsigned long curr_update_phys;
    1.42      unsigned long count;
    1.43      net_ring_t *net_ring;
    1.44      net_vif_t *net_vif;
    1.45 @@ -402,16 +421,15 @@ int final_setup_guestos(struct task_stru
    1.46      /* first of all, set up domain pagetables */
    1.47      pgt_updates = (page_update_request_t *)
    1.48          map_domain_mem(meminfo->pgt_update_arr);
    1.49 -    printk(KERN_ALERT "bd240 debug: update request starting virt %lx, phys %lx\n", pgt_updates, meminfo->pgt_update_arr);
    1.50 +    curr_update_phys = meminfo->pgt_update_arr;
    1.51      for(count = 0; count < meminfo->num_pgt_updates; count++){
    1.52 -        printk(KERN_ALERT "bd240 debug: update pair %lx, %lx\n", pgt_updates->ptr, pgt_updates->val); 
    1.53 -        new_do_process_page_updates(pgt_updates, 1);
    1.54 +        do_process_page_updates_bh(pgt_updates, 1);
    1.55          pgt_updates++;
    1.56          if(!((unsigned long)pgt_updates & (PAGE_SIZE-1))){
    1.57 -            pgt_updates--;
    1.58 -            pgt_updates = (page_update_request_t *)map_domain_mem(
    1.59 -                ((frame_table + ((unsigned long)pgt_updates >> 
    1.60 -                PAGE_SHIFT))->next) << PAGE_SHIFT);   
    1.61 +            unmap_domain_mem((void *)((unsigned long)(pgt_updates-1) & PAGE_MASK));
    1.62 +            curr_update_phys = (frame_table + (curr_update_phys >> PAGE_SHIFT))->next 
    1.63 +                << PAGE_SHIFT;
    1.64 +            pgt_updates = (page_update_request_t *)map_domain_mem(curr_update_phys);
    1.65          }
    1.66      }
    1.67  
    1.68 @@ -428,15 +446,18 @@ int final_setup_guestos(struct task_stru
    1.69      l2tab[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = 
    1.70          mk_l2_pgentry(__pa(p->mm.perdomain_pt) | PAGE_HYPERVISOR);
    1.71      p->mm.pagetable = mk_pagetable(phys_l2tab);
    1.72 +    unmap_domain_mem(l2tab);
    1.73  
    1.74      /* map in the shared info structure */
    1.75 -    phys_l2tab = pagetable_val(p->mm.pagetable) + 
    1.76 -        (l2_table_offset(meminfo->virt_shinfo_addr) * sizeof(l2_pgentry_t));
    1.77 +    phys_l2tab = pagetable_val(p->mm.pagetable); 
    1.78      l2tab = map_domain_mem(phys_l2tab);
    1.79 +    l2tab += l2_table_offset(meminfo->virt_shinfo_addr);
    1.80      phys_l1tab = l2_pgentry_to_phys(*l2tab) + 
    1.81          (l1_table_offset(meminfo->virt_shinfo_addr) * sizeof(l1_pgentry_t));
    1.82      l1tab = map_domain_mem(phys_l1tab);
    1.83      *l1tab = mk_l1_pgentry(__pa(p->shared_info) | L1_PROT);
    1.84 +    unmap_domain_mem(l2tab);
    1.85 +    unmap_domain_mem(l1tab);
    1.86  
    1.87      /* set up the shared info structure */
    1.88      rdtscll(time);
    1.89 @@ -523,37 +544,29 @@ int final_setup_guestos(struct task_stru
    1.90  
    1.91      return 0;
    1.92  }
    1.93 -     
    1.94 -/*
    1.95 - * Initial load map:
    1.96 - *  start_address:
    1.97 - *     OS image
    1.98 - *      ....
    1.99 - *  stack_start:
   1.100 - *  start_info:
   1.101 - *      <one page>
   1.102 - *  page tables:
   1.103 - *      <enough pages>
   1.104 - *  end_address:
   1.105 - *  shared_info:
   1.106 - *      <one page>
   1.107 +
   1.108 +static unsigned long alloc_page_from_domain(unsigned long * cur_addr, 
   1.109 +    unsigned long * index)
   1.110 +{
   1.111 +    *cur_addr = (frame_table + (*cur_addr >> PAGE_SHIFT))->prev << PAGE_SHIFT;
   1.112 +    (*index)--;    
   1.113 +    return *cur_addr;
   1.114 +}
   1.115 +
   1.116 +/* setup_guestos is used for building dom0 solely. other domains are built in
   1.117 + * userspace dom0 and final setup is being done by final_setup_guestos.
   1.118   */
   1.119 -#define MB_PER_DOMAIN 16
   1.120  int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
   1.121  {
   1.122 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
   1.123 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
   1.124 -#define ALLOC_FRAME_FROM_DOMAIN() (alloc_address -= PAGE_SIZE)
   1.125      char *src, *dst;
   1.126      int i, dom = p->domain;
   1.127 -    unsigned long start_address, phys_l1tab, phys_l2tab;
   1.128 -    unsigned long cur_address, end_address, alloc_address, vaddr;
   1.129 +    unsigned long phys_l1tab, phys_l2tab;
   1.130 +    unsigned long cur_address, alloc_address;
   1.131      unsigned long virt_load_address, virt_stack_address, virt_shinfo_address;
   1.132 -    unsigned long virt_ftable_start_addr = 0, virt_ftable_end_addr;
   1.133 -    unsigned long ft_mapping = (unsigned long)frame_table;
   1.134 -    unsigned int ft_size = 0;
   1.135      start_info_t  *virt_startinfo_address;
   1.136      unsigned long long time;
   1.137 +    unsigned long count;
   1.138 +    unsigned long alloc_index;
   1.139      l2_pgentry_t *l2tab, *l2start;
   1.140      l1_pgentry_t *l1tab = NULL;
   1.141      struct pfn_info *page = NULL;
   1.142 @@ -575,32 +588,22 @@ int setup_guestos(struct task_struct *p,
   1.143      }
   1.144  
   1.145      if ( alloc_new_dom_mem(p, params->memory_kb) ) return -ENOMEM;
   1.146 -
   1.147 -    /* temporary, *_address have to be reimplemented in another way
   1.148 -     * as we can no longer expect contiguous addr space
   1.149 -     */
   1.150 -    start_address = p->pg_head << PAGE_SHIFT; 
   1.151 -    alloc_address = end_address = start_address + (p->tot_pages << PAGE_SHIFT);
   1.152 -
   1.153 -    /* start_address += (dom * MB_PER_DOMAIN) << 20; */ /* MB -> bytes */
   1.154 -    /* alloc_address = end_address = start_address + (MB_PER_DOMAIN << 20); */
   1.155 +    alloc_address = p->pg_head << PAGE_SHIFT;
   1.156 +    alloc_index = p->tot_pages;
   1.157  
   1.158      if ( (mod[nr_mods-1].mod_end-mod[0].mod_start) > 
   1.159 -         ((end_address-start_address)>>1) )
   1.160 +         (params->memory_kb << 9) )
   1.161      {
   1.162          printk("DOM%d: Guest OS image is too large\n"
   1.163 -               "       (%luMB is greater than %luMB limit for a\n"
   1.164 -               "        %luMB address space)\n",
   1.165 +               "       (%luMB is greater than %uMB limit for a\n"
   1.166 +               "        %uMB address space)\n",
   1.167                 dom, (mod[nr_mods-1].mod_end-mod[0].mod_start)>>20,
   1.168 -               (end_address-start_address)>>21,
   1.169 -               (end_address-start_address)>>20);
   1.170 +               (params->memory_kb)>>11,
   1.171 +               (params->memory_kb)>>10);
   1.172          /* XXX should free domain memory here XXX */
   1.173          return -1;
   1.174      }
   1.175  
   1.176 -    /* Set up initial mappings. */
   1.177 -    printk("DOM%d: Mapping physmem %08lx -> %08lx (%luMB)\n", dom,
   1.178 -           start_address, end_address, (end_address-start_address)>>20);
   1.179      printk("DOM%d: Guest OS virtual load address is %08lx\n", dom,
   1.180             virt_load_address);
   1.181      
   1.182 @@ -608,7 +611,7 @@ int setup_guestos(struct task_struct *p,
   1.183       * WARNING: The new domain must have its 'processor' field
   1.184       * filled in by now !!
   1.185       */
   1.186 -    phys_l2tab = ALLOC_FRAME_FROM_DOMAIN();
   1.187 +    phys_l2tab = alloc_page_from_domain(&alloc_address, &alloc_index);
   1.188      l2start = l2tab = map_domain_mem(phys_l2tab);
   1.189      memcpy(l2tab, idle_pg_table[p->processor], PAGE_SIZE);
   1.190      l2tab[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
   1.191 @@ -621,68 +624,47 @@ int setup_guestos(struct task_struct *p,
   1.192       * make sure a pte exists when we want to map the shared_info struct.
   1.193       */
   1.194  
   1.195 -    /* bd240: not only one extra page but one + num of pages required for
   1.196 -     * frame_table if domain 0 is in question. this ugly for loop 
   1.197 -     * condition is going to change once domain building is moved out
   1.198 -     * of hypervisor.
   1.199 -     */
   1.200 -
   1.201 -    if(dom == 0)
   1.202 -        ft_size = frame_table_size; 
   1.203 -
   1.204      l2tab += l2_table_offset(virt_load_address);
   1.205 -    for ( cur_address  = start_address;
   1.206 -          cur_address != (end_address + PAGE_SIZE + ft_size);
   1.207 -          cur_address += PAGE_SIZE )
   1.208 +    cur_address = p->pg_head << PAGE_SHIFT;
   1.209 +    for ( count  = 0;
   1.210 +          count < p->tot_pages + 1;
   1.211 +          count++)
   1.212      {
   1.213          if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
   1.214          {
   1.215              if ( l1tab != NULL ) unmap_domain_mem(l1tab-1);
   1.216 -            phys_l1tab = ALLOC_FRAME_FROM_DOMAIN();
   1.217 +            phys_l1tab = alloc_page_from_domain(&alloc_address, &alloc_index);
   1.218              *l2tab++ = mk_l2_pgentry(phys_l1tab|L2_PROT);
   1.219              l1tab = map_domain_mem(phys_l1tab);
   1.220              clear_page(l1tab);
   1.221              l1tab += l1_table_offset(
   1.222 -                virt_load_address + cur_address - start_address);
   1.223 +                virt_load_address + (count << PAGE_SHIFT));
   1.224          }
   1.225 -        *l1tab++ = mk_l1_pgentry(cur_address|L1_PROT);
   1.226          
   1.227 -        /* New domain doesn't own shared_info page, or frame_table. */
   1.228 -        if ( cur_address < end_address )
   1.229 +        if( count < alloc_index )
   1.230          {
   1.231 +            *l1tab++ = mk_l1_pgentry(cur_address|L1_PROT);
   1.232              page = frame_table + (cur_address >> PAGE_SHIFT);
   1.233              page->flags = dom | PGT_writeable_page;
   1.234              page->type_count = page->tot_count = 1;
   1.235 +        } 
   1.236 +        else 
   1.237 +        {
   1.238 +            *l1tab++ = mk_l1_pgentry((cur_address|L1_PROT) & ~_PAGE_RW);
   1.239 +            page = frame_table + (cur_address >> PAGE_SHIFT);
   1.240 +            page->flags = dom | PGT_l1_page_table;
   1.241 +            page->type_count = 1;
   1.242 +            page->tot_count = 2; 
   1.243          }
   1.244 +
   1.245 +        cur_address = ((frame_table + (cur_address >> PAGE_SHIFT))->next) << PAGE_SHIFT;
   1.246      }
   1.247      unmap_domain_mem(l1tab-1);
   1.248 -    
   1.249 -    /* Pages that are part of page tables must be read-only. */
   1.250 -    vaddr = virt_load_address + alloc_address - start_address;
   1.251 -    l2tab = l2start + l2_table_offset(vaddr);
   1.252 -    l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
   1.253 -    l1tab += l1_table_offset(vaddr);
   1.254 -    l2tab++;
   1.255 -    for ( cur_address  = alloc_address;
   1.256 -          cur_address != end_address;
   1.257 -          cur_address += PAGE_SIZE )
   1.258 -    {
   1.259 -        if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
   1.260 -        {
   1.261 -            unmap_domain_mem(l1tab-1);
   1.262 -            l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
   1.263 -            l2tab++;
   1.264 -        }
   1.265 -        *l1tab++ = mk_l1_pgentry(l1_pgentry_val(*l1tab) & ~_PAGE_RW);
   1.266 -        page = frame_table + (cur_address >> PAGE_SHIFT);
   1.267 -        page->flags = dom | PGT_l1_page_table;
   1.268 -        page->tot_count++;
   1.269 -    }
   1.270 -    unmap_domain_mem(l1tab-1);
   1.271 +    page = frame_table + (frame_table + p->pg_head)->prev; 
   1.272      page->flags = dom | PGT_l2_page_table;
   1.273  
   1.274      /* Map in the the shared info structure. */
   1.275 -    virt_shinfo_address = end_address - start_address + virt_load_address;
   1.276 +    virt_shinfo_address = virt_load_address + (p->tot_pages << PAGE_SHIFT); 
   1.277      l2tab = l2start + l2_table_offset(virt_shinfo_address);
   1.278      l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
   1.279      l1tab += l1_table_offset(virt_shinfo_address);
   1.280 @@ -695,26 +677,8 @@ int setup_guestos(struct task_struct *p,
   1.281      p->shared_info->domain_time  = time;
   1.282      p->shared_info->ticks_per_ms = ticks_per_usec * 1000;
   1.283  
   1.284 -    /* for DOM0, setup mapping of frame table */
   1.285 -    if ( dom == 0 )
   1.286 -    {
   1.287 -        virt_ftable_start_addr = virt_shinfo_address + PAGE_SIZE;
   1.288 -        virt_ftable_end_addr = virt_ftable_start_addr + frame_table_size;
   1.289 -        for(cur_address = virt_ftable_start_addr;
   1.290 -            cur_address < virt_ftable_end_addr;
   1.291 -            cur_address += PAGE_SIZE)
   1.292 -        {
   1.293 -            l2tab = l2start + l2_table_offset(cur_address);
   1.294 -            l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
   1.295 -            l1tab += l1_table_offset(cur_address);
   1.296 -            *l1tab = mk_l1_pgentry(__pa(ft_mapping)|L1_PROT);
   1.297 -            unmap_domain_mem(l1tab);
   1.298 -            ft_mapping += PAGE_SIZE;
   1.299 -        }
   1.300 -    }
   1.301 -
   1.302      virt_startinfo_address = (start_info_t *)
   1.303 -        (alloc_address - start_address - PAGE_SIZE + virt_load_address);
   1.304 +        (virt_load_address + ((alloc_index - 1) << PAGE_SHIFT));
   1.305      virt_stack_address  = (unsigned long)virt_startinfo_address;
   1.306  
   1.307      unmap_domain_mem(l2start);
   1.308 @@ -731,16 +695,12 @@ int setup_guestos(struct task_struct *p,
   1.309  
   1.310      /* Set up start info area. */
   1.311      memset(virt_startinfo_address, 0, sizeof(*virt_startinfo_address));
   1.312 -    virt_startinfo_address->nr_pages = (end_address-start_address)>>PAGE_SHIFT;
   1.313 +    virt_startinfo_address->nr_pages = p->tot_pages;
   1.314      virt_startinfo_address->shared_info = 
   1.315          (shared_info_t *)virt_shinfo_address;
   1.316 -    virt_startinfo_address->pt_base = 
   1.317 -        end_address - PAGE_SIZE - start_address + virt_load_address;
   1.318 -    virt_startinfo_address->phys_base = start_address;
   1.319 -    /* NB. Next field will be NULL if dom != 0. */
   1.320 -    virt_startinfo_address->frame_table = virt_ftable_start_addr;
   1.321 -    virt_startinfo_address->frame_table_len = ft_size;
   1.322 -    virt_startinfo_address->frame_table_pa = __pa(frame_table);
   1.323 +    virt_startinfo_address->pt_base = virt_load_address + 
   1.324 +        ((p->tot_pages - 1) << PAGE_SHIFT); 
   1.325 +    virt_startinfo_address->phys_base = p->pg_head << PAGE_SHIFT;
   1.326  
   1.327      /* Add virtual network interfaces and point to them in startinfo. */
   1.328      while (params->num_vifs-- > 0) {
     2.1 --- a/xen-2.4.16/common/memory.c	Sun Jan 26 11:30:21 2003 +0000
     2.2 +++ b/xen-2.4.16/common/memory.c	Tue Jan 28 15:30:17 2003 +0000
     2.3 @@ -569,6 +569,9 @@ static int mod_l1_entry(unsigned long pa
     2.4          if ( (l1_pgentry_val(new_l1_entry) &
     2.5                (_PAGE_GLOBAL|_PAGE_PAT)) ) 
     2.6          {
     2.7 +
     2.8 +            printk(KERN_ALERT "bd240 debug: bad l1 entry val %lx\n", l1_pgentry_val(new_l1_entry) & (_PAGE_GLOBAL | _PAGE_PAT));
     2.9 +
    2.10              MEM_LOG("Bad L1 entry val %04lx",
    2.11                      l1_pgentry_val(new_l1_entry) & 
    2.12                      (_PAGE_GLOBAL|_PAGE_PAT));
    2.13 @@ -588,8 +591,10 @@ static int mod_l1_entry(unsigned long pa
    2.14              }
    2.15              
    2.16              if ( get_page(l1_pgentry_to_pagenr(new_l1_entry),
    2.17 -                          l1_pgentry_val(new_l1_entry) & _PAGE_RW) )
    2.18 +                          l1_pgentry_val(new_l1_entry) & _PAGE_RW) ){
    2.19 +                printk(KERN_ALERT "bd240 debug: get_page err\n");
    2.20                  goto fail;
    2.21 +            }
    2.22          } 
    2.23      }
    2.24      else if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) )
    2.25 @@ -694,122 +699,26 @@ static int do_extended_command(unsigned 
    2.26      return err;
    2.27  }
    2.28  
    2.29 -/* Apply updates to page table @pagetable_id within the current domain. */
    2.30 -int do_process_page_updates(page_update_request_t *updates, int count)
    2.31 +/* functions to handle page table updates: upper half is invoked in case pt updates
    2.32 + * are requested by a domain and it invokes copy_from_user. bottom half is invoked
    2.33 + * both in case of domain downcall and domain building by hypervisor.
    2.34 + */
    2.35 +page_update_request_t * do_process_page_updates_uh(page_update_request_t *updates,
    2.36 +    int count)
    2.37  {
    2.38 -    page_update_request_t cur;
    2.39 -    unsigned long flags, pfn;
    2.40 -    struct pfn_info *page;
    2.41 -    int err = 0, i;
    2.42 -
    2.43 -    for ( i = 0; i < count; i++ )
    2.44 -    {
    2.45 -        if ( copy_from_user(&cur, updates, sizeof(cur)) )
    2.46 -        {
    2.47 -            kill_domain_with_errmsg("Cannot read page update request");
    2.48 -        }
    2.49 -
    2.50 -        pfn = cur.ptr >> PAGE_SHIFT;
    2.51 -        if ( pfn >= max_page )
    2.52 -        {
    2.53 -            MEM_LOG("Page out of range (%08lx > %08lx)", pfn, max_page);
    2.54 -            kill_domain_with_errmsg("Page update request out of range");
    2.55 -        }
    2.56 -
    2.57 -        err = 1;
    2.58 -
    2.59 -        /* Least significant bits of 'ptr' demux the operation type. */
    2.60 -        switch ( cur.ptr & (sizeof(l1_pgentry_t)-1) )
    2.61 -        {
    2.62 -
    2.63 -            /*
    2.64 -             * PGREQ_NORMAL: Normal update to any level of page table.
    2.65 -             */
    2.66 -        case PGREQ_NORMAL:
    2.67 -            page = frame_table + pfn;
    2.68 -            flags = page->flags;
    2.69 -            if ( DOMAIN_OKAY(flags) )
    2.70 -            {
    2.71 -                switch ( (flags & PG_type_mask) )
    2.72 -                {
    2.73 -                case PGT_l1_page_table: 
    2.74 -                    err = mod_l1_entry(cur.ptr, mk_l1_pgentry(cur.val)); 
    2.75 -                    break;
    2.76 -                case PGT_l2_page_table: 
    2.77 -                    err = mod_l2_entry(cur.ptr, mk_l2_pgentry(cur.val)); 
    2.78 -                    break;
    2.79 -                default:
    2.80 -                    MEM_LOG("Update to non-pt page %08lx", cur.ptr);
    2.81 -                    break;
    2.82 -                }
    2.83 -            }
    2.84 -            break;
    2.85 +    page_update_request_t * ret = kmalloc(sizeof(page_update_request_t) * count, 
    2.86 +        GFP_KERNEL);
    2.87  
    2.88 -            /*
    2.89 -             * PGREQ_UNCHECKED_UPDATE: Make an unchecked update to a
    2.90 -             * bottom-level page-table entry.
    2.91 -             * Restrictions apply:
    2.92 -             *  1. Update only allowed by domain 0.
    2.93 -             *  2. Update must be to a level-1 pte belonging to dom0.
    2.94 -             */
    2.95 -        case PGREQ_UNCHECKED_UPDATE:
    2.96 -            cur.ptr &= ~(sizeof(l1_pgentry_t) - 1);
    2.97 -            page = frame_table + pfn;
    2.98 -            flags = page->flags;
    2.99 -            if ( (flags | current->domain) == PGT_l1_page_table )
   2.100 -            {
   2.101 -                unsigned long *va = map_domain_mem(cur.ptr);
   2.102 -                *va = cur.val;
   2.103 -                unmap_domain_mem(va);
   2.104 -                err = 0;
   2.105 -            }
   2.106 -            else
   2.107 -            {
   2.108 -                MEM_LOG("UNCHECKED_UPDATE: Bad domain %d, or"
   2.109 -                        " bad pte type %08lx", current->domain, flags);
   2.110 -            }
   2.111 -            break;
   2.112 -
   2.113 -            /*
   2.114 -             * PGREQ_EXTENDED_COMMAND: Extended command is specified
   2.115 -             * in the least-siginificant bits of the 'value' field.
   2.116 -             */
   2.117 -        case PGREQ_EXTENDED_COMMAND:
   2.118 -            cur.ptr &= ~(sizeof(l1_pgentry_t) - 1);
   2.119 -            err = do_extended_command(cur.ptr, cur.val);
   2.120 -            break;
   2.121 -
   2.122 -        default:
   2.123 -            MEM_LOG("Invalid page update command %08lx", cur.ptr);
   2.124 -            break;
   2.125 -        }
   2.126 -
   2.127 -        if ( err )
   2.128 -        {
   2.129 -            page = frame_table + (cur.ptr >> PAGE_SHIFT);
   2.130 -            printk(KERN_ALERT "bd240 debug: Update request %d\n", cur.ptr & (sizeof(l1_pgentry_t) - 1)); 
   2.131 -            printk(KERN_ALERT "bd240 debug: Update request %lx, %lx\n", cur.ptr, cur.val);
   2.132 -            printk(KERN_ALERT "bd240 debug: Page flags %lx\n", page->flags);
   2.133 -
   2.134 -            kill_domain_with_errmsg("Illegal page update request");
   2.135 -        }
   2.136 -
   2.137 -        updates++;
   2.138 +    if ( copy_from_user(ret, updates, sizeof(page_update_request_t) * count) )
   2.139 +    {
   2.140 +        kill_domain_with_errmsg("Cannot read page update request");
   2.141      }
   2.142 -
   2.143 -    if ( tlb_flush[smp_processor_id()] )
   2.144 -    {
   2.145 -        tlb_flush[smp_processor_id()] = 0;
   2.146 -        __asm__ __volatile__ (
   2.147 -            "movl %%eax,%%cr3" : : 
   2.148 -            "a" (pagetable_val(current->mm.pagetable)));
   2.149 -    }
   2.150 -
   2.151 -    return(0);
   2.152 +    
   2.153 +    return ret;
   2.154  }
   2.155  
   2.156  /* Apply updates to page table @pagetable_id within the current domain. */
   2.157 -int new_do_process_page_updates(page_update_request_t * cur, int count)
   2.158 +int do_process_page_updates_bh(page_update_request_t * cur, int count)
   2.159  {
   2.160      unsigned long flags, pfn;
   2.161      struct pfn_info *page;
   2.162 @@ -837,11 +746,8 @@ int new_do_process_page_updates(page_upd
   2.163              page = frame_table + pfn;
   2.164              flags = page->flags;
   2.165              
   2.166 -            printk(KERN_ALERT "bd240 debug: normal update\n");
   2.167 -            
   2.168 -            if ( (flags & PG_domain_mask) == current->domain )
   2.169 +            if ( DOMAIN_OKAY(flags) )
   2.170              {
   2.171 -                printk(KERN_ALERT "bd240 debug: normal update inside\n");
   2.172                  switch ( (flags & PG_type_mask) )
   2.173                  {
   2.174                  case PGT_l1_page_table: 
   2.175 @@ -856,8 +762,6 @@ int new_do_process_page_updates(page_upd
   2.176                  }
   2.177              }
   2.178  
   2.179 -            printk(KERN_ALERT "bd240 debug: normal update finish\n");
   2.180 -
   2.181              break;
   2.182  
   2.183              /*
   2.184 @@ -901,10 +805,6 @@ int new_do_process_page_updates(page_upd
   2.185          if ( err )
   2.186          {
   2.187              page = frame_table + (cur->ptr >> PAGE_SHIFT);
   2.188 -            printk(KERN_ALERT "bd240 debug: Update request %lx\n", cur->ptr & (sizeof(l1_pgentry_t) - 1)); 
   2.189 -            printk(KERN_ALERT "bd240 debug: Update request %lx, %lx\n", cur->ptr, cur->val);
   2.190 -            printk(KERN_ALERT "bd240 debug: Page flags %lx\n", page->flags);
   2.191 -
   2.192              kill_domain_with_errmsg("Illegal page update request");
   2.193          }
   2.194  
   2.195 @@ -921,3 +821,12 @@ int new_do_process_page_updates(page_upd
   2.196  
   2.197      return(0);
   2.198  }
   2.199 +
   2.200 +/* Apply updates to page table @pagetable_id within the current domain. */
   2.201 +int do_process_page_updates(page_update_request_t *updates, int count)
   2.202 +{
   2.203 +    page_update_request_t * pg_updates;
   2.204 +
   2.205 +    pg_updates = do_process_page_updates_uh(updates, count);
   2.206 +    return do_process_page_updates_bh(pg_updates, count);
   2.207 +}
     3.1 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Sun Jan 26 11:30:21 2003 +0000
     3.2 +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Tue Jan 28 15:30:17 2003 +0000
     3.3 @@ -200,9 +200,6 @@ typedef struct start_info_st {
     3.4      net_ring_t *net_rings;
     3.5      int num_net_rings;
     3.6      blk_ring_t *blk_ring;         /* block io communication rings */
     3.7 -    unsigned long frame_table;    /* mapping of the frame_table for dom0 */
     3.8 -    unsigned long frame_table_len;
     3.9 -    unsigned long frame_table_pa; /* frame_table physical address */
    3.10      unsigned char cmd_line[1];    /* variable-length */
    3.11  } start_info_t;
    3.12  
     4.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/dom0_core.c	Sun Jan 26 11:30:21 2003 +0000
     4.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/dom0_core.c	Tue Jan 28 15:30:17 2003 +0000
     4.3 @@ -34,12 +34,10 @@
     4.4  
     4.5  #define XENO_BASE       "xeno"          // proc file name defs should be in separate .h
     4.6  #define DOM0_CMD_INTF   "dom0_cmd"
     4.7 -#define DOM0_FT         "frame_table"
     4.8  #define DOM0_NEWDOM     "new_dom_data"
     4.9  
    4.10  #define MAX_LEN         16
    4.11  #define DOM_DIR         "dom"
    4.12 -#define DOM_TS          "task_data"
    4.13  #define DOM_MEM         "mem"
    4.14  
    4.15  static struct proc_dir_entry *xeno_base;
    4.16 @@ -50,11 +48,6 @@ unsigned long direct_mmap(unsigned long,
    4.17  int direct_unmap(unsigned long, unsigned long);
    4.18  int direct_disc_unmap(unsigned long, unsigned long, int);
    4.19  
    4.20 -/* frame_table mapped from dom0 */
    4.21 -frame_table_t * frame_table;
    4.22 -unsigned long frame_table_len;
    4.23 -unsigned long frame_table_pa;
    4.24 -
    4.25  static unsigned char readbuf[1204];
    4.26  
    4.27  static int cmd_read_proc(char *page, char **start, off_t off,
    4.28 @@ -67,58 +60,6 @@ static int cmd_read_proc(char *page, cha
    4.29      return strlen(page);
    4.30  }
    4.31  
    4.32 -static ssize_t ts_read(struct file * file, char * buff, size_t size, loff_t * off)
    4.33 -{
    4.34 -    dom0_op_t op;
    4.35 -    unsigned long addr;
    4.36 -    pgprot_t prot;
    4.37 -    int ret = 0;
    4.38 -
    4.39 -    /* retrieve domain specific data from proc_dir_entry */
    4.40 -    dom_procdata_t * dom_data = (dom_procdata_t *)((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
    4.41 -    
    4.42 -    /* 
    4.43 -     * get the phys addr of the task struct for the requested
    4.44 -     * domain
    4.45 -     */
    4.46 -    op.cmd = DOM0_MAPTASK;
    4.47 -    op.u.mapdomts.domain = dom_data->domain;
    4.48 -    op.u.mapdomts.ts_phy_addr = -1;
    4.49 -
    4.50 -    ret = HYPERVISOR_dom0_op(&op);
    4.51 -    if(ret != 0)
    4.52 -       return -EAGAIN;
    4.53 -
    4.54 -    prot = PAGE_SHARED; 
    4.55 -
    4.56 -    /* remap the range using xen specific routines */
    4.57 -    addr = direct_mmap(op.u.mapdomts.ts_phy_addr, PAGE_SIZE, prot, 0, 0);
    4.58 -    copy_to_user((unsigned long *)buff, &addr, sizeof(addr));
    4.59 -    dom_data->map_size = PAGE_SIZE;
    4.60 -
    4.61 -    return sizeof(addr);
    4.62 -     
    4.63 -}
    4.64 -
    4.65 -static ssize_t ts_write(struct file * file, const char * buff, size_t size , loff_t * off)
    4.66 -{
    4.67 -    unsigned long addr;
    4.68 -    dom_procdata_t * dom_data = (dom_procdata_t *)((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
    4.69 -    
    4.70 -    copy_from_user(&addr, (unsigned long *)buff, sizeof(addr));
    4.71 -    
    4.72 -    if(direct_unmap(addr, dom_data->map_size) == 0){
    4.73 -        return sizeof(addr);
    4.74 -    } else {
    4.75 -        return -1;
    4.76 -    }
    4.77 -}
    4.78 - 
    4.79 -struct file_operations ts_ops = {
    4.80 -    read:   ts_read,
    4.81 -    write:  ts_write,
    4.82 -};
    4.83 -
    4.84  static void create_proc_dom_entries(int dom)
    4.85  {
    4.86      struct proc_dir_entry * dir;
    4.87 @@ -133,16 +74,6 @@ static void create_proc_dom_entries(int 
    4.88  
    4.89      dir = proc_mkdir(dir_name, xeno_base);
    4.90      dir->data = dom_data;
    4.91 -
    4.92 -    file = create_proc_entry(DOM_TS, 0600, dir);
    4.93 -    if(file != NULL)
    4.94 -    {   
    4.95 -        file->owner = THIS_MODULE;
    4.96 -        file->nlink = 1;
    4.97 -        file->proc_fops = &ts_ops;
    4.98 -    
    4.99 -        file->data = dom_data;
   4.100 -    }
   4.101  }
   4.102  
   4.103  static ssize_t dom_mem_write(struct file * file, const char * buff, 
   4.104 @@ -303,45 +234,8 @@ out:
   4.105      
   4.106  }
   4.107  
   4.108 -static ssize_t ft_write(struct file * file, const char * buff, size_t size , loff_t * off)
   4.109 -{
   4.110 -    unsigned long addr;
   4.111 -    
   4.112 -    copy_from_user(&addr, (unsigned long *)buff, sizeof(addr));
   4.113 -    
   4.114 -    if(direct_unmap(addr, frame_table_len) == 0){
   4.115 -        return sizeof(addr);
   4.116 -    } else {
   4.117 -        return -1;
   4.118 -    }
   4.119 -}
   4.120 -
   4.121 -static ssize_t ft_read(struct file * file, char * buff, size_t size, loff_t * off)
   4.122 -{
   4.123 -    unsigned long addr;
   4.124 -    pgprot_t prot;
   4.125 -
   4.126 -    prot = PAGE_SHARED; 
   4.127 -
   4.128 -    /* remap the range using xen specific routines */
   4.129 -    addr = direct_mmap(frame_table_pa, frame_table_len, prot, 0, 0);
   4.130 -    copy_to_user((unsigned long *)buff, &addr, sizeof(addr));
   4.131 -
   4.132 -    return sizeof(addr);
   4.133 -     
   4.134 -}
   4.135 -
   4.136 -struct file_operations ft_ops = {
   4.137 -    read:   ft_read,
   4.138 -    write: ft_write,
   4.139 -};
   4.140 -
   4.141  static int __init init_module(void)
   4.142  {
   4.143 -    frame_table = (frame_table_t *)start_info.frame_table;
   4.144 -    frame_table_len = start_info.frame_table_len;
   4.145 -    frame_table_pa = start_info.frame_table_pa;
   4.146 -
   4.147      /* xeno proc root setup */
   4.148      xeno_base = proc_mkdir(XENO_BASE, &proc_root); 
   4.149  
   4.150 @@ -356,15 +250,6 @@ static int __init init_module(void)
   4.151          dom0_cmd_intf->write_proc = cmd_write_proc;
   4.152      }
   4.153  
   4.154 -    /* frame table mapping, to be mmaped */
   4.155 -    proc_ft = create_proc_entry(DOM0_FT, 0600, xeno_base);
   4.156 -    if(proc_ft != NULL)
   4.157 -    {   
   4.158 -        proc_ft->owner = THIS_MODULE;
   4.159 -        proc_ft->nlink = 1;
   4.160 -        proc_ft->proc_fops = &ft_ops;
   4.161 -    }
   4.162 -
   4.163      /* set up /proc entries for dom 0 */
   4.164      create_proc_dom_entries(0);
   4.165  
     5.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/kernel/setup.c	Sun Jan 26 11:30:21 2003 +0000
     5.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/kernel/setup.c	Tue Jan 28 15:30:17 2003 +0000
     5.3 @@ -259,7 +259,6 @@ void __init setup_arch(char **cmdline_p)
     5.4          }
     5.5      }
     5.6      cur_pgd = init_mm.pgd = (pgd_t *)start_info.pt_base;
     5.7 -    queue_pgd_pin(__pa(init_mm.pgd));
     5.8  
     5.9  #ifdef CONFIG_BLK_DEV_INITRD
    5.10      if (start_info.mod_start) {