ia64/xen-unstable

changeset 2055:5dc17e68374c

bitkeeper revision 1.1131 (410f9b4eILziuHga5Sd_VLggMEwKrQ)

Move all the ptwr bookkeeping info into a per-cpu structure.
author cl349@freefall.cl.cam.ac.uk
date Tue Aug 03 14:03:58 2004 +0000 (2004-08-03)
parents 689f558de2f2
children bd7b8d136aba f5ce0f8cd1b0
files xen/arch/x86/memory.c xen/arch/x86/traps.c xen/common/schedule.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Tue Aug 03 13:37:05 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Tue Aug 03 14:03:58 2004 +0000
     1.3 @@ -2,6 +2,7 @@
     1.4   * arch/x86/memory.c
     1.5   * 
     1.6   * Copyright (c) 2002-2004 K A Fraser
     1.7 + * Copyright (c) 2004 Christian Limpach
     1.8   * 
     1.9   * This program is free software; you can redistribute it and/or modify
    1.10   * it under the terms of the GNU General Public License as published by
    1.11 @@ -711,7 +712,7 @@ static int do_extended_command(unsigned 
    1.12      u32 x, y;
    1.13      domid_t domid;
    1.14  
    1.15 -    cleanup_writable_pagetable(PTRW_CLEANUP_ACTIVE | PTRW_CLEANUP_INACTIVE);
    1.16 +    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    1.17  
    1.18      switch ( cmd )
    1.19      {
    1.20 @@ -962,7 +963,7 @@ int do_mmu_update(mmu_update_t *ureqs, i
    1.21      perfc_incrc(calls_to_mmu_update); 
    1.22      perfc_addc(num_page_updates, count);
    1.23  
    1.24 -    cleanup_writable_pagetable(PTRW_CLEANUP_ACTIVE | PTRW_CLEANUP_INACTIVE);
    1.25 +    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    1.26  
    1.27      for ( i = 0; i < count; i++ )
    1.28      {
    1.29 @@ -1140,7 +1141,7 @@ int do_update_va_mapping(unsigned long p
    1.30      if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) )
    1.31          return -EINVAL;
    1.32  
    1.33 -    cleanup_writable_pagetable(PTRW_CLEANUP_ACTIVE | PTRW_CLEANUP_INACTIVE);
    1.34 +    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    1.35  
    1.36      /*
    1.37       * XXX When we make this support 4MB superpages we should also deal with 
    1.38 @@ -1205,7 +1206,7 @@ int do_update_va_mapping_otherdomain(uns
    1.39      if ( unlikely(!IS_PRIV(current)) )
    1.40          return -EPERM;
    1.41  
    1.42 -    cleanup_writable_pagetable(PTRW_CLEANUP_ACTIVE | PTRW_CLEANUP_INACTIVE);
    1.43 +    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    1.44  
    1.45      percpu_info[cpu].gps = d = find_domain_by_id(domid);
    1.46      if ( unlikely(d == NULL) )
    1.47 @@ -1235,21 +1236,26 @@ static inline int readonly_page_from_l1e
    1.48      return 1;
    1.49  }
    1.50  
    1.51 -/*  */
    1.52 -unsigned long ptwr_disconnected[NR_CPUS] __cacheline_aligned =
    1.53 -	{ [ 0 ... NR_CPUS-1 ] = ENTRIES_PER_L2_PAGETABLE };
    1.54 -static l1_pgentry_t ptwr_disconnected_page[NR_CPUS][ENTRIES_PER_L1_PAGETABLE] __cacheline_aligned;
    1.55 -static unsigned long *ptwr_writable_l1[NR_CPUS] __cacheline_aligned;
    1.56 -#define	PTWR_NR_WRITABLES 4
    1.57 -static unsigned long *ptwr_writables[NR_CPUS][PTWR_NR_WRITABLES] __cacheline_aligned;
    1.58 -int ptwr_writable_idx[NR_CPUS] __cacheline_aligned = { 0, };
    1.59 -static l1_pgentry_t ptwr_writable_page[NR_CPUS][PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE] __cacheline_aligned;
    1.60 +
    1.61 +/* Writable Pagetables */
    1.62 +
    1.63 +ptwr_info_t ptwr_info[NR_CPUS] =
    1.64 +    { [ 0 ... NR_CPUS-1 ] =
    1.65 +      {
    1.66 +	  .disconnected = ENTRIES_PER_L2_PAGETABLE,
    1.67 +	  .writable_idx = 0,
    1.68  #ifdef PTWR_TRACK_DOMAIN
    1.69 -domid_t ptwr_domain[NR_CPUS] = { 0, };
    1.70 +	  .domain = 0,
    1.71  #endif
    1.72 +      }
    1.73 +    };
    1.74  
    1.75 +#ifndef NDEBUG
    1.76  int ptwr_debug = 0;
    1.77 -#define PTWR_PRINTK if (ptwr_debug) printk
    1.78 +#define PTWR_PRINTK(x) if (ptwr_debug) printk x
    1.79 +#else
    1.80 +#define PTWR_PRINTK(x)
    1.81 +#endif
    1.82  
    1.83  void ptwr_reconnect_disconnected(unsigned long addr)
    1.84  {
    1.85 @@ -1266,30 +1272,30 @@ void ptwr_reconnect_disconnected(unsigne
    1.86          printk("ptwr_reconnect_disconnected domain mismatch %d != %d\n",
    1.87                 ptwr_domain[cpu], get_current()->domain);
    1.88  #endif
    1.89 -    PTWR_PRINTK("page fault in disconnected space: addr %08lx space %08lx\n",
    1.90 -                addr, ptwr_disconnected[cpu] << L2_PAGETABLE_SHIFT);
    1.91 -    pl2e = &linear_l2_table[ptwr_disconnected[cpu]];
    1.92 +    PTWR_PRINTK(("page fault in disconnected space: addr %08lx space %08lx\n",
    1.93 +		 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    1.94 +    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
    1.95  
    1.96 -    if (__get_user(pte, ptwr_writable_l1[cpu]))
    1.97 +    if (__get_user(pte, ptwr_info[cpu].writable_l1))
    1.98          BUG();
    1.99      pfn = pte >> PAGE_SHIFT;
   1.100      page = &frame_table[pfn];
   1.101  
   1.102      /* reconnect l1 page */
   1.103 -    PTWR_PRINTK("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.104 -                l2_pgentry_val(*pl2e),
   1.105 -                l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.106 -                                               PAGE_SHIFT]) >> PAGE_SHIFT,
   1.107 -                frame_table[pfn].u.inuse.type_info,
   1.108 -                frame_table[pfn].u.inuse.count_info,
   1.109 -                frame_table[pfn].u.inuse.domain->domain);
   1.110 +    PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.111 +		 l2_pgentry_val(*pl2e),
   1.112 +		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.113 +						PAGE_SHIFT]) >> PAGE_SHIFT,
   1.114 +		 frame_table[pfn].u.inuse.type_info,
   1.115 +		 frame_table[pfn].u.inuse.count_info,
   1.116 +		 frame_table[pfn].u.inuse.domain->domain));
   1.117  
   1.118      nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~0x800) |
   1.119                           _PAGE_PRESENT);
   1.120      pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
   1.121      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.122          l1_pgentry_t ol1e, nl1e;
   1.123 -        ol1e = ptwr_disconnected_page[cpu][i];
   1.124 +        ol1e = ptwr_info[cpu].disconnected_page[i];
   1.125          nl1e = pl1e[i];
   1.126          if (likely(l1_pgentry_val(nl1e) == l1_pgentry_val(ol1e)))
   1.127              continue;
   1.128 @@ -1306,20 +1312,22 @@ void ptwr_reconnect_disconnected(unsigne
   1.129      unmap_domain_mem(pl1e);
   1.130      update_l2e(pl2e, *pl2e, nl2e);
   1.131  
   1.132 -    PTWR_PRINTK("now pl2e %p l2e %08lx              taf %08x/%08x/%u\n", pl2e,
   1.133 -                l2_pgentry_val(*pl2e),
   1.134 -                frame_table[pfn].u.inuse.type_info,
   1.135 -                frame_table[pfn].u.inuse.count_info,
   1.136 -                frame_table[pfn].u.inuse.domain->domain);
   1.137 -    ptwr_disconnected[cpu] = ENTRIES_PER_L2_PAGETABLE;
   1.138 +    PTWR_PRINTK(("now pl2e %p l2e %08lx              taf %08x/%08x/%u\n", pl2e,
   1.139 +		 l2_pgentry_val(*pl2e),
   1.140 +		 frame_table[pfn].u.inuse.type_info,
   1.141 +		 frame_table[pfn].u.inuse.count_info,
   1.142 +		 frame_table[pfn].u.inuse.domain->domain));
   1.143 +    ptwr_info[cpu].disconnected = ENTRIES_PER_L2_PAGETABLE;
   1.144      /* make pt page write protected */
   1.145 -    if (__get_user(pte, ptwr_writable_l1[cpu]))
   1.146 +    if (__get_user(pte, ptwr_info[cpu].writable_l1))
   1.147          BUG();
   1.148 -    PTWR_PRINTK("writable_l1 at %p is %08lx\n", ptwr_writable_l1[cpu], pte);
   1.149 +    PTWR_PRINTK(("writable_l1 at %p is %08lx\n", ptwr_info[cpu].writable_l1,
   1.150 +		 pte));
   1.151      pte &= ~_PAGE_RW;
   1.152 -    if (__put_user(pte, ptwr_writable_l1[cpu]))
   1.153 +    if (__put_user(pte, ptwr_info[cpu].writable_l1))
   1.154          BUG();
   1.155 -    PTWR_PRINTK("writable_l1 at %p now %08lx\n", ptwr_writable_l1[cpu], pte);
   1.156 +    PTWR_PRINTK(("writable_l1 at %p now %08lx\n", ptwr_info[cpu].writable_l1,
   1.157 +		 pte));
   1.158      /* and try again */
   1.159      return;
   1.160  }
   1.161 @@ -1331,28 +1339,32 @@ void ptwr_flush_inactive(void)
   1.162      l1_pgentry_t *pl1e;
   1.163      int cpu = smp_processor_id();
   1.164      int i, idx;
   1.165 -    static int maxidx = 0;
   1.166  
   1.167  #ifdef PTWR_TRACK_DOMAIN
   1.168 -    if (ptwr_domain[cpu] != get_current()->domain)
   1.169 +    if (ptwr_info[cpu].domain != get_current()->domain)
   1.170          printk("ptwr_flush_inactive domain mismatch %d != %d\n",
   1.171 -               ptwr_domain[cpu], get_current()->domain);
   1.172 +               ptwr_info[cpu].domain, get_current()->domain);
   1.173  #endif
   1.174 -    if (ptwr_writable_idx[cpu] > maxidx) {
   1.175 -        maxidx = ptwr_writable_idx[cpu];
   1.176 -        printk("maxidx on cpu %d now %d\n", cpu, maxidx);
   1.177 +#if 0
   1.178 +    {
   1.179 +	static int maxidx = 0;
   1.180 +	if (ptwr_info[cpu].writable_idx > maxidx) {
   1.181 +	    maxidx = ptwr_info[cpu].writable_idx;
   1.182 +	    printk("maxidx on cpu %d now %d\n", cpu, maxidx);
   1.183 +	}
   1.184      }
   1.185 -    for (idx = 0; idx < ptwr_writable_idx[cpu]; idx++) {
   1.186 -        if (__get_user(pte, ptwr_writables[cpu][idx]))
   1.187 +#endif
   1.188 +    for (idx = 0; idx < ptwr_info[cpu].writable_idx; idx++) {
   1.189 +        if (__get_user(pte, ptwr_info[cpu].writables[idx]))
   1.190              BUG();
   1.191          pfn = pte >> PAGE_SHIFT;
   1.192          page = &frame_table[pfn];
   1.193 -        PTWR_PRINTK("alloc l1 page %p\n", page);
   1.194 +        PTWR_PRINTK(("alloc l1 page %p\n", page));
   1.195  
   1.196          pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.197          for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.198              l1_pgentry_t ol1e, nl1e;
   1.199 -            ol1e = ptwr_writable_page[cpu][idx][i];
   1.200 +            ol1e = ptwr_info[cpu].writable_page[idx][i];
   1.201              nl1e = pl1e[i];
   1.202              if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
   1.203                  continue;
   1.204 @@ -1364,15 +1376,15 @@ void ptwr_flush_inactive(void)
   1.205          unmap_domain_mem(pl1e);
   1.206  
   1.207          /* make pt page writable */
   1.208 -        PTWR_PRINTK("writable_l1 at %p is %08lx\n", ptwr_writables[cpu][idx],
   1.209 -                    pte);
   1.210 +        PTWR_PRINTK(("writable_l1 at %p is %08lx\n",
   1.211 +		     ptwr_info[cpu].writables[idx], pte));
   1.212          pte &= ~_PAGE_RW;
   1.213 -        if (__put_user(pte, ptwr_writables[cpu][idx]))
   1.214 +        if (__put_user(pte, ptwr_info[cpu].writables[idx]))
   1.215              BUG();
   1.216 -        PTWR_PRINTK("writable_l1 at %p now %08lx\n", ptwr_writables[cpu][idx],
   1.217 -                    pte);
   1.218 +        PTWR_PRINTK(("writable_l1 at %p now %08lx\n",
   1.219 +		     ptwr_info[cpu].writables[idx], pte));
   1.220      }
   1.221 -    ptwr_writable_idx[cpu] = 0;
   1.222 +    ptwr_info[cpu].writable_idx = 0;
   1.223  }
   1.224  
   1.225  int ptwr_do_page_fault(unsigned long addr)
   1.226 @@ -1385,8 +1397,8 @@ int ptwr_do_page_fault(unsigned long add
   1.227      int cpu = smp_processor_id();
   1.228  
   1.229  #if 0
   1.230 -    PTWR_PRINTK("get user %p for va %08lx\n",
   1.231 -                &linear_pg_table[addr>>PAGE_SHIFT], addr);
   1.232 +    PTWR_PRINTK(("get user %p for va %08lx\n",
   1.233 +		 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   1.234  #endif
   1.235      if (l2_pgentry_val(linear_l2_table[addr >> L2_PAGETABLE_SHIFT]) &
   1.236          _PAGE_PRESENT &&
   1.237 @@ -1394,74 +1406,76 @@ int ptwr_do_page_fault(unsigned long add
   1.238                     &linear_pg_table[addr >> PAGE_SHIFT]) == 0) {
   1.239          pfn = pte >> PAGE_SHIFT;
   1.240  #if 0
   1.241 -        PTWR_PRINTK("check pte %08lx = pfn %08lx for va %08lx\n", pte, pfn,
   1.242 -                    addr);
   1.243 +        PTWR_PRINTK(("check pte %08lx = pfn %08lx for va %08lx\n", pte, pfn,
   1.244 +		     addr));
   1.245  #endif
   1.246          page = &frame_table[pfn];
   1.247          if ((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table) {
   1.248  #ifdef PTWR_TRACK_DOMAIN
   1.249 -            if (ptwr_domain[cpu] != get_current()->domain)
   1.250 +            if (ptwr_info[cpu].domain != get_current()->domain)
   1.251                  printk("ptwr_do_page_fault domain mismatch %d != %d\n",
   1.252 -                       ptwr_domain[cpu], get_current()->domain);
   1.253 +                       ptwr_info[cpu].domain, get_current()->domain);
   1.254  #endif
   1.255              pl2e = &linear_l2_table[(page->u.inuse.type_info &
   1.256                                       PGT_va_mask) >> PGT_va_shift];
   1.257 -            PTWR_PRINTK("page_fault on l1 pt at va %08lx, pt for %08x, "
   1.258 -			"pfn %08lx\n", addr,
   1.259 -			((page->u.inuse.type_info & PGT_va_mask) >>
   1.260 -			 PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn);
   1.261 +            PTWR_PRINTK(("page_fault on l1 pt at va %08lx, pt for %08x, "
   1.262 +			 "pfn %08lx\n", addr,
   1.263 +			 ((page->u.inuse.type_info & PGT_va_mask) >>
   1.264 +			  PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   1.265              if (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) {
   1.266                  l1_pgentry_t *pl1e;
   1.267 -                PTWR_PRINTK("freeing l1 page %p taf %08x/%08x\n", page,
   1.268 -                            page->u.inuse.type_info, page->u.inuse.count_info);
   1.269 -                if (ptwr_writable_idx[cpu] == PTWR_NR_WRITABLES)
   1.270 +                PTWR_PRINTK(("freeing l1 page %p taf %08x/%08x\n", page,
   1.271 +			     page->u.inuse.type_info,
   1.272 +			     page->u.inuse.count_info));
   1.273 +                if (ptwr_info[cpu].writable_idx == PTWR_NR_WRITABLES)
   1.274                      ptwr_flush_inactive();
   1.275 -                ptwr_writables[cpu][ptwr_writable_idx[cpu]] = (unsigned long *)
   1.276 -                    &linear_pg_table[addr>>PAGE_SHIFT];
   1.277 +                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] =
   1.278 +		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   1.279  
   1.280                  pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.281 -                memcpy(&ptwr_writable_page[cpu][ptwr_writable_idx[cpu]][0],
   1.282 +                memcpy(&ptwr_info[cpu].writable_page[
   1.283 +			   ptwr_info[cpu].writable_idx][0],
   1.284                         pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.285                  unmap_domain_mem(pl1e);
   1.286  
   1.287 -                ptwr_writable_idx[cpu]++;
   1.288 +                ptwr_info[cpu].writable_idx++;
   1.289              } else {
   1.290                  l2_pgentry_t nl2e;
   1.291                  l1_pgentry_t *pl1e;
   1.292 -                if (ptwr_disconnected[cpu] != ENTRIES_PER_L2_PAGETABLE)
   1.293 +                if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE)
   1.294                      ptwr_reconnect_disconnected(addr);
   1.295 -                PTWR_PRINTK("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n",
   1.296 -                            pl2e, l2_pgentry_val(*pl2e),
   1.297 -                            l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.298 -                                                           >> PAGE_SHIFT]) >>
   1.299 -                            PAGE_SHIFT,
   1.300 -                            frame_table[pfn].u.inuse.type_info,
   1.301 -                            frame_table[pfn].u.inuse.count_info,
   1.302 -                            frame_table[pfn].u.inuse.domain->domain);
   1.303 +                PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx "
   1.304 +			     "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.305 +			     l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.306 +							    >> PAGE_SHIFT]) >>
   1.307 +			     PAGE_SHIFT,
   1.308 +			     frame_table[pfn].u.inuse.type_info,
   1.309 +			     frame_table[pfn].u.inuse.count_info,
   1.310 +			     frame_table[pfn].u.inuse.domain->domain));
   1.311                  /* disconnect l1 page */
   1.312                  nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) &
   1.313                                        ~_PAGE_PRESENT) | 0x800);
   1.314                  update_l2e(pl2e, *pl2e, nl2e);
   1.315  
   1.316 -                ptwr_disconnected[cpu] = (page->u.inuse.type_info & PGT_va_mask)
   1.317 -                    >> PGT_va_shift;
   1.318 -                PTWR_PRINTK("now pl2e %p l2e %08lx              taf %08x/%08x/%u\n",
   1.319 -                            pl2e, l2_pgentry_val(*pl2e),
   1.320 -                            frame_table[pfn].u.inuse.type_info,
   1.321 -                            frame_table[pfn].u.inuse.count_info,
   1.322 -                            frame_table[pfn].u.inuse.domain->domain);
   1.323 -                ptwr_writable_l1[cpu] = (unsigned long *)
   1.324 -                    &linear_pg_table[addr>>PAGE_SHIFT];
   1.325 +                ptwr_info[cpu].disconnected =
   1.326 +		    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   1.327 +                PTWR_PRINTK(("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].u.inuse.count_info,
   1.331 +			     frame_table[pfn].u.inuse.domain->domain));
   1.332 +                ptwr_info[cpu].writable_l1 =
   1.333 +		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   1.334                  pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) <<
   1.335                                        PAGE_SHIFT);
   1.336 -                memcpy(&ptwr_disconnected_page[cpu][0], pl1e,
   1.337 +                memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e,
   1.338                         ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.339                  unmap_domain_mem(pl1e);
   1.340              }
   1.341              /* make pt page writable */
   1.342              pte |= _PAGE_RW;
   1.343 -            PTWR_PRINTK("update %p pte to %08lx\n",
   1.344 -                   &linear_pg_table[addr>>PAGE_SHIFT], pte);
   1.345 +            PTWR_PRINTK(("update %p pte to %08lx\n",
   1.346 +			 &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.347              if (__put_user(pte, (unsigned long *)
   1.348                             &linear_pg_table[addr>>PAGE_SHIFT]))
   1.349                  BUG();
   1.350 @@ -1480,34 +1494,35 @@ void ptwr_status(void)
   1.351      l2_pgentry_t *pl2e;
   1.352      int cpu = smp_processor_id();
   1.353  
   1.354 -    for (i = 0; i < ptwr_writable_idx[cpu]; i++) {
   1.355 -        if (__get_user(pte, ptwr_writables[cpu][i]))
   1.356 +    for (i = 0; i < ptwr_info[cpu].writable_idx; i++) {
   1.357 +        if (__get_user(pte, ptwr_info[cpu].writables[i]))
   1.358              BUG();
   1.359          pfn = pte >> PAGE_SHIFT;
   1.360          page = &frame_table[pfn];
   1.361          printk("need to alloc l1 page %p\n", page);
   1.362          /* make pt page writable */
   1.363          printk("need to make read-only l1-page at %p is %08lx\n",
   1.364 -               ptwr_writables[cpu][i], pte);
   1.365 +               ptwr_info[cpu].writables[i], pte);
   1.366      }
   1.367  
   1.368 -    if (ptwr_disconnected[cpu] == ENTRIES_PER_L2_PAGETABLE)
   1.369 +    if (ptwr_info[cpu].disconnected == ENTRIES_PER_L2_PAGETABLE)
   1.370          return;
   1.371  
   1.372      printk("disconnected space: space %08lx\n",
   1.373 -           ptwr_disconnected[cpu] << L2_PAGETABLE_SHIFT);
   1.374 -    pl2e = &linear_l2_table[ptwr_disconnected[cpu]];
   1.375 +           ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT);
   1.376 +    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
   1.377  
   1.378 -    if (__get_user(pte, ptwr_writable_l1[cpu]))
   1.379 +    if (__get_user(pte, ptwr_info[cpu].writable_l1))
   1.380          BUG();
   1.381      pfn = pte >> PAGE_SHIFT;
   1.382      page = &frame_table[pfn];
   1.383  
   1.384 -    PTWR_PRINTK("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.385 -                l2_pgentry_val(*pl2e),
   1.386 -                l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.387 -                                               PAGE_SHIFT]) >> PAGE_SHIFT,
   1.388 -                frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.389 -                frame_table[pfn].u.inuse.type_info, frame_table[pfn].u.inuse.domain->domain);
   1.390 +    PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   1.391 +		 l2_pgentry_val(*pl2e),
   1.392 +		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   1.393 +						PAGE_SHIFT]) >> PAGE_SHIFT,
   1.394 +		 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.395 +		 frame_table[pfn].u.inuse.type_info,
   1.396 +		 frame_table[pfn].u.inuse.domain->domain));
   1.397  }
   1.398  #endif
     2.1 --- a/xen/arch/x86/traps.c	Tue Aug 03 13:37:05 2004 +0000
     2.2 +++ b/xen/arch/x86/traps.c	Tue Aug 03 14:03:58 2004 +0000
     2.3 @@ -331,7 +331,7 @@ asmlinkage void do_page_fault(struct pt_
     2.4              return; /* successfully copied the mapping */
     2.5      }
     2.6  
     2.7 -    if ((addr >> L2_PAGETABLE_SHIFT) == ptwr_disconnected[cpu]) {
     2.8 +    if ((addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected) {
     2.9          ptwr_reconnect_disconnected(addr);
    2.10          return;
    2.11      }
     3.1 --- a/xen/common/schedule.c	Tue Aug 03 13:37:05 2004 +0000
     3.2 +++ b/xen/common/schedule.c	Tue Aug 03 14:03:58 2004 +0000
     3.3 @@ -371,7 +371,7 @@ void __enter_scheduler(void)
     3.4      if ( unlikely(prev == next) )
     3.5          return;
     3.6      
     3.7 -    cleanup_writable_pagetable(PTRW_CLEANUP_ACTIVE | PTRW_CLEANUP_INACTIVE);
     3.8 +    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
     3.9  
    3.10  #ifdef PTWR_TRACK_DOMAIN
    3.11      {
     4.1 --- a/xen/include/asm-x86/mm.h	Tue Aug 03 13:37:05 2004 +0000
     4.2 +++ b/xen/include/asm-x86/mm.h	Tue Aug 03 14:03:58 2004 +0000
     4.3 @@ -329,25 +329,39 @@ int memguard_is_guarded(void *p);
     4.4  #define memguard_is_guarded(_p)        (0)
     4.5  #endif
     4.6  
     4.7 -/*  */
     4.8 -extern unsigned long ptwr_disconnected[];
     4.9 -extern int ptwr_writable_idx[];
    4.10 +
    4.11 +/* Writable Pagetables */
    4.12 +#define	PTWR_NR_WRITABLES 1
    4.13 +typedef struct {
    4.14 +    unsigned long disconnected;
    4.15 +    l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE];
    4.16 +    unsigned long *writable_l1;
    4.17 +    unsigned long *writables[PTWR_NR_WRITABLES];
    4.18 +    int writable_idx;
    4.19 +    l1_pgentry_t writable_page[PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE];
    4.20 +#ifdef PTWR_TRACK_DOMAIN
    4.21 +    domid_t domain;
    4.22 +#endif
    4.23 +} __cacheline_aligned ptwr_info_t;
    4.24 +
    4.25 +extern ptwr_info_t ptwr_info[];
    4.26 +
    4.27 +#define PTWR_CLEANUP_ACTIVE	1
    4.28 +#define PTWR_CLEANUP_INACTIVE	2
    4.29 +
    4.30  void ptwr_reconnect_disconnected(unsigned long addr);
    4.31  void ptwr_flush_inactive(void);
    4.32  int ptwr_do_page_fault(unsigned long);
    4.33  
    4.34 -#define PTRW_CLEANUP_ACTIVE	1
    4.35 -#define PTRW_CLEANUP_INACTIVE	2
    4.36 -
    4.37  static inline void cleanup_writable_pagetable(const int what)
    4.38  {
    4.39      int cpu = smp_processor_id();
    4.40  
    4.41 -    if (what & PTRW_CLEANUP_ACTIVE)
    4.42 -        if (ptwr_disconnected[cpu] != ENTRIES_PER_L2_PAGETABLE)
    4.43 +    if (what & PTWR_CLEANUP_ACTIVE)
    4.44 +        if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE)
    4.45              ptwr_reconnect_disconnected(0L);
    4.46 -    if (what & PTRW_CLEANUP_INACTIVE)
    4.47 -        if (ptwr_writable_idx[cpu])
    4.48 +    if (what & PTWR_CLEANUP_INACTIVE)
    4.49 +        if (ptwr_info[cpu].writable_idx)
    4.50              ptwr_flush_inactive();
    4.51  }
    4.52