ia64/xen-unstable

changeset 2458:d3c0c3c96dc0

bitkeeper revision 1.1159.1.137 (413f0665_0jsl7Ps44McAAquhcKOIQ)

Writable pagetables v2.
author cl349@freefall.cl.cam.ac.uk
date Wed Sep 08 13:17:25 2004 +0000 (2004-09-08)
parents 1ae6a24623a9
children 0aadba2b9bc3 9c7d7819508a
files xen/arch/x86/memory.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Wed Sep 08 09:49:46 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Wed Sep 08 13:17:25 2004 +0000
     1.3 @@ -144,6 +144,7 @@ static struct domain *dom_xen, *dom_io;
     1.4  void arch_init_memory(void)
     1.5  {
     1.6      unsigned long mfn;
     1.7 +    int i;
     1.8  
     1.9      /*
    1.10       * We are rather picky about the layout of 'struct pfn_info'. The
    1.11 @@ -164,9 +165,6 @@ void arch_init_memory(void)
    1.12  
    1.13      memset(percpu_info, 0, sizeof(percpu_info));
    1.14  
    1.15 -    vm_assist_info[VMASST_TYPE_writable_pagetables].enable = NULL;
    1.16 -    vm_assist_info[VMASST_TYPE_writable_pagetables].disable = NULL;
    1.17 -
    1.18      for ( mfn = 0; mfn < max_page; mfn++ )
    1.19          frame_table[mfn].count_info |= PGC_always_set;
    1.20  
    1.21 @@ -200,6 +198,15 @@ void arch_init_memory(void)
    1.22          frame_table[mfn].u.inuse.type_info  = PGT_gdt_page | 1; /* non-RW */
    1.23          frame_table[mfn].u.inuse.domain     = dom_xen;
    1.24      }
    1.25 +
    1.26 +    vm_assist_info[VMASST_TYPE_writable_pagetables].enable = NULL;
    1.27 +    vm_assist_info[VMASST_TYPE_writable_pagetables].disable = NULL;
    1.28 +
    1.29 +    for ( i = 0; i < smp_num_cpus; i++ )
    1.30 +    {
    1.31 +        ptwr_info[i].disconnected_page = (void *)alloc_xenheap_page();
    1.32 +        ptwr_info[i].writable_page = (void *)alloc_xenheap_page();
    1.33 +    }
    1.34  }
    1.35  
    1.36  static void __invalidate_shadow_ldt(struct domain *d)
    1.37 @@ -1487,22 +1494,28 @@ ptwr_info_t ptwr_info[NR_CPUS] =
    1.38      { [ 0 ... NR_CPUS-1 ] =
    1.39        {
    1.40            .disconnected_pteidx = -1,
    1.41 +          .disconnected_page = 0,
    1.42            .writable_l1va = 0,
    1.43 +          .writable_page = 0,
    1.44        }
    1.45      };
    1.46  
    1.47  #ifdef VERBOSE
    1.48 -int ptwr_debug = 0;
    1.49 -#define PTWR_PRINTK(x) if (ptwr_debug) printk x
    1.50 +int ptwr_debug = 0x0;
    1.51 +#define PTWR_PRINTK(w, x) if (ptwr_debug & (w)) printk x
    1.52 +#define PP_ALL 0xff
    1.53 +#define PP_A 0x1
    1.54 +#define PP_I 0x2
    1.55  #else
    1.56 -#define PTWR_PRINTK(x)
    1.57 +#define PTWR_PRINTK(w, x)
    1.58  #endif
    1.59  
    1.60  void ptwr_reconnect_disconnected(void)
    1.61  {
    1.62      unsigned long pte;
    1.63 +#ifdef VERBOSE
    1.64      unsigned long pfn;
    1.65 -    struct pfn_info *page;
    1.66 +#endif
    1.67      l2_pgentry_t *pl2e, nl2e;
    1.68      l1_pgentry_t *pl1e;
    1.69      int cpu = smp_processor_id();
    1.70 @@ -1510,38 +1523,35 @@ void ptwr_reconnect_disconnected(void)
    1.71      unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.72          [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT];
    1.73  
    1.74 -    PTWR_PRINTK(("[A] page fault in disconn space %08lx\n",
    1.75 -                 ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT));
    1.76 +    PTWR_PRINTK(PP_A, ("[A] page fault in disconn space %08lx\n",
    1.77 +                       ptwr_info[cpu].disconnected_pteidx <<
    1.78 +                       L2_PAGETABLE_SHIFT));
    1.79      pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx];
    1.80  
    1.81 -    if (__get_user(pte, writable_pte)) {
    1.82 -        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.83 -        domain_crash();
    1.84 -    }
    1.85 -    pfn = pte >> PAGE_SHIFT;
    1.86 -    page = &frame_table[pfn];
    1.87 -
    1.88 -    /* reconnect l1 page */
    1.89 -    PTWR_PRINTK(("[A]     pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n",
    1.90 -                 pl2e, l2_pgentry_val(*pl2e),
    1.91 -                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
    1.92 -                                                PAGE_SHIFT]) >> PAGE_SHIFT,
    1.93 -                 frame_table[pfn].u.inuse.type_info,
    1.94 -                 frame_table[pfn].count_info,
    1.95 -                 frame_table[pfn].u.inuse.domain->domain));
    1.96 +#ifdef VERBOSE
    1.97 +    pfn = ptwr_info[cpu].disconnected_pte >> PAGE_SHIFT;
    1.98 +#endif
    1.99 +    PTWR_PRINTK(PP_A, ("[A]     pl2e %p l2e %08lx pfn %08lx taf %08x/%08x\n",
   1.100 +                       pl2e, l2_pgentry_val(*pl2e), l1_pgentry_val(
   1.101 +                           linear_pg_table[(unsigned long)pl2e >>
   1.102 +                                           PAGE_SHIFT]) >> PAGE_SHIFT,
   1.103 +                       frame_table[pfn].u.inuse.type_info,
   1.104 +                       frame_table[pfn].count_info));
   1.105  
   1.106      nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
   1.107 -    pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
   1.108 +    pl1e = ptwr_info[cpu].disconnected_pl1e;
   1.109      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.110          l1_pgentry_t ol1e, nl1e;
   1.111 -        ol1e = ptwr_info[cpu].disconnected_page[i];
   1.112 -        nl1e = pl1e[i];
   1.113 +        nl1e = ptwr_info[cpu].disconnected_page[i];
   1.114 +        ol1e = pl1e[i];
   1.115          if (likely(l1_pgentry_val(nl1e) == l1_pgentry_val(ol1e)))
   1.116              continue;
   1.117          if (likely(l1_pgentry_val(nl1e) == (l1_pgentry_val(ol1e) | _PAGE_RW)))
   1.118          {
   1.119 -            if (likely(readonly_page_from_l1e(nl1e)))
   1.120 +            if (likely(readonly_page_from_l1e(nl1e))) {
   1.121 +                pl1e[i] = ptwr_info[cpu].disconnected_page[i];
   1.122                  continue;
   1.123 +            }
   1.124          }
   1.125          if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
   1.126              put_page_from_l1e(ol1e, current);
   1.127 @@ -1549,58 +1559,52 @@ void ptwr_reconnect_disconnected(void)
   1.128              MEM_LOG("ptwr: Could not re-validate l1 page\n");
   1.129              domain_crash();
   1.130          }
   1.131 +        pl1e[i] = ptwr_info[cpu].disconnected_page[i];
   1.132      }
   1.133      unmap_domain_mem(pl1e);
   1.134 +    /* reconnect l1 page */
   1.135      update_l2e(pl2e, *pl2e, nl2e);
   1.136  
   1.137 -    PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              taf %08x/%08x/%u\n",
   1.138 +    PTWR_PRINTK(PP_A,
   1.139 +                ("[A] now pl2e %p l2e %08lx              taf %08x/%08x\n",
   1.140                   pl2e, l2_pgentry_val(*pl2e),
   1.141                   frame_table[pfn].u.inuse.type_info,
   1.142 -                 frame_table[pfn].count_info,
   1.143 -                 frame_table[pfn].u.inuse.domain->domain));
   1.144 +                 frame_table[pfn].count_info));
   1.145      ptwr_info[cpu].disconnected_pteidx = -1;
   1.146 +
   1.147      /* make pt page write protected */
   1.148      if (__get_user(pte, writable_pte)) {
   1.149          MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.150          domain_crash();
   1.151      }
   1.152 -    PTWR_PRINTK(("[A] disconnected_l1va at %p is %08lx\n",
   1.153 -                 writable_pte, pte));
   1.154 -    pte &= ~_PAGE_RW;
   1.155 +    PTWR_PRINTK(PP_A, ("[A] disconnected_l1va at %p is %08lx\n",
   1.156 +                       writable_pte, pte));
   1.157 +    pte = (ptwr_info[cpu].disconnected_pte & PAGE_MASK) |
   1.158 +        (pte & ~(PAGE_MASK|_PAGE_RW));
   1.159      if (__put_user(pte, writable_pte)) {
   1.160          MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.161          domain_crash();
   1.162      }
   1.163      __flush_tlb_one(ptwr_info[cpu].disconnected_l1va);
   1.164 -    PTWR_PRINTK(("[A] disconnected_l1va at %p now %08lx\n",
   1.165 -                 writable_pte, pte));
   1.166 -    /* and try again */
   1.167 -    return;
   1.168 +    PTWR_PRINTK(PP_A, ("[A] disconnected_l1va at %p now %08lx\n",
   1.169 +                       writable_pte, pte));
   1.170 +
   1.171  }
   1.172  
   1.173  void ptwr_flush_inactive(void)
   1.174  {
   1.175 -    unsigned long pte, pfn;
   1.176 -    struct pfn_info *page;
   1.177 +    unsigned long pte;
   1.178      l1_pgentry_t *pl1e;
   1.179      int cpu = smp_processor_id();
   1.180      int i;
   1.181 -
   1.182      unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.183          [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT];
   1.184 -    if (__get_user(pte, writable_pte)) {
   1.185 -        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.186 -        domain_crash();
   1.187 -    }
   1.188 -    pfn = pte >> PAGE_SHIFT;
   1.189 -    page = &frame_table[pfn];
   1.190 -    PTWR_PRINTK(("[I] alloc l1 page %p\n", page));
   1.191  
   1.192 -    pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.193 +    pl1e = ptwr_info[cpu].writable_pl1e;
   1.194      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.195          l1_pgentry_t ol1e, nl1e;
   1.196 -        ol1e = ptwr_info[cpu].writable_page[i];
   1.197 -        nl1e = pl1e[i];
   1.198 +        nl1e = ptwr_info[cpu].writable_page[i];
   1.199 +        ol1e = pl1e[i];
   1.200          if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
   1.201              continue;
   1.202          if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
   1.203 @@ -1609,20 +1613,26 @@ void ptwr_flush_inactive(void)
   1.204              MEM_LOG("ptwr: Could not re-validate l1 page\n");
   1.205              domain_crash();
   1.206          }
   1.207 +        pl1e[i] = ptwr_info[cpu].writable_page[i];
   1.208      }
   1.209      unmap_domain_mem(pl1e);
   1.210  
   1.211      /* make pt page writable */
   1.212 -    PTWR_PRINTK(("[I] disconnected_l1va at %p is %08lx\n",
   1.213 -                 writable_pte, pte));
   1.214 -    pte &= ~_PAGE_RW;
   1.215 +    if (__get_user(pte, writable_pte)) {
   1.216 +        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.217 +        domain_crash();
   1.218 +    }
   1.219 +    PTWR_PRINTK(PP_I, ("[I] disconnected_l1va at %p is %08lx\n",
   1.220 +                       writable_pte, pte));
   1.221 +    pte = (ptwr_info[cpu].writable_pte & PAGE_MASK) |
   1.222 +        (pte & ~(PAGE_MASK|_PAGE_RW));
   1.223      if (__put_user(pte, writable_pte)) {
   1.224          MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.225          domain_crash();
   1.226      }
   1.227      __flush_tlb_one(ptwr_info[cpu].writable_l1va);
   1.228 -    PTWR_PRINTK(("[I] disconnected_l1va at %p now %08lx\n",
   1.229 -                 writable_pte, pte));
   1.230 +    PTWR_PRINTK(PP_I, ("[I] disconnected_l1va at %p now %08lx\n",
   1.231 +                       writable_pte, pte));
   1.232  
   1.233      ptwr_info[cpu].writable_l1va = 0;
   1.234  }
   1.235 @@ -1636,8 +1646,8 @@ int ptwr_do_page_fault(unsigned long add
   1.236      int cpu = smp_processor_id();
   1.237  
   1.238  #if 0
   1.239 -    PTWR_PRINTK(("get user %p for va %08lx\n",
   1.240 -                 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   1.241 +    PTWR_PRINTK(PP_ALL, ("get user %p for va %08lx\n",
   1.242 +                         &linear_pg_table[addr>>PAGE_SHIFT], addr));
   1.243  #endif
   1.244  
   1.245      /* Testing for page_present in the L2 avoids lots of unncessary fixups */
   1.246 @@ -1648,72 +1658,80 @@ int ptwr_do_page_fault(unsigned long add
   1.247      {
   1.248          pfn = pte >> PAGE_SHIFT;
   1.249  #if 0
   1.250 -        PTWR_PRINTK(("check pte %08lx = pfn %08lx for va %08lx\n", pte, pfn,
   1.251 -                     addr));
   1.252 +        PTWR_PRINTK(PP_ALL, ("check pte %08lx = pfn %08lx for va %08lx\n", pte,
   1.253 +                             pfn, addr));
   1.254  #endif
   1.255          page = &frame_table[pfn];
   1.256          if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table )
   1.257          {
   1.258              pl2e = &linear_l2_table[(page->u.inuse.type_info &
   1.259                                       PGT_va_mask) >> PGT_va_shift];
   1.260 -            PTWR_PRINTK(("page_fault on l1 pt at va %08lx, pt for %08x, "
   1.261 -                         "pfn %08lx\n", addr,
   1.262 -                         ((page->u.inuse.type_info & PGT_va_mask) >>
   1.263 -                          PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   1.264 +            PTWR_PRINTK(PP_ALL, ("page_fault on l1 pt at va %08lx, pt for %08x"
   1.265 +                                 ", pfn %08lx\n", addr,
   1.266 +                                 ((page->u.inuse.type_info & PGT_va_mask) >>
   1.267 +                                  PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   1.268  
   1.269              if ( l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn )
   1.270              {
   1.271                  /* this L1 is not in the current address space */
   1.272 -                l1_pgentry_t *pl1e;
   1.273 -                PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page,
   1.274 -                             page->u.inuse.type_info,
   1.275 -                             page->count_info));
   1.276 +                PTWR_PRINTK(PP_I, ("[I] freeing l1 page %p taf %08x/%08x\n",
   1.277 +                                   page, page->u.inuse.type_info,
   1.278 +                                   page->count_info));
   1.279                  if (ptwr_info[cpu].writable_l1va)
   1.280                      ptwr_flush_inactive();
   1.281                  ptwr_info[cpu].writable_l1va = addr | 1;
   1.282  
   1.283 -                pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.284 -                memcpy(&ptwr_info[cpu].writable_page[0],
   1.285 -                       pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.286 -                unmap_domain_mem(pl1e);
   1.287 +                ptwr_info[cpu].writable_pl1e =
   1.288 +                    map_domain_mem(pfn << PAGE_SHIFT);
   1.289 +                memcpy(ptwr_info[cpu].writable_page,
   1.290 +                       ptwr_info[cpu].writable_pl1e,
   1.291 +                       ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.292 +
   1.293 +                /* make pt page writable */
   1.294 +                ptwr_info[cpu].writable_pte = pte;
   1.295 +                pte = (virt_to_phys(ptwr_info[cpu].writable_page) &
   1.296 +                       PAGE_MASK) | _PAGE_RW | (pte & ~PAGE_MASK);
   1.297              }
   1.298              else
   1.299              {
   1.300                  l2_pgentry_t nl2e;
   1.301 -                l1_pgentry_t *pl1e;
   1.302 +
   1.303                  if ( ptwr_info[cpu].disconnected_pteidx >= 0 )
   1.304                      ptwr_reconnect_disconnected();
   1.305 -                PTWR_PRINTK(("[A]    pl2e %p l2e %08lx pfn %08lx "
   1.306 -                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.307 -                             l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.308 -                                                            >> PAGE_SHIFT]) >>
   1.309 -                             PAGE_SHIFT,
   1.310 -                             frame_table[pfn].u.inuse.type_info,
   1.311 -                             frame_table[pfn].count_info,
   1.312 -                             frame_table[pfn].u.inuse.domain->domain));
   1.313 +                PTWR_PRINTK(PP_A, ("[A]    pl2e %p l2e %08lx pfn %08lx "
   1.314 +                                   "taf %08x/%08x\n", pl2e,
   1.315 +                                   l2_pgentry_val(*pl2e),
   1.316 +                                   l1_pgentry_val(linear_pg_table
   1.317 +                                                  [(unsigned long)pl2e >>
   1.318 +                                                   PAGE_SHIFT]) >> PAGE_SHIFT,
   1.319 +                                   frame_table[pfn].u.inuse.type_info,
   1.320 +                                   frame_table[pfn].count_info));
   1.321                  /* disconnect l1 page */
   1.322                  nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
   1.323                  update_l2e(pl2e, *pl2e, nl2e);
   1.324  
   1.325                  ptwr_info[cpu].disconnected_pteidx =
   1.326                      (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   1.327 -                PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              "
   1.328 -                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.329 -                             frame_table[pfn].u.inuse.type_info,
   1.330 -                             frame_table[pfn].count_info,
   1.331 -                             frame_table[pfn].u.inuse.domain->domain));
   1.332 +                PTWR_PRINTK(PP_A, ("[A] now pl2e %p l2e %08lx              "
   1.333 +                                   "taf %08x/%08x\n", pl2e,
   1.334 +                                   l2_pgentry_val(*pl2e),
   1.335 +                                   frame_table[pfn].u.inuse.type_info,
   1.336 +                                   frame_table[pfn].count_info));
   1.337                  ptwr_info[cpu].disconnected_l1va = addr;
   1.338 -                pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) <<
   1.339 -                                      PAGE_SHIFT);
   1.340 -                memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e,
   1.341 +                ptwr_info[cpu].disconnected_pl1e =
   1.342 +                    map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
   1.343 +                memcpy(&ptwr_info[cpu].disconnected_page[0],
   1.344 +                       ptwr_info[cpu].disconnected_pl1e,
   1.345                         ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.346 -                unmap_domain_mem(pl1e);
   1.347 +
   1.348 +                /* make pt page writable */
   1.349 +                ptwr_info[cpu].disconnected_pte = pte;
   1.350 +                pte = (virt_to_phys(ptwr_info[cpu].disconnected_page) &
   1.351 +                       PAGE_MASK) | _PAGE_RW | (pte & ~PAGE_MASK);
   1.352              }
   1.353  
   1.354 -            /* make pt page writable */
   1.355 -            pte |= _PAGE_RW;
   1.356 -            PTWR_PRINTK(("update %p pte to %08lx\n",
   1.357 -                         &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.358 +            PTWR_PRINTK(PP_ALL, ("update %p pte to %08lx\n",
   1.359 +                                 &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.360              if ( __put_user(pte, (unsigned long *)
   1.361                              &linear_pg_table[addr>>PAGE_SHIFT]) ) {
   1.362                  MEM_LOG("ptwr: Could not update pte at %p\n", (unsigned long *)
   1.363 @@ -1765,13 +1783,14 @@ void ptwr_status(void)
   1.364      pfn = pte >> PAGE_SHIFT;
   1.365      page = &frame_table[pfn];
   1.366  
   1.367 -    PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.368 -                 l2_pgentry_val(*pl2e),
   1.369 -                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.370 -                                                PAGE_SHIFT]) >> PAGE_SHIFT,
   1.371 -                 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.372 -                 frame_table[pfn].u.inuse.type_info,
   1.373 -                 frame_table[pfn].u.inuse.domain->domain));
   1.374 +    PTWR_PRINTK(PP_ALL, ("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x\n",
   1.375 +                         pl2e, l2_pgentry_val(*pl2e), l1_pgentry_val(
   1.376 +                             linear_pg_table[(unsigned long)pl2e >>
   1.377 +                                             PAGE_SHIFT]) >> PAGE_SHIFT,
   1.378 +                         frame_table[
   1.379 +                             l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.380 +                         frame_table[pfn].u.inuse.type_info,
   1.381 +                         frame_table[pfn].u.inuse.domain->domain));
   1.382  }
   1.383  
   1.384  
     2.1 --- a/xen/include/asm-x86/mm.h	Wed Sep 08 09:49:46 2004 +0000
     2.2 +++ b/xen/include/asm-x86/mm.h	Wed Sep 08 13:17:25 2004 +0000
     2.3 @@ -371,11 +371,15 @@ extern vm_assist_info_t vm_assist_info[]
     2.4  
     2.5  /* Writable Pagetables */
     2.6  typedef struct {
     2.7 +    unsigned long disconnected_l1va;
     2.8 +    l1_pgentry_t *disconnected_page;
     2.9      long disconnected_pteidx;
    2.10 -    l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE];
    2.11 -    unsigned long disconnected_l1va;
    2.12 +    unsigned long disconnected_pte;
    2.13 +    l1_pgentry_t *disconnected_pl1e;
    2.14      unsigned long writable_l1va;
    2.15 -    l1_pgentry_t writable_page[ENTRIES_PER_L1_PAGETABLE];
    2.16 +    l1_pgentry_t *writable_page;
    2.17 +    unsigned long writable_pte;
    2.18 +    l1_pgentry_t *writable_pl1e;
    2.19  } __cacheline_aligned ptwr_info_t;
    2.20  
    2.21  extern ptwr_info_t ptwr_info[];