ia64/xen-unstable

changeset 2593:a28d3cf3832c

bitkeeper revision 1.1159.99.3 (41616473OrT0a62n0DQje0P8dGOxwA)

Go back to writable pagetables v1:
- disconnect pagetable page mapped va space
- give guest write permissions to its pagetable page
- tlb flush to avoid intermediate caching
- reorder operations for correctness on smp
author cl349@freefall.cl.cam.ac.uk
date Mon Oct 04 14:55:47 2004 +0000 (2004-10-04)
parents 654b2df93458
children a4fbb98f00cb fe2f4bbcf869
files xen/arch/x86/memory.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Mon Oct 04 13:23:57 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Mon Oct 04 14:55:47 2004 +0000
     1.3 @@ -1642,36 +1642,13 @@ void ptwr_flush(const int which)
     1.4  {
     1.5      unsigned long pte, *ptep;
     1.6      l1_pgentry_t *pl1e;
     1.7 +    l2_pgentry_t *pl2e, nl2e;
     1.8      int cpu = smp_processor_id();
     1.9      int i;
    1.10  
    1.11      ptep = (unsigned long *)&linear_pg_table
    1.12          [ptwr_info[cpu].ptinfo[which].l1va>>PAGE_SHIFT];
    1.13  
    1.14 -    pl1e = ptwr_info[cpu].ptinfo[which].pl1e;
    1.15 -    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.16 -        l1_pgentry_t ol1e, nl1e;
    1.17 -        nl1e = ptwr_info[cpu].ptinfo[which].page[i];
    1.18 -        ol1e = pl1e[i];
    1.19 -        if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
    1.20 -            continue;
    1.21 -        if (likely(l1_pgentry_val(ol1e) == (l1_pgentry_val(nl1e) | _PAGE_RW)))
    1.22 -        {
    1.23 -            if (likely(readonly_page_from_l1e(nl1e))) {
    1.24 -                pl1e[i] = nl1e;
    1.25 -                continue;
    1.26 -            }
    1.27 -        }
    1.28 -        if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
    1.29 -            put_page_from_l1e(ol1e, current);
    1.30 -        if (unlikely(!get_page_from_l1e(nl1e, current))) {
    1.31 -            MEM_LOG("ptwr: Could not re-validate l1 page\n");
    1.32 -            domain_crash();
    1.33 -        }
    1.34 -        pl1e[i] = nl1e;
    1.35 -    }
    1.36 -    unmap_domain_mem(pl1e);
    1.37 -
    1.38      /* make pt page write protected */
    1.39      if ( unlikely(__get_user(pte, ptep)) ) {
    1.40          MEM_LOG("ptwr: Could not read pte at %p\n", ptep);
    1.41 @@ -1679,19 +1656,46 @@ void ptwr_flush(const int which)
    1.42      }
    1.43      PTWR_PRINTK(PP_ALL, ("disconnected_l1va at %p is %08lx\n",
    1.44                           ptep, pte));
    1.45 -    pte = (ptwr_info[cpu].ptinfo[which].pte & PAGE_MASK) |
    1.46 -        (pte & ~(PAGE_MASK|_PAGE_RW));
    1.47 +    pte &= ~_PAGE_RW;
    1.48      if ( unlikely(__put_user(pte, ptep)) ) {
    1.49          MEM_LOG("ptwr: Could not update pte at %p\n", ptep);
    1.50          domain_crash();
    1.51      }
    1.52 +    __flush_tlb_one(ptwr_info[cpu].ptinfo[which].l1va);
    1.53 +    PTWR_PRINTK(PP_ALL, ("disconnected_l1va at %p now %08lx\n",
    1.54 +                         ptep, pte));
    1.55 +
    1.56 +    pl1e = ptwr_info[cpu].ptinfo[which].pl1e;
    1.57 +    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.58 +        l1_pgentry_t ol1e, nl1e;
    1.59 +        ol1e = ptwr_info[cpu].ptinfo[which].page[i];
    1.60 +        nl1e = pl1e[i];
    1.61 +        if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
    1.62 +            continue;
    1.63 +        if (likely(l1_pgentry_val(ol1e) == (l1_pgentry_val(nl1e) | _PAGE_RW))
    1.64 +	    && readonly_page_from_l1e(nl1e))
    1.65 +	    continue;
    1.66 +        if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
    1.67 +            put_page_from_l1e(ol1e, current);
    1.68 +        if (unlikely(!get_page_from_l1e(nl1e, current))) {
    1.69 +            MEM_LOG("ptwr: Could not re-validate l1 page\n");
    1.70 +            domain_crash();
    1.71 +        }
    1.72 +    }
    1.73 +    unmap_domain_mem(pl1e);
    1.74 +
    1.75 +    if (which == PTWR_PT_ACTIVE) {
    1.76 +	/* reconnect l1 page */
    1.77 +	pl2e = &linear_l2_table[ptwr_info[cpu].active_pteidx];
    1.78 +	nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
    1.79 +	update_l2e(pl2e, *pl2e, nl2e);
    1.80 +    }
    1.81  
    1.82      if ( unlikely(current->mm.shadow_mode) )
    1.83      {
    1.84          unsigned long spte;
    1.85          unsigned long sstat = 
    1.86 -            get_shadow_status(&current->mm, 
    1.87 -                              ptwr_info[cpu].ptinfo[which].pte >> PAGE_SHIFT);
    1.88 +            get_shadow_status(&current->mm, pte >> PAGE_SHIFT);
    1.89  
    1.90          if ( sstat & PSH_shadowed ) 
    1.91          { 
    1.92 @@ -1715,10 +1719,6 @@ void ptwr_flush(const int which)
    1.93                     [ptwr_info[cpu].ptinfo[which].l1va>>PAGE_SHIFT]);
    1.94      }
    1.95  
    1.96 -    __flush_tlb_one(ptwr_info[cpu].ptinfo[which].l1va);
    1.97 -    PTWR_PRINTK(PP_ALL, ("disconnected_l1va at %p now %08lx\n",
    1.98 -                         ptep, pte));
    1.99 -
   1.100      ptwr_info[cpu].ptinfo[which].l1va = 0;
   1.101  }
   1.102  
   1.103 @@ -1727,7 +1727,7 @@ int ptwr_do_page_fault(unsigned long add
   1.104      /* write page fault, check if we're trying to modify an l1 page table */
   1.105      unsigned long pte, pfn;
   1.106      struct pfn_info *page;
   1.107 -    l2_pgentry_t *pl2e;
   1.108 +    l2_pgentry_t *pl2e, nl2e;
   1.109      int cpu = smp_processor_id();
   1.110      int which;
   1.111  
   1.112 @@ -1771,8 +1771,13 @@ int ptwr_do_page_fault(unsigned long add
   1.113                  ptwr_flush(which);
   1.114              ptwr_info[cpu].ptinfo[which].l1va = addr | 1;
   1.115  
   1.116 -            if (which == PTWR_PT_ACTIVE)
   1.117 +            if (which == PTWR_PT_ACTIVE) {
   1.118                  ptwr_info[cpu].active_pteidx = va_mask;
   1.119 +		/* disconnect l1 page */
   1.120 +		nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
   1.121 +		update_l2e(pl2e, *pl2e, nl2e);
   1.122 +		flush_tlb();
   1.123 +	    }
   1.124  
   1.125              ptwr_info[cpu].ptinfo[which].pl1e =
   1.126                  map_domain_mem(pfn << PAGE_SHIFT);
   1.127 @@ -1781,10 +1786,7 @@ int ptwr_do_page_fault(unsigned long add
   1.128                     ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.129  
   1.130              /* make pt page writable */
   1.131 -            ptwr_info[cpu].ptinfo[which].pte = pte;
   1.132 -            pte = (virt_to_phys(ptwr_info[cpu].ptinfo[which].page) &
   1.133 -                   PAGE_MASK) | _PAGE_RW | (pte & ~PAGE_MASK);
   1.134 -
   1.135 +            pte |= _PAGE_RW;
   1.136              PTWR_PRINTK(PP_ALL, ("update %p pte to %08lx\n",
   1.137                                   &linear_pg_table[addr>>PAGE_SHIFT], pte));
   1.138              if ( unlikely(__put_user(pte, (unsigned long *)
     2.1 --- a/xen/include/asm-x86/mm.h	Mon Oct 04 13:23:57 2004 +0000
     2.2 +++ b/xen/include/asm-x86/mm.h	Mon Oct 04 14:55:47 2004 +0000
     2.3 @@ -254,7 +254,6 @@ extern vm_assist_info_t vm_assist_info[]
     2.4  typedef struct {
     2.5      unsigned long l1va;
     2.6      l1_pgentry_t *page;
     2.7 -    unsigned long pte;
     2.8      l1_pgentry_t *pl1e;
     2.9  } ptwr_ptinfo_t;
    2.10