ia64/xen-unstable

changeset 2474:c3fbcaa24a41

bitkeeper revision 1.1159.1.151 (4146b5306QI3lyn9RWNjqIQrf4XltA)

Merge active/inactive writable pagetable code.
author cl349@freefall.cl.cam.ac.uk
date Tue Sep 14 09:09:04 2004 +0000 (2004-09-14)
parents c02736a96f00
children f0629dc22034 d90f9be8758d
files xen/arch/x86/memory.c xen/arch/x86/traps.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Mon Sep 13 10:30:18 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Tue Sep 14 09:09:04 2004 +0000
     1.3 @@ -1615,62 +1615,42 @@ int do_update_va_mapping_otherdomain(uns
     1.4  ptwr_info_t ptwr_info[NR_CPUS] =
     1.5      { [ 0 ... NR_CPUS-1 ] =
     1.6        {
     1.7 -          .disconnected_pteidx = -1,
     1.8 -          .disconnected_page = 0,
     1.9 -          .writable_l1va = 0,
    1.10 -          .writable_page = 0,
    1.11 +          .ptinfo[PTWR_PT_ACTIVE].l1va = 0,
    1.12 +          .ptinfo[PTWR_PT_ACTIVE].page = 0,
    1.13 +          .ptinfo[PTWR_PT_INACTIVE].l1va = 0,
    1.14 +          .ptinfo[PTWR_PT_INACTIVE].page = 0,
    1.15        }
    1.16      };
    1.17  
    1.18  #ifdef VERBOSE
    1.19  int ptwr_debug = 0x0;
    1.20 -#define PTWR_PRINTK(w, x) if (ptwr_debug & (w)) printk x
    1.21 +#define PTWR_PRINTK(w, x) if ( unlikely(ptwr_debug & (w)) ) printk x
    1.22  #define PP_ALL 0xff
    1.23 -#define PP_A 0x1
    1.24 -#define PP_I 0x2
    1.25  #else
    1.26  #define PTWR_PRINTK(w, x)
    1.27  #endif
    1.28  
    1.29 -void ptwr_reconnect_disconnected(void)
    1.30 +void ptwr_flush(const int which)
    1.31  {
    1.32 -    unsigned long pte;
    1.33 -#ifdef VERBOSE
    1.34 -    unsigned long pfn;
    1.35 -    l2_pgentry_t *pl2e;
    1.36 -#endif
    1.37 +    unsigned long pte, *ptep;
    1.38      l1_pgentry_t *pl1e;
    1.39      int cpu = smp_processor_id();
    1.40      int i;
    1.41 -    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.42 -        [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT];
    1.43 -
    1.44 -    PTWR_PRINTK(PP_A, ("[A] page fault in disconn space %08lx\n",
    1.45 -                       ptwr_info[cpu].disconnected_pteidx <<
    1.46 -                       L2_PAGETABLE_SHIFT));
    1.47  
    1.48 -#ifdef VERBOSE
    1.49 -    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx];
    1.50 -    pfn = ptwr_info[cpu].disconnected_pte >> PAGE_SHIFT;
    1.51 -#endif
    1.52 -    PTWR_PRINTK(PP_A, ("[A]     pl2e %p l2e %08lx pfn %08lx taf %08x/%08x\n",
    1.53 -                       pl2e, l2_pgentry_val(*pl2e), l1_pgentry_val(
    1.54 -                           linear_pg_table[(unsigned long)pl2e >>
    1.55 -                                           PAGE_SHIFT]) >> PAGE_SHIFT,
    1.56 -                       frame_table[pfn].u.inuse.type_info,
    1.57 -                       frame_table[pfn].count_info));
    1.58 +    ptep = (unsigned long *)&linear_pg_table
    1.59 +        [ptwr_info[cpu].ptinfo[which].l1va>>PAGE_SHIFT];
    1.60  
    1.61 -    pl1e = ptwr_info[cpu].disconnected_pl1e;
    1.62 +    pl1e = ptwr_info[cpu].ptinfo[which].pl1e;
    1.63      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.64          l1_pgentry_t ol1e, nl1e;
    1.65 -        nl1e = ptwr_info[cpu].disconnected_page[i];
    1.66 +        nl1e = ptwr_info[cpu].ptinfo[which].page[i];
    1.67          ol1e = pl1e[i];
    1.68          if (likely(l1_pgentry_val(nl1e) == l1_pgentry_val(ol1e)))
    1.69              continue;
    1.70          if (likely(l1_pgentry_val(nl1e) == (l1_pgentry_val(ol1e) | _PAGE_RW)))
    1.71          {
    1.72              if (likely(readonly_page_from_l1e(nl1e))) {
    1.73 -                pl1e[i] = ptwr_info[cpu].disconnected_page[i];
    1.74 +                pl1e[i] = ptwr_info[cpu].ptinfo[which].page[i];
    1.75                  continue;
    1.76              }
    1.77          }
    1.78 @@ -1680,141 +1660,58 @@ void ptwr_reconnect_disconnected(void)
    1.79              MEM_LOG("ptwr: Could not re-validate l1 page\n");
    1.80              domain_crash();
    1.81          }
    1.82 -        pl1e[i] = ptwr_info[cpu].disconnected_page[i];
    1.83 +        pl1e[i] = ptwr_info[cpu].ptinfo[which].page[i];
    1.84      }
    1.85      unmap_domain_mem(pl1e);
    1.86  
    1.87 -    PTWR_PRINTK(PP_A,
    1.88 -                ("[A] now pl2e %p l2e %08lx              taf %08x/%08x\n",
    1.89 -                 pl2e, l2_pgentry_val(*pl2e),
    1.90 -                 frame_table[pfn].u.inuse.type_info,
    1.91 -                 frame_table[pfn].count_info));
    1.92 -    ptwr_info[cpu].disconnected_pteidx = -1;
    1.93 -
    1.94      /* make pt page write protected */
    1.95 -    if (__get_user(pte, writable_pte)) {
    1.96 -        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.97 +    if ( unlikely(__get_user(pte, ptep)) ) {
    1.98 +        MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
    1.99          domain_crash();
   1.100      }
   1.101 -    PTWR_PRINTK(PP_A, ("[A] disconnected_l1va at %p is %08lx\n",
   1.102 -                       writable_pte, pte));
   1.103 -    pte = (ptwr_info[cpu].disconnected_pte & PAGE_MASK) |
   1.104 +    PTWR_PRINTK(PP_ALL, ("disconnected_l1va at %p is %08lx\n",
   1.105 +                         ptep, pte));
   1.106 +    pte = (ptwr_info[cpu].ptinfo[which].pte & PAGE_MASK) |
   1.107          (pte & ~(PAGE_MASK|_PAGE_RW));
   1.108 -    if (__put_user(pte, writable_pte)) {
   1.109 -        MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.110 +    if ( unlikely(__put_user(pte, ptep)) ) {
   1.111 +        MEM_LOG("ptwr: Could not update pte at %p\n", ptep);
   1.112          domain_crash();
   1.113      }
   1.114  
   1.115      if ( unlikely(current->mm.shadow_mode) )
   1.116      {
   1.117 -	unsigned long spte;
   1.118 -	unsigned long sstat = 
   1.119 -	    get_shadow_status(&current->mm, 
   1.120 -			      ptwr_info[cpu].disconnected_pte >> PAGE_SHIFT);
   1.121 +        unsigned long spte;
   1.122 +        unsigned long sstat = 
   1.123 +            get_shadow_status(&current->mm, 
   1.124 +                              ptwr_info[cpu].ptinfo[which].pte >> PAGE_SHIFT);
   1.125  
   1.126 -	if ( sstat & PSH_shadowed ) 
   1.127 -	{ 
   1.128 -	    int i;
   1.129 -	    unsigned long spfn = sstat & PSH_pfn_mask;
   1.130 -	    l1_pgentry_t *sl1e = map_domain_mem( spfn << PAGE_SHIFT );
   1.131 -	    
   1.132 -	    for( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.133 -		l1pte_no_fault( &current->mm, 
   1.134 -				&l1_pgentry_val(
   1.135 -				    ptwr_info[cpu].disconnected_page[i]),
   1.136 -				&l1_pgentry_val(sl1e[i]) );
   1.137 -	    }
   1.138 -	    unmap_domain_mem( sl1e );
   1.139 -	    put_shadow_status(&current->mm);
   1.140 -	} 
   1.141 +        if ( sstat & PSH_shadowed ) 
   1.142 +        { 
   1.143 +            int i;
   1.144 +            unsigned long spfn = sstat & PSH_pfn_mask;
   1.145 +            l1_pgentry_t *sl1e = map_domain_mem( spfn << PAGE_SHIFT );
   1.146 +            
   1.147 +            for( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
   1.148 +            {
   1.149 +                l1pte_no_fault(&current->mm, 
   1.150 +                               &l1_pgentry_val(
   1.151 +                                   ptwr_info[cpu].ptinfo[which].page[i]),
   1.152 +                               &l1_pgentry_val(sl1e[i]));
   1.153 +            }
   1.154 +            unmap_domain_mem(sl1e);
   1.155 +            put_shadow_status(&current->mm);
   1.156 +        } 
   1.157  
   1.158 -	l1pte_no_fault( &current->mm,
   1.159 -			&pte, &spte );
   1.160 -	__put_user(spte, (unsigned long *)&shadow_linear_pg_table
   1.161 -		   [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT] );
   1.162 +        l1pte_no_fault(&current->mm, &pte, &spte);
   1.163 +        __put_user(spte, (unsigned long *)&shadow_linear_pg_table
   1.164 +                   [ptwr_info[cpu].ptinfo[which].l1va>>PAGE_SHIFT]);
   1.165      }
   1.166  
   1.167 -    __flush_tlb_one(ptwr_info[cpu].disconnected_l1va);
   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;
   1.176 -    l1_pgentry_t *pl1e;
   1.177 -    int cpu = smp_processor_id();
   1.178 -    int i;
   1.179 -    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.180 -        [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT];
   1.181 -
   1.182 -    pl1e = ptwr_info[cpu].writable_pl1e;
   1.183 -    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.184 -        l1_pgentry_t ol1e, nl1e;
   1.185 -        nl1e = ptwr_info[cpu].writable_page[i];
   1.186 -        ol1e = pl1e[i];
   1.187 -        if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
   1.188 -            continue;
   1.189 -        if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
   1.190 -            put_page_from_l1e(ol1e, current);
   1.191 -        if (unlikely(!get_page_from_l1e(nl1e, current))) {
   1.192 -            MEM_LOG("ptwr: Could not re-validate l1 page\n");
   1.193 -            domain_crash();
   1.194 -        }
   1.195 -        pl1e[i] = ptwr_info[cpu].writable_page[i];
   1.196 -    }
   1.197 -    unmap_domain_mem(pl1e);
   1.198 +    __flush_tlb_one(ptwr_info[cpu].ptinfo[which].l1va);
   1.199 +    PTWR_PRINTK(PP_ALL, ("disconnected_l1va at %p now %08lx\n",
   1.200 +                         ptep, pte));
   1.201  
   1.202 -    /* make pt page write protected */
   1.203 -    if (__get_user(pte, writable_pte)) {
   1.204 -        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.205 -        domain_crash();
   1.206 -    }
   1.207 -    PTWR_PRINTK(PP_I, ("[I] disconnected_l1va at %p is %08lx\n",
   1.208 -                       writable_pte, pte));
   1.209 -    pte = (ptwr_info[cpu].writable_pte & PAGE_MASK) |
   1.210 -        (pte & ~(PAGE_MASK|_PAGE_RW));
   1.211 -    if (__put_user(pte, writable_pte)) {
   1.212 -        MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.213 -        domain_crash();
   1.214 -    }
   1.215 -
   1.216 -    if ( unlikely(current->mm.shadow_mode) )
   1.217 -    {
   1.218 -	unsigned long spte;
   1.219 -	unsigned long sstat = 
   1.220 -	    get_shadow_status(&current->mm, 
   1.221 -			      ptwr_info[cpu].writable_pte >> PAGE_SHIFT);
   1.222 -
   1.223 -	if ( sstat & PSH_shadowed ) 
   1.224 -	{ 
   1.225 -	    int i;
   1.226 -	    unsigned long spfn = sstat & PSH_pfn_mask;
   1.227 -	    l1_pgentry_t *sl1e = map_domain_mem( spfn << PAGE_SHIFT );
   1.228 -	    
   1.229 -	    for( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.230 -		l1pte_no_fault( &current->mm, 
   1.231 -				&l1_pgentry_val(
   1.232 -				    ptwr_info[cpu].writable_page[i]),
   1.233 -				&l1_pgentry_val(sl1e[i]) );
   1.234 -					       
   1.235 -	    }
   1.236 -	    unmap_domain_mem( sl1e );
   1.237 -	    put_shadow_status(&current->mm);
   1.238 -	} 
   1.239 -
   1.240 -	l1pte_no_fault( &current->mm,
   1.241 -			&pte, &spte );
   1.242 -	__put_user(spte, (unsigned long *)&shadow_linear_pg_table
   1.243 -		   [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT] );
   1.244 -    }
   1.245 -
   1.246 -    __flush_tlb_one(ptwr_info[cpu].writable_l1va);
   1.247 -    PTWR_PRINTK(PP_I, ("[I] disconnected_l1va at %p now %08lx\n",
   1.248 -                       writable_pte, pte));
   1.249 -
   1.250 -    ptwr_info[cpu].writable_l1va = 0;
   1.251 +    ptwr_info[cpu].ptinfo[which].l1va = 0;
   1.252  }
   1.253  
   1.254  int ptwr_do_page_fault(unsigned long addr)
   1.255 @@ -1824,6 +1721,7 @@ int ptwr_do_page_fault(unsigned long add
   1.256      struct pfn_info *page;
   1.257      l2_pgentry_t *pl2e;
   1.258      int cpu = smp_processor_id();
   1.259 +    int which;
   1.260  
   1.261  #if 0
   1.262      PTWR_PRINTK(PP_ALL, ("get user %p for va %08lx\n",
   1.263 @@ -1836,8 +1734,8 @@ int ptwr_do_page_fault(unsigned long add
   1.264           (__get_user(pte, (unsigned long *)
   1.265                       &linear_pg_table[addr >> PAGE_SHIFT]) == 0) )
   1.266      {
   1.267 -	if( (pte & _PAGE_RW) && (pte & _PAGE_PRESENT) )
   1.268 -	    return 0; /* we can't help. Maybe shadow mode can? */
   1.269 +        if( (pte & _PAGE_RW) && (pte & _PAGE_PRESENT) )
   1.270 +            return 0; /* we can't help. Maybe shadow mode can? */
   1.271  
   1.272          pfn = pte >> PAGE_SHIFT;
   1.273  #if 0
   1.274 @@ -1849,11 +1747,6 @@ int ptwr_do_page_fault(unsigned long add
   1.275          {
   1.276              u32 va_mask = page->u.inuse.type_info & PGT_va_mask;
   1.277  
   1.278 -            /*
   1.279 -             * XXX KAF: This version of writable pagetables doesn't need
   1.280 -             * to know the back pointer at all, as it is unnecessary to be
   1.281 -             * unlinking the page table --- FIXME!
   1.282 -             */
   1.283              if ( unlikely(va_mask >= PGT_va_unknown) )
   1.284                  domain_crash();
   1.285              va_mask >>= PGT_va_shift;
   1.286 @@ -1863,71 +1756,38 @@ int ptwr_do_page_fault(unsigned long add
   1.287                                   ", pfn %08lx\n", addr,
   1.288                                   va_mask << L2_PAGETABLE_SHIFT, pfn));
   1.289  
   1.290 -            if ( l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn )
   1.291 -            {
   1.292 -                /* this L1 is not in the current address space */
   1.293 -                PTWR_PRINTK(PP_I, ("[I] freeing l1 page %p taf %08x/%08x\n",
   1.294 -                                   page, page->u.inuse.type_info,
   1.295 -                                   page->count_info));
   1.296 -                if (ptwr_info[cpu].writable_l1va)
   1.297 -                    ptwr_flush_inactive();
   1.298 -                ptwr_info[cpu].writable_l1va = addr | 1;
   1.299 +            which = (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) ?
   1.300 +                PTWR_PT_INACTIVE : PTWR_PT_ACTIVE;
   1.301  
   1.302 -                ptwr_info[cpu].writable_pl1e =
   1.303 -                    map_domain_mem(pfn << PAGE_SHIFT);
   1.304 -                memcpy(ptwr_info[cpu].writable_page,
   1.305 -                       ptwr_info[cpu].writable_pl1e,
   1.306 -                       ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.307 +            if ( ptwr_info[cpu].ptinfo[which].l1va )
   1.308 +                ptwr_flush(which);
   1.309 +            ptwr_info[cpu].ptinfo[which].l1va = addr | 1;
   1.310  
   1.311 -                /* make pt page writable */
   1.312 -                ptwr_info[cpu].writable_pte = pte;
   1.313 -                pte = (virt_to_phys(ptwr_info[cpu].writable_page) &
   1.314 -                       PAGE_MASK) | _PAGE_RW | (pte & ~PAGE_MASK);
   1.315 -            }
   1.316 -            else
   1.317 -            {
   1.318 -                if ( ptwr_info[cpu].disconnected_pteidx >= 0 )
   1.319 -                    ptwr_reconnect_disconnected();
   1.320 +            if (which == PTWR_PT_ACTIVE)
   1.321 +                ptwr_info[cpu].active_pteidx = va_mask;
   1.322  
   1.323 -		/* No need to actually disconnect L1 anymore in v2 wr_pt  */
   1.324 -
   1.325 -                ptwr_info[cpu].disconnected_pteidx = va_mask;
   1.326 -                PTWR_PRINTK(PP_A, ("[A] now pl2e %p l2e %08lx              "
   1.327 -                                   "taf %08x/%08x\n", pl2e,
   1.328 -                                   l2_pgentry_val(*pl2e),
   1.329 -                                   frame_table[pfn].u.inuse.type_info,
   1.330 -                                   frame_table[pfn].count_info));
   1.331 -                ptwr_info[cpu].disconnected_l1va = addr;
   1.332 -                ptwr_info[cpu].disconnected_pl1e =
   1.333 -                    map_domain_mem( l2_pgentry_to_pagenr(*pl2e)<<PAGE_SHIFT );
   1.334 +            ptwr_info[cpu].ptinfo[which].pl1e =
   1.335 +                map_domain_mem(pfn << PAGE_SHIFT);
   1.336 +            memcpy(ptwr_info[cpu].ptinfo[which].page,
   1.337 +                   ptwr_info[cpu].ptinfo[which].pl1e,
   1.338 +                   ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.339  
   1.340 -		/* XXX we could use the linear page table here... */	      
   1.341 -		ASSERT( ((page->u.inuse.type_info & PGT_va_mask) >> 
   1.342 -			 PGT_va_shift) < (PAGE_OFFSET >> L2_PAGETABLE_SHIFT)); 
   1.343 -
   1.344 -                memcpy(&ptwr_info[cpu].disconnected_page[0],
   1.345 -                       ptwr_info[cpu].disconnected_pl1e,
   1.346 -                       ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   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 +            /* make pt page writable */
   1.354 +            ptwr_info[cpu].ptinfo[which].pte = pte;
   1.355 +            pte = (virt_to_phys(ptwr_info[cpu].ptinfo[which].page) &
   1.356 +                   PAGE_MASK) | _PAGE_RW | (pte & ~PAGE_MASK);
   1.357  
   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 +            if ( unlikely(__put_user(pte, (unsigned long *)
   1.363 +                                     &linear_pg_table[addr>>PAGE_SHIFT])) ) {
   1.364                  MEM_LOG("ptwr: Could not update pte at %p\n", (unsigned long *)
   1.365                          &linear_pg_table[addr>>PAGE_SHIFT]);
   1.366                  domain_crash();
   1.367              }
   1.368  
   1.369 -	    if( unlikely(current->mm.shadow_mode) )
   1.370 -		return 0;  /* fall through to shadow mode to propagate */
   1.371 -	    else
   1.372 -		return 1;
   1.373 +            /* maybe fall through to shadow mode to propagate */
   1.374 +            return ( !current->mm.shadow_mode );
   1.375          }
   1.376      }
   1.377      return 0;
   1.378 @@ -1939,8 +1799,10 @@ static __init int ptwr_init(void)
   1.379  
   1.380      for ( i = 0; i < smp_num_cpus; i++ )
   1.381      {
   1.382 -        ptwr_info[i].disconnected_page = (void *)alloc_xenheap_page();
   1.383 -        ptwr_info[i].writable_page = (void *)alloc_xenheap_page();
   1.384 +        ptwr_info[i].ptinfo[PTWR_PT_ACTIVE].page =
   1.385 +            (void *)alloc_xenheap_page();
   1.386 +        ptwr_info[i].ptinfo[PTWR_PT_INACTIVE].page =
   1.387 +            (void *)alloc_xenheap_page();
   1.388      }
   1.389  
   1.390      return 0;
   1.391 @@ -1950,16 +1812,15 @@ static __init int ptwr_init(void)
   1.392  #ifndef NDEBUG
   1.393  void ptwr_status(void)
   1.394  {
   1.395 -    unsigned long pte, pfn;
   1.396 +    unsigned long pte, *ptep, pfn;
   1.397      struct pfn_info *page;
   1.398 -    l2_pgentry_t *pl2e;
   1.399      int cpu = smp_processor_id();
   1.400  
   1.401 -    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.402 -        [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT];
   1.403 +    ptep = (unsigned long *)&linear_pg_table
   1.404 +        [ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va>>PAGE_SHIFT];
   1.405  
   1.406 -    if ( __get_user(pte, writable_pte) ) {
   1.407 -        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.408 +    if ( __get_user(pte, ptep) ) {
   1.409 +        MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
   1.410          domain_crash();
   1.411      }
   1.412  
   1.413 @@ -1968,30 +1829,19 @@ void ptwr_status(void)
   1.414      printk("need to alloc l1 page %p\n", page);
   1.415      /* make pt page writable */
   1.416      printk("need to make read-only l1-page at %p is %08lx\n",
   1.417 -           writable_pte, pte);
   1.418 +           ptep, pte);
   1.419  
   1.420 -    if ( ptwr_info[cpu].disconnected_pteidx < 0 )
   1.421 +    if ( ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va == 0 )
   1.422          return;
   1.423  
   1.424 -    printk("disconnected space: space %08lx\n",
   1.425 -           ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT);
   1.426 -    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx];
   1.427 -
   1.428 -    if ( __get_user(pte, (unsigned long *)ptwr_info[cpu].disconnected_l1va) ) {
   1.429 +    if ( __get_user(pte, (unsigned long *)
   1.430 +                    ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va) ) {
   1.431          MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *)
   1.432 -                ptwr_info[cpu].disconnected_l1va);
   1.433 +                ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va);
   1.434          domain_crash();
   1.435      }
   1.436      pfn = pte >> PAGE_SHIFT;
   1.437      page = &frame_table[pfn];
   1.438 -
   1.439 -    PTWR_PRINTK(PP_ALL, ("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x\n",
   1.440 -                         pl2e, l2_pgentry_val(*pl2e), l1_pgentry_val(
   1.441 -                             linear_pg_table[(unsigned long)pl2e >>
   1.442 -                                             PAGE_SHIFT]) >> PAGE_SHIFT,
   1.443 -                         frame_table[
   1.444 -                             l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   1.445 -                         frame_table[pfn].u.inuse.type_info));
   1.446  }
   1.447  
   1.448  
     2.1 --- a/xen/arch/x86/traps.c	Mon Sep 13 10:30:18 2004 +0000
     2.2 +++ b/xen/arch/x86/traps.c	Tue Sep 14 09:09:04 2004 +0000
     2.3 @@ -359,10 +359,11 @@ asmlinkage void do_page_fault(struct pt_
     2.4  
     2.5      if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
     2.6      {
     2.7 -        if ( unlikely((addr >> L2_PAGETABLE_SHIFT) ==
     2.8 -                      ptwr_info[cpu].disconnected_pteidx ))
     2.9 +        if ( unlikely(ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va &&
    2.10 +                      (addr >> L2_PAGETABLE_SHIFT) ==
    2.11 +                      ptwr_info[cpu].active_pteidx ))
    2.12          {
    2.13 -            ptwr_reconnect_disconnected();
    2.14 +            ptwr_flush(PTWR_PT_ACTIVE);
    2.15              return;
    2.16          }
    2.17  
     3.1 --- a/xen/include/asm-x86/mm.h	Mon Sep 13 10:30:18 2004 +0000
     3.2 +++ b/xen/include/asm-x86/mm.h	Tue Sep 14 09:09:04 2004 +0000
     3.3 @@ -250,35 +250,37 @@ extern vm_assist_info_t vm_assist_info[]
     3.4  
     3.5  /* Writable Pagetables */
     3.6  typedef struct {
     3.7 -    unsigned long disconnected_l1va;
     3.8 -    l1_pgentry_t *disconnected_page;
     3.9 -    long disconnected_pteidx;
    3.10 -    unsigned long disconnected_pte;
    3.11 -    l1_pgentry_t *disconnected_pl1e;
    3.12 -    unsigned long writable_l1va;
    3.13 -    l1_pgentry_t *writable_page;
    3.14 -    unsigned long writable_pte;
    3.15 -    l1_pgentry_t *writable_pl1e;
    3.16 +    unsigned long l1va;
    3.17 +    l1_pgentry_t *page;
    3.18 +    unsigned long pte;
    3.19 +    l1_pgentry_t *pl1e;
    3.20 +} ptwr_ptinfo_t;
    3.21 +
    3.22 +typedef struct {
    3.23 +    ptwr_ptinfo_t ptinfo[2];
    3.24 +    long active_pteidx;
    3.25  } __cacheline_aligned ptwr_info_t;
    3.26  
    3.27  extern ptwr_info_t ptwr_info[];
    3.28  
    3.29 -#define PTWR_CLEANUP_ACTIVE	1
    3.30 -#define PTWR_CLEANUP_INACTIVE	2
    3.31 +#define PTWR_PT_ACTIVE 0
    3.32 +#define PTWR_PT_INACTIVE 1
    3.33  
    3.34 -void ptwr_reconnect_disconnected(void);
    3.35 -void ptwr_flush_inactive(void);
    3.36 +#define PTWR_CLEANUP_ACTIVE 1
    3.37 +#define PTWR_CLEANUP_INACTIVE 2
    3.38 +
    3.39 +void ptwr_flush(const int);
    3.40  int ptwr_do_page_fault(unsigned long);
    3.41  
    3.42  #define __cleanup_writable_pagetable(_what)                                 \
    3.43  do {                                                                        \
    3.44      int cpu = smp_processor_id();                                           \
    3.45      if ((_what) & PTWR_CLEANUP_ACTIVE)                                      \
    3.46 -        if (ptwr_info[cpu].disconnected_pteidx >= 0)                        \
    3.47 -            ptwr_reconnect_disconnected();                                  \
    3.48 +        if (ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va)                     \
    3.49 +            ptwr_flush(PTWR_PT_ACTIVE);                                     \
    3.50      if ((_what) & PTWR_CLEANUP_INACTIVE)                                    \
    3.51 -        if (ptwr_info[cpu].writable_l1va)                                   \
    3.52 -            ptwr_flush_inactive();                                          \
    3.53 +        if (ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va)                   \
    3.54 +            ptwr_flush(PTWR_PT_INACTIVE);                                   \
    3.55  } while ( 0 )
    3.56  
    3.57  #define cleanup_writable_pagetable(_d, _w)                                \