ia64/xen-unstable

changeset 1883:ce3ac2fde5dd

bitkeeper revision 1.1122 (4100e6888NElNlJWva2s9TQlJ4nejw)

Fastpath revalidation of pages going from writable to read-only.
author cl349@freefall.cl.cam.ac.uk
date Fri Jul 23 10:20:56 2004 +0000 (2004-07-23)
parents 853d916ceb18
children 381b2b637b12
files xen/arch/x86/memory.c
line diff
     1.1 --- a/xen/arch/x86/memory.c	Thu Jul 22 21:20:32 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Fri Jul 23 10:20:56 2004 +0000
     1.3 @@ -1224,6 +1224,18 @@ int do_update_va_mapping_otherdomain(uns
     1.4  }
     1.5  
     1.6  
     1.7 +static inline int readonly_page_from_l1e(l1_pgentry_t l1e)
     1.8 +{
     1.9 +    struct pfn_info *page = &frame_table[l1_pgentry_to_pagenr(l1e)];
    1.10 +    unsigned long    l1v  = l1_pgentry_val(l1e);
    1.11 +
    1.12 +    if ( (l1v & _PAGE_RW) || !(l1v & _PAGE_PRESENT) ||
    1.13 +         !pfn_is_ram(l1v >> PAGE_SHIFT) )
    1.14 +        return 0;
    1.15 +    put_page_type(page);
    1.16 +    return 1;
    1.17 +}
    1.18 +
    1.19  /*  */
    1.20  unsigned long ptwr_disconnected[NR_CPUS] __cacheline_aligned =
    1.21  	{ [ 0 ... NR_CPUS-1 ] = ENTRIES_PER_L2_PAGETABLE };
    1.22 @@ -1277,12 +1289,26 @@ void ptwr_reconnect_disconnected(unsigne
    1.23                           _PAGE_PRESENT);
    1.24      pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
    1.25      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.26 +        if ((l1_pgentry_val(pl1e[i]) ^
    1.27 +             l1_pgentry_val(ptwr_disconnected_page[cpu][i])) == _PAGE_RW) {
    1.28 +#if 0
    1.29 +            struct pfn_info *page = &frame_table[l1_pgentry_to_pagenr(pl1e[i])];
    1.30 +            printk("%03x: %08lx != %08lx %08x/%08x\n", i,
    1.31 +                   l1_pgentry_val(ptwr_disconnected_page[cpu][i]),
    1.32 +                   l1_pgentry_val(pl1e[i]), page->type_and_flags,
    1.33 +                   page->count_and_flags);
    1.34 +#endif
    1.35 +            if (readonly_page_from_l1e(pl1e[i]))
    1.36 +                continue;
    1.37 +        }
    1.38          if (l1_pgentry_val(pl1e[i]) != l1_pgentry_val(ptwr_disconnected_page[cpu][i])) {
    1.39  #if 0
    1.40 -            printk("%03x: %08lx != %08lx\n", i, l1_pgentry_val(pl1e[i]),
    1.41 -                   l1_pgentry_val(ptwr_disconnected_page[cpu][i]));
    1.42 +            printk("%03x: %08lx != %08lx\n", i,
    1.43 +                   l1_pgentry_val(ptwr_disconnected_page[cpu][i]),
    1.44 +                   l1_pgentry_val(pl1e[i]));
    1.45  #endif
    1.46 -            put_page_from_l1e(ptwr_disconnected_page[cpu][i]);
    1.47 +            if (l1_pgentry_val(ptwr_disconnected_page[cpu][i]) & _PAGE_PRESENT)
    1.48 +                put_page_from_l1e(ptwr_disconnected_page[cpu][i]);
    1.49              if (unlikely(!get_page_from_l1e(pl1e[i])))
    1.50                  BUG();
    1.51          }
    1.52 @@ -1320,12 +1346,17 @@ void ptwr_flush_inactive(void)
    1.53      l1_pgentry_t *pl1e;
    1.54      int cpu = smp_processor_id();
    1.55      int i, idx;
    1.56 +    static int maxidx = 0;
    1.57  
    1.58  #ifdef TRACK_PTWR_DOMAIN
    1.59      if (ptwr_domain[cpu] != get_current()->domain)
    1.60          printk("ptwr_flush_inactive domain mismatch %d != %d\n",
    1.61                 ptwr_domain[cpu], get_current()->domain);
    1.62  #endif
    1.63 +    if (ptwr_writable_idx[cpu] > maxidx) {
    1.64 +        maxidx = ptwr_writable_idx[cpu];
    1.65 +        printk("maxidx on cpu %d now %d\n", cpu, maxidx);
    1.66 +    }
    1.67      for (idx = 0; idx < ptwr_writable_idx[cpu]; idx++) {
    1.68          if (__get_user(pte, ptwr_writables[cpu][idx]))
    1.69              BUG();
    1.70 @@ -1335,13 +1366,29 @@ void ptwr_flush_inactive(void)
    1.71  
    1.72          pl1e = map_domain_mem(pfn << PAGE_SHIFT);
    1.73          for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.74 +#if 0
    1.75 +            if ((l1_pgentry_val(pl1e[i]) ^
    1.76 +                 l1_pgentry_val(ptwr_writable_page[cpu][idx][i])) == _PAGE_RW) {
    1.77 +#if 01
    1.78 +                struct pfn_info *page = &frame_table[l1_pgentry_to_pagenr(pl1e[i])];
    1.79 +                printk("%03x: %08lx != %08lx %08x/%08x\n", i,
    1.80 +                       l1_pgentry_val(ptwr_writable_page[cpu][idx][i]),
    1.81 +                       l1_pgentry_val(pl1e[i]), page->type_and_flags,
    1.82 +                       page->count_and_flags);
    1.83 +#endif
    1.84 +                if (readonly_page_from_l1e(pl1e[i]))
    1.85 +                    continue;
    1.86 +            }
    1.87 +#endif
    1.88              if (l1_pgentry_val(pl1e[i]) !=
    1.89                  l1_pgentry_val(ptwr_writable_page[cpu][idx][i])) {
    1.90  #if 0
    1.91 -                printk("%03x: %08lx != %08lx\n", i, l1_pgentry_val(pl1e[i]),
    1.92 -                       l1_pgentry_val(ptwr_writable_page[cpu][idx][i]));
    1.93 +                printk("%03x: %08lx != %08lx\n", i,
    1.94 +                       l1_pgentry_val(ptwr_writable_page[cpu][idx][i]),
    1.95 +                       l1_pgentry_val(pl1e[i]));
    1.96  #endif
    1.97 -                put_page_from_l1e(ptwr_writable_page[cpu][idx][i]);
    1.98 +                if (l1_pgentry_val(ptwr_writable_page[cpu][idx][i]) & _PAGE_PRESENT)
    1.99 +                    put_page_from_l1e(ptwr_writable_page[cpu][idx][i]);
   1.100                  if (unlikely(!get_page_from_l1e(pl1e[i])))
   1.101                      BUG();
   1.102              }