ia64/xen-unstable

changeset 2189:0dd06fdaffd4

bitkeeper revision 1.1159.23.1 (411a606fwcWYG3KD9XAVULSlXBrivA)

Writable pagetable fixes.
author cl349@freefall.cl.cam.ac.uk
date Wed Aug 11 18:07:43 2004 +0000 (2004-08-11)
parents d7b517eaf176
children 8927b36dfcc0
files xen/arch/x86/memory.c xen/common/kernel.c xen/common/memory.c xen/include/asm-x86/mm.h xen/include/hypervisor-ifs/hypervisor-if.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Wed Aug 11 07:33:29 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Wed Aug 11 18:07:43 2004 +0000
     1.3 @@ -136,9 +136,14 @@ static struct {
     1.4  #define GPS (percpu_info[smp_processor_id()].gps ? : current)
     1.5  
     1.6  
     1.7 -void init_percpu_info(void)
     1.8 +void ptwr_init_backpointers(void);
     1.9 +
    1.10 +void arch_init_memory(void)
    1.11  {
    1.12      memset(percpu_info, 0, sizeof(percpu_info));
    1.13 +
    1.14 +    vm_assist_info[VMASST_TYPE_writeable_pagetables].enable =
    1.15 +        ptwr_init_backpointers;
    1.16  }
    1.17  
    1.18  static void __invalidate_shadow_ldt(struct domain *d)
    1.19 @@ -255,6 +260,17 @@ static int get_page_and_type_from_pagenr
    1.20  }
    1.21  
    1.22  
    1.23 +static inline void set_l1_page_va(unsigned long pfn,
    1.24 +                                  unsigned long va_idx)
    1.25 +{
    1.26 +    struct pfn_info *page;
    1.27 +    
    1.28 +    page = &frame_table[pfn];
    1.29 +    page->u.inuse.type_info &= ~PGT_va_mask;
    1.30 +    page->u.inuse.type_info |= va_idx << PGT_va_shift;
    1.31 +}
    1.32 +
    1.33 +
    1.34  /*
    1.35   * We allow an L2 tables to map each other (a.k.a. linear page tables). It
    1.36   * needs some special care with reference counst and access permissions:
    1.37 @@ -413,9 +429,11 @@ static int alloc_l2_table(struct pfn_inf
    1.38     
    1.39      pl2e = map_domain_mem(page_nr << PAGE_SHIFT);
    1.40  
    1.41 -    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
    1.42 +    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) {
    1.43          if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
    1.44              goto fail;
    1.45 +        set_l1_page_va(l2_pgentry_val(pl2e[i]) >> PAGE_SHIFT, i);
    1.46 +    }
    1.47      
    1.48  #if defined(__i386__)
    1.49      /* Now we add our private high mappings. */
    1.50 @@ -509,17 +527,6 @@ static inline int update_l2e(l2_pgentry_
    1.51  }
    1.52  
    1.53  
    1.54 -static inline void set_l1_page_va(unsigned long pfn,
    1.55 -                                  unsigned long va_idx)
    1.56 -{
    1.57 -    struct pfn_info *page;
    1.58 -    
    1.59 -    page = &frame_table[pfn];
    1.60 -    page->u.inuse.type_info &= ~PGT_va_mask;
    1.61 -    page->u.inuse.type_info |= va_idx << PGT_va_shift;
    1.62 -}
    1.63 -
    1.64 -
    1.65  /* Update the L2 entry at pl2e to new value nl2e. pl2e is within frame pfn. */
    1.66  static int mod_l2_entry(l2_pgentry_t *pl2e, 
    1.67                          l2_pgentry_t nl2e, 
    1.68 @@ -1266,32 +1273,33 @@ void ptwr_reconnect_disconnected(unsigne
    1.69      l1_pgentry_t *pl1e;
    1.70      int cpu = smp_processor_id();
    1.71      int i;
    1.72 +    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.73 +        [ptwr_info[cpu].writable_l1>>PAGE_SHIFT];
    1.74  
    1.75  #ifdef PTWR_TRACK_DOMAIN
    1.76      if (ptwr_domain[cpu] != get_current()->domain)
    1.77          printk("ptwr_reconnect_disconnected domain mismatch %d != %d\n",
    1.78                 ptwr_domain[cpu], get_current()->domain);
    1.79  #endif
    1.80 -    PTWR_PRINTK(("page fault in disconnected space: addr %08lx space %08lx\n",
    1.81 -		 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    1.82 +    PTWR_PRINTK(("[A] page fault in disconnected space: addr %08lx space %08lx\n",
    1.83 +                 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    1.84      pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
    1.85  
    1.86 -    if (__get_user(pte, ptwr_info[cpu].writable_l1))
    1.87 +    if (__get_user(pte, writable_pte))
    1.88          BUG();
    1.89      pfn = pte >> PAGE_SHIFT;
    1.90      page = &frame_table[pfn];
    1.91  
    1.92      /* reconnect l1 page */
    1.93 -    PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
    1.94 -		 l2_pgentry_val(*pl2e),
    1.95 -		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
    1.96 -						PAGE_SHIFT]) >> PAGE_SHIFT,
    1.97 -		 frame_table[pfn].u.inuse.type_info,
    1.98 -		 frame_table[pfn].u.inuse.count_info,
    1.99 -		 frame_table[pfn].u.inuse.domain->domain));
   1.100 +    PTWR_PRINTK(("[A]     pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n",
   1.101 +                 pl2e, l2_pgentry_val(*pl2e),
   1.102 +                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.103 +                                                PAGE_SHIFT]) >> PAGE_SHIFT,
   1.104 +                 frame_table[pfn].u.inuse.type_info,
   1.105 +                 frame_table[pfn].u.inuse.count_info,
   1.106 +                 frame_table[pfn].u.inuse.domain->domain));
   1.107  
   1.108 -    nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~0x800) |
   1.109 -                         _PAGE_PRESENT);
   1.110 +    nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
   1.111      pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
   1.112      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.113          l1_pgentry_t ol1e, nl1e;
   1.114 @@ -1312,22 +1320,23 @@ void ptwr_reconnect_disconnected(unsigne
   1.115      unmap_domain_mem(pl1e);
   1.116      update_l2e(pl2e, *pl2e, nl2e);
   1.117  
   1.118 -    PTWR_PRINTK(("now pl2e %p l2e %08lx              taf %08x/%08x/%u\n", pl2e,
   1.119 -		 l2_pgentry_val(*pl2e),
   1.120 -		 frame_table[pfn].u.inuse.type_info,
   1.121 -		 frame_table[pfn].u.inuse.count_info,
   1.122 -		 frame_table[pfn].u.inuse.domain->domain));
   1.123 +    PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              taf %08x/%08x/%u\n",
   1.124 +                 pl2e, l2_pgentry_val(*pl2e),
   1.125 +                 frame_table[pfn].u.inuse.type_info,
   1.126 +                 frame_table[pfn].u.inuse.count_info,
   1.127 +                 frame_table[pfn].u.inuse.domain->domain));
   1.128      ptwr_info[cpu].disconnected = ENTRIES_PER_L2_PAGETABLE;
   1.129      /* make pt page write protected */
   1.130 -    if (__get_user(pte, ptwr_info[cpu].writable_l1))
   1.131 +    if (__get_user(pte, writable_pte))
   1.132          BUG();
   1.133 -    PTWR_PRINTK(("writable_l1 at %p is %08lx\n", ptwr_info[cpu].writable_l1,
   1.134 -		 pte));
   1.135 +    PTWR_PRINTK(("[A] writable_l1 at %p is %08lx\n",
   1.136 +                 writable_pte, pte));
   1.137      pte &= ~_PAGE_RW;
   1.138 -    if (__put_user(pte, ptwr_info[cpu].writable_l1))
   1.139 +    if (__put_user(pte, writable_pte))
   1.140          BUG();
   1.141 -    PTWR_PRINTK(("writable_l1 at %p now %08lx\n", ptwr_info[cpu].writable_l1,
   1.142 -		 pte));
   1.143 +    __flush_tlb_one(ptwr_info[cpu].writable_l1);
   1.144 +    PTWR_PRINTK(("[A] writable_l1 at %p now %08lx\n",
   1.145 +                 writable_pte, pte));
   1.146      /* and try again */
   1.147      return;
   1.148  }
   1.149 @@ -1355,11 +1364,13 @@ void ptwr_flush_inactive(void)
   1.150      }
   1.151  #endif
   1.152      for (idx = 0; idx < ptwr_info[cpu].writable_idx; idx++) {
   1.153 -        if (__get_user(pte, ptwr_info[cpu].writables[idx]))
   1.154 +        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.155 +            [ptwr_info[cpu].writables[idx]>>PAGE_SHIFT];
   1.156 +        if (__get_user(pte, writable_pte))
   1.157              BUG();
   1.158          pfn = pte >> PAGE_SHIFT;
   1.159          page = &frame_table[pfn];
   1.160 -        PTWR_PRINTK(("alloc l1 page %p\n", page));
   1.161 +        PTWR_PRINTK(("[I] alloc l1 page %p\n", page));
   1.162  
   1.163          pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.164          for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.165 @@ -1376,13 +1387,14 @@ void ptwr_flush_inactive(void)
   1.166          unmap_domain_mem(pl1e);
   1.167  
   1.168          /* make pt page writable */
   1.169 -        PTWR_PRINTK(("writable_l1 at %p is %08lx\n",
   1.170 -		     ptwr_info[cpu].writables[idx], pte));
   1.171 +        PTWR_PRINTK(("[I] writable_l1 at %p is %08lx\n",
   1.172 +                     writable_pte, pte));
   1.173          pte &= ~_PAGE_RW;
   1.174 -        if (__put_user(pte, ptwr_info[cpu].writables[idx]))
   1.175 +        if (__put_user(pte, writable_pte))
   1.176              BUG();
   1.177 -        PTWR_PRINTK(("writable_l1 at %p now %08lx\n",
   1.178 -		     ptwr_info[cpu].writables[idx], pte));
   1.179 +        __flush_tlb_one(ptwr_info[cpu].writables[idx]);
   1.180 +        PTWR_PRINTK(("[I] writable_l1 at %p now %08lx\n",
   1.181 +                     writable_pte, pte));
   1.182      }
   1.183      ptwr_info[cpu].writable_idx = 0;
   1.184  }
   1.185 @@ -1398,7 +1410,7 @@ int ptwr_do_page_fault(unsigned long add
   1.186  
   1.187  #if 0
   1.188      PTWR_PRINTK(("get user %p for va %08lx\n",
   1.189 -		 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   1.190 +                 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   1.191  #endif
   1.192      if (l2_pgentry_val(linear_l2_table[addr >> L2_PAGETABLE_SHIFT]) &
   1.193          _PAGE_PRESENT &&
   1.194 @@ -1407,7 +1419,7 @@ int ptwr_do_page_fault(unsigned long add
   1.195          pfn = pte >> PAGE_SHIFT;
   1.196  #if 0
   1.197          PTWR_PRINTK(("check pte %08lx = pfn %08lx for va %08lx\n", pte, pfn,
   1.198 -		     addr));
   1.199 +                     addr));
   1.200  #endif
   1.201          page = &frame_table[pfn];
   1.202          if ((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table) {
   1.203 @@ -1419,22 +1431,21 @@ int ptwr_do_page_fault(unsigned long add
   1.204              pl2e = &linear_l2_table[(page->u.inuse.type_info &
   1.205                                       PGT_va_mask) >> PGT_va_shift];
   1.206              PTWR_PRINTK(("page_fault on l1 pt at va %08lx, pt for %08x, "
   1.207 -			 "pfn %08lx\n", addr,
   1.208 -			 ((page->u.inuse.type_info & PGT_va_mask) >>
   1.209 -			  PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   1.210 +                         "pfn %08lx\n", addr,
   1.211 +                         ((page->u.inuse.type_info & PGT_va_mask) >>
   1.212 +                          PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   1.213              if (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) {
   1.214                  l1_pgentry_t *pl1e;
   1.215 -                PTWR_PRINTK(("freeing l1 page %p taf %08x/%08x\n", page,
   1.216 -			     page->u.inuse.type_info,
   1.217 -			     page->u.inuse.count_info));
   1.218 +                PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page,
   1.219 +                             page->u.inuse.type_info,
   1.220 +                             page->u.inuse.count_info));
   1.221                  if (ptwr_info[cpu].writable_idx == PTWR_NR_WRITABLES)
   1.222                      ptwr_flush_inactive();
   1.223 -                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] =
   1.224 -		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   1.225 +                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] = addr;
   1.226  
   1.227                  pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.228                  memcpy(&ptwr_info[cpu].writable_page[
   1.229 -			   ptwr_info[cpu].writable_idx][0],
   1.230 +                           ptwr_info[cpu].writable_idx][0],
   1.231                         pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.232                  unmap_domain_mem(pl1e);
   1.233  
   1.234 @@ -1444,28 +1455,26 @@ int ptwr_do_page_fault(unsigned long add
   1.235                  l1_pgentry_t *pl1e;
   1.236                  if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE)
   1.237                      ptwr_reconnect_disconnected(addr);
   1.238 -                PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx "
   1.239 -			     "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.240 -			     l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.241 -							    >> PAGE_SHIFT]) >>
   1.242 -			     PAGE_SHIFT,
   1.243 -			     frame_table[pfn].u.inuse.type_info,
   1.244 -			     frame_table[pfn].u.inuse.count_info,
   1.245 -			     frame_table[pfn].u.inuse.domain->domain));
   1.246 +                PTWR_PRINTK(("[A]    pl2e %p l2e %08lx pfn %08lx "
   1.247 +                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.248 +                             l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.249 +                                                            >> PAGE_SHIFT]) >>
   1.250 +                             PAGE_SHIFT,
   1.251 +                             frame_table[pfn].u.inuse.type_info,
   1.252 +                             frame_table[pfn].u.inuse.count_info,
   1.253 +                             frame_table[pfn].u.inuse.domain->domain));
   1.254                  /* disconnect l1 page */
   1.255 -                nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) &
   1.256 -                                      ~_PAGE_PRESENT) | 0x800);
   1.257 +                nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
   1.258                  update_l2e(pl2e, *pl2e, nl2e);
   1.259  
   1.260                  ptwr_info[cpu].disconnected =
   1.261 -		    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   1.262 -                PTWR_PRINTK(("now pl2e %p l2e %08lx              "
   1.263 -			     "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.264 -			     frame_table[pfn].u.inuse.type_info,
   1.265 -			     frame_table[pfn].u.inuse.count_info,
   1.266 -			     frame_table[pfn].u.inuse.domain->domain));
   1.267 -                ptwr_info[cpu].writable_l1 =
   1.268 -		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   1.269 +                    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   1.270 +                PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              "
   1.271 +                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.272 +                             frame_table[pfn].u.inuse.type_info,
   1.273 +                             frame_table[pfn].u.inuse.count_info,
   1.274 +                             frame_table[pfn].u.inuse.domain->domain));
   1.275 +                ptwr_info[cpu].writable_l1 = addr;
   1.276                  pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) <<
   1.277                                        PAGE_SHIFT);
   1.278                  memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e,
   1.279 @@ -1475,7 +1484,7 @@ int ptwr_do_page_fault(unsigned long add
   1.280              /* make pt page writable */
   1.281              pte |= _PAGE_RW;
   1.282              PTWR_PRINTK(("update %p pte to %08lx\n",
   1.283 -			 &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.284 +                         &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.285              if (__put_user(pte, (unsigned long *)
   1.286                             &linear_pg_table[addr>>PAGE_SHIFT]))
   1.287                  BUG();
   1.288 @@ -1485,6 +1494,28 @@ int ptwr_do_page_fault(unsigned long add
   1.289      return 0;
   1.290  }
   1.291  
   1.292 +void ptwr_init_backpointers(void)
   1.293 +{
   1.294 +    struct pfn_info *page;
   1.295 +    unsigned long pde, pfn;
   1.296 +    int va_idx;
   1.297 +
   1.298 +    for (va_idx = 0; va_idx < DOMAIN_ENTRIES_PER_L2_PAGETABLE; va_idx++) {
   1.299 +        /* check if entry valid */
   1.300 +        pde = l2_pgentry_val(linear_l2_table[va_idx]);
   1.301 +        if ((pde & _PAGE_PRESENT) == 0)
   1.302 +            continue;
   1.303 +        pfn = pde >> PAGE_SHIFT;
   1.304 +        page = &frame_table[pfn];
   1.305 +        /* assert that page is an l1_page_table   XXXcl maybe l2? */
   1.306 +        if ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) {
   1.307 +            BUG();
   1.308 +        }
   1.309 +        page->u.inuse.type_info &= ~PGT_va_mask;
   1.310 +        page->u.inuse.type_info |= va_idx << PGT_va_shift;
   1.311 +    }
   1.312 +}
   1.313 +
   1.314  #ifndef NDEBUG
   1.315  void ptwr_status(void)
   1.316  {
   1.317 @@ -1495,14 +1526,16 @@ void ptwr_status(void)
   1.318      int cpu = smp_processor_id();
   1.319  
   1.320      for (i = 0; i < ptwr_info[cpu].writable_idx; i++) {
   1.321 -        if (__get_user(pte, ptwr_info[cpu].writables[i]))
   1.322 +        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.323 +            [ptwr_info[cpu].writables[i]>>PAGE_SHIFT];
   1.324 +        if (__get_user(pte, writable_pte))
   1.325              BUG();
   1.326          pfn = pte >> PAGE_SHIFT;
   1.327          page = &frame_table[pfn];
   1.328          printk("need to alloc l1 page %p\n", page);
   1.329          /* make pt page writable */
   1.330          printk("need to make read-only l1-page at %p is %08lx\n",
   1.331 -               ptwr_info[cpu].writables[i], pte);
   1.332 +               writable_pte, pte);
   1.333      }
   1.334  
   1.335      if (ptwr_info[cpu].disconnected == ENTRIES_PER_L2_PAGETABLE)
   1.336 @@ -1518,11 +1551,11 @@ void ptwr_status(void)
   1.337      page = &frame_table[pfn];
   1.338  
   1.339      PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.340 -		 l2_pgentry_val(*pl2e),
   1.341 -		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.342 -						PAGE_SHIFT]) >> PAGE_SHIFT,
   1.343 -		 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.344 -		 frame_table[pfn].u.inuse.type_info,
   1.345 -		 frame_table[pfn].u.inuse.domain->domain));
   1.346 +                 l2_pgentry_val(*pl2e),
   1.347 +                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.348 +                                                PAGE_SHIFT]) >> PAGE_SHIFT,
   1.349 +                 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.350 +                 frame_table[pfn].u.inuse.type_info,
   1.351 +                 frame_table[pfn].u.inuse.domain->domain));
   1.352  }
   1.353  #endif
     2.1 --- a/xen/common/kernel.c	Wed Aug 11 07:33:29 2004 +0000
     2.2 +++ b/xen/common/kernel.c	Wed Aug 11 18:07:43 2004 +0000
     2.3 @@ -30,6 +30,8 @@ unsigned long xenheap_phys_end;
     2.4  
     2.5  xmem_cache_t *domain_struct_cachep;
     2.6  
     2.7 +vm_assist_info_t vm_assist_info[MAX_VMASST_TYPE + 1];
     2.8 +
     2.9  struct e820entry {
    2.10      unsigned long addr_lo, addr_hi;        /* start of memory segment */
    2.11      unsigned long size_lo, size_hi;        /* size of memory segment */
    2.12 @@ -353,16 +355,20 @@ long do_xen_version(int cmd)
    2.13  
    2.14  long do_vm_assist(unsigned int cmd, unsigned int type)
    2.15  {
    2.16 -    if ( type > (sizeof(unsigned long) * 8) )
    2.17 +    if ( type > MAX_VMASST_TYPE )
    2.18          return -EINVAL;
    2.19  
    2.20      switch ( cmd )
    2.21      {
    2.22      case VMASST_CMD_enable:
    2.23          set_bit(type, &current->vm_assist);
    2.24 +        if (vm_assist_info[type].enable)
    2.25 +            (*vm_assist_info[type].enable)();
    2.26          return 0;
    2.27      case VMASST_CMD_disable:
    2.28          clear_bit(type, &current->vm_assist);
    2.29 +        if (vm_assist_info[type].disable)
    2.30 +            (*vm_assist_info[type].disable)();
    2.31          return 0;
    2.32      }
    2.33  
     3.1 --- a/xen/common/memory.c	Wed Aug 11 07:33:29 2004 +0000
     3.2 +++ b/xen/common/memory.c	Wed Aug 11 18:07:43 2004 +0000
     3.3 @@ -37,13 +37,13 @@ struct pfn_info *frame_table;
     3.4  unsigned long frame_table_size;
     3.5  unsigned long max_page;
     3.6  
     3.7 -extern void init_percpu_info(void);
     3.8 +extern void arch_init_memory(void);
     3.9  
    3.10  void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
    3.11  {
    3.12      unsigned long mfn;
    3.13  
    3.14 -    init_percpu_info();
    3.15 +    arch_init_memory();
    3.16  
    3.17      max_page = nr_pages;
    3.18      frame_table_size = nr_pages * sizeof(struct pfn_info);
     4.1 --- a/xen/include/asm-x86/mm.h	Wed Aug 11 07:33:29 2004 +0000
     4.2 +++ b/xen/include/asm-x86/mm.h	Wed Aug 11 18:07:43 2004 +0000
     4.3 @@ -330,13 +330,20 @@ int memguard_is_guarded(void *p);
     4.4  #endif
     4.5  
     4.6  
     4.7 +typedef struct {
     4.8 +    void	(*enable)(void);
     4.9 +    void	(*disable)(void);
    4.10 +} vm_assist_info_t;
    4.11 +extern vm_assist_info_t vm_assist_info[];
    4.12 +
    4.13 +
    4.14  /* Writable Pagetables */
    4.15  #define	PTWR_NR_WRITABLES 1
    4.16  typedef struct {
    4.17      unsigned long disconnected;
    4.18      l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE];
    4.19 -    unsigned long *writable_l1;
    4.20 -    unsigned long *writables[PTWR_NR_WRITABLES];
    4.21 +    unsigned long writable_l1;
    4.22 +    unsigned long writables[PTWR_NR_WRITABLES];
    4.23      int writable_idx;
    4.24      l1_pgentry_t writable_page[PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE];
    4.25  #ifdef PTWR_TRACK_DOMAIN
     5.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Aug 11 07:33:29 2004 +0000
     5.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Aug 11 18:07:43 2004 +0000
     5.3 @@ -190,6 +190,7 @@
     5.4  #define VMASST_TYPE_4gb_segments         0
     5.5  #define VMASST_TYPE_4gb_segments_notify  1
     5.6  #define VMASST_TYPE_writeable_pagetables 2
     5.7 +#define MAX_VMASST_TYPE 2
     5.8  
     5.9  #ifndef __ASSEMBLY__
    5.10