ia64/xen-unstable

changeset 2457:1ae6a24623a9

bitkeeper revision 1.1159.1.136 (413ed5baHUBJ5EA2PO0yZ_45_I8a5w)

g/c support for multiple inactive writable pagetables.
Also use consistent names for bookkeeping data.
author cl349@freefall.cl.cam.ac.uk
date Wed Sep 08 09:49:46 2004 +0000 (2004-09-08)
parents 56bea31b70e5
children d3c0c3c96dc0
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	Tue Sep 07 20:24:46 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Wed Sep 08 09:49:46 2004 +0000
     1.3 @@ -1486,8 +1486,8 @@ 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 = ENTRIES_PER_L2_PAGETABLE,
     1.8 -          .writable_idx = 0,
     1.9 +          .disconnected_pteidx = -1,
    1.10 +          .writable_l1va = 0,
    1.11        }
    1.12      };
    1.13  
    1.14 @@ -1498,7 +1498,7 @@ int ptwr_debug = 0;
    1.15  #define PTWR_PRINTK(x)
    1.16  #endif
    1.17  
    1.18 -void ptwr_reconnect_disconnected(unsigned long addr)
    1.19 +void ptwr_reconnect_disconnected(void)
    1.20  {
    1.21      unsigned long pte;
    1.22      unsigned long pfn;
    1.23 @@ -1508,11 +1508,11 @@ void ptwr_reconnect_disconnected(unsigne
    1.24      int cpu = smp_processor_id();
    1.25      int i;
    1.26      unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.27 -        [ptwr_info[cpu].writable_l1>>PAGE_SHIFT];
    1.28 +        [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT];
    1.29  
    1.30 -    PTWR_PRINTK(("[A] page fault in disconn space: addr %08lx space %08lx\n",
    1.31 -                 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    1.32 -    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
    1.33 +    PTWR_PRINTK(("[A] page fault in disconn space %08lx\n",
    1.34 +                 ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT));
    1.35 +    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx];
    1.36  
    1.37      if (__get_user(pte, writable_pte)) {
    1.38          MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.39 @@ -1558,21 +1558,21 @@ void ptwr_reconnect_disconnected(unsigne
    1.40                   frame_table[pfn].u.inuse.type_info,
    1.41                   frame_table[pfn].count_info,
    1.42                   frame_table[pfn].u.inuse.domain->domain));
    1.43 -    ptwr_info[cpu].disconnected = ENTRIES_PER_L2_PAGETABLE;
    1.44 +    ptwr_info[cpu].disconnected_pteidx = -1;
    1.45      /* make pt page write protected */
    1.46      if (__get_user(pte, writable_pte)) {
    1.47          MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.48          domain_crash();
    1.49      }
    1.50 -    PTWR_PRINTK(("[A] writable_l1 at %p is %08lx\n",
    1.51 +    PTWR_PRINTK(("[A] disconnected_l1va at %p is %08lx\n",
    1.52                   writable_pte, pte));
    1.53      pte &= ~_PAGE_RW;
    1.54      if (__put_user(pte, writable_pte)) {
    1.55          MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
    1.56          domain_crash();
    1.57      }
    1.58 -    __flush_tlb_one(ptwr_info[cpu].writable_l1);
    1.59 -    PTWR_PRINTK(("[A] writable_l1 at %p now %08lx\n",
    1.60 +    __flush_tlb_one(ptwr_info[cpu].disconnected_l1va);
    1.61 +    PTWR_PRINTK(("[A] disconnected_l1va at %p now %08lx\n",
    1.62                   writable_pte, pte));
    1.63      /* and try again */
    1.64      return;
    1.65 @@ -1584,48 +1584,47 @@ void ptwr_flush_inactive(void)
    1.66      struct pfn_info *page;
    1.67      l1_pgentry_t *pl1e;
    1.68      int cpu = smp_processor_id();
    1.69 -    int i, idx;
    1.70 +    int i;
    1.71 +
    1.72 +    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.73 +        [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT];
    1.74 +    if (__get_user(pte, writable_pte)) {
    1.75 +        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.76 +        domain_crash();
    1.77 +    }
    1.78 +    pfn = pte >> PAGE_SHIFT;
    1.79 +    page = &frame_table[pfn];
    1.80 +    PTWR_PRINTK(("[I] alloc l1 page %p\n", page));
    1.81  
    1.82 -    for (idx = 0; idx < ptwr_info[cpu].writable_idx; idx++) {
    1.83 -        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    1.84 -            [ptwr_info[cpu].writables[idx]>>PAGE_SHIFT];
    1.85 -        if (__get_user(pte, writable_pte)) {
    1.86 -            MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
    1.87 +    pl1e = map_domain_mem(pfn << PAGE_SHIFT);
    1.88 +    for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    1.89 +        l1_pgentry_t ol1e, nl1e;
    1.90 +        ol1e = ptwr_info[cpu].writable_page[i];
    1.91 +        nl1e = pl1e[i];
    1.92 +        if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
    1.93 +            continue;
    1.94 +        if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
    1.95 +            put_page_from_l1e(ol1e, current);
    1.96 +        if (unlikely(!get_page_from_l1e(nl1e, current))) {
    1.97 +            MEM_LOG("ptwr: Could not re-validate l1 page\n");
    1.98              domain_crash();
    1.99          }
   1.100 -        pfn = pte >> PAGE_SHIFT;
   1.101 -        page = &frame_table[pfn];
   1.102 -        PTWR_PRINTK(("[I] alloc l1 page %p\n", page));
   1.103 +    }
   1.104 +    unmap_domain_mem(pl1e);
   1.105  
   1.106 -        pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.107 -        for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   1.108 -            l1_pgentry_t ol1e, nl1e;
   1.109 -            ol1e = ptwr_info[cpu].writable_page[idx][i];
   1.110 -            nl1e = pl1e[i];
   1.111 -            if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)))
   1.112 -                continue;
   1.113 -            if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
   1.114 -                put_page_from_l1e(ol1e, current);
   1.115 -            if (unlikely(!get_page_from_l1e(nl1e, current))) {
   1.116 -                MEM_LOG("ptwr: Could not re-validate l1 page\n");
   1.117 -                domain_crash();
   1.118 -            }
   1.119 -        }
   1.120 -        unmap_domain_mem(pl1e);
   1.121 +    /* make pt page writable */
   1.122 +    PTWR_PRINTK(("[I] disconnected_l1va at %p is %08lx\n",
   1.123 +                 writable_pte, pte));
   1.124 +    pte &= ~_PAGE_RW;
   1.125 +    if (__put_user(pte, writable_pte)) {
   1.126 +        MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.127 +        domain_crash();
   1.128 +    }
   1.129 +    __flush_tlb_one(ptwr_info[cpu].writable_l1va);
   1.130 +    PTWR_PRINTK(("[I] disconnected_l1va at %p now %08lx\n",
   1.131 +                 writable_pte, pte));
   1.132  
   1.133 -        /* make pt page writable */
   1.134 -        PTWR_PRINTK(("[I] writable_l1 at %p is %08lx\n",
   1.135 -                     writable_pte, pte));
   1.136 -        pte &= ~_PAGE_RW;
   1.137 -        if (__put_user(pte, writable_pte)) {
   1.138 -            MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
   1.139 -            domain_crash();
   1.140 -        }
   1.141 -        __flush_tlb_one(ptwr_info[cpu].writables[idx]);
   1.142 -        PTWR_PRINTK(("[I] writable_l1 at %p now %08lx\n",
   1.143 -                     writable_pte, pte));
   1.144 -    }
   1.145 -    ptwr_info[cpu].writable_idx = 0;
   1.146 +    ptwr_info[cpu].writable_l1va = 0;
   1.147  }
   1.148  
   1.149  int ptwr_do_page_fault(unsigned long addr)
   1.150 @@ -1669,24 +1668,21 @@ int ptwr_do_page_fault(unsigned long add
   1.151                  PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page,
   1.152                               page->u.inuse.type_info,
   1.153                               page->count_info));
   1.154 -                if (ptwr_info[cpu].writable_idx == PTWR_NR_WRITABLES)
   1.155 +                if (ptwr_info[cpu].writable_l1va)
   1.156                      ptwr_flush_inactive();
   1.157 -                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] = addr;
   1.158 +                ptwr_info[cpu].writable_l1va = addr | 1;
   1.159  
   1.160                  pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   1.161 -                memcpy(&ptwr_info[cpu].writable_page[
   1.162 -                           ptwr_info[cpu].writable_idx][0],
   1.163 +                memcpy(&ptwr_info[cpu].writable_page[0],
   1.164                         pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   1.165                  unmap_domain_mem(pl1e);
   1.166 -
   1.167 -                ptwr_info[cpu].writable_idx++;
   1.168              }
   1.169              else
   1.170              {
   1.171                  l2_pgentry_t nl2e;
   1.172                  l1_pgentry_t *pl1e;
   1.173 -                if ( ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE )
   1.174 -                    ptwr_reconnect_disconnected(addr);
   1.175 +                if ( ptwr_info[cpu].disconnected_pteidx >= 0 )
   1.176 +                    ptwr_reconnect_disconnected();
   1.177                  PTWR_PRINTK(("[A]    pl2e %p l2e %08lx pfn %08lx "
   1.178                               "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.179                               l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   1.180 @@ -1699,14 +1695,14 @@ int ptwr_do_page_fault(unsigned long add
   1.181                  nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
   1.182                  update_l2e(pl2e, *pl2e, nl2e);
   1.183  
   1.184 -                ptwr_info[cpu].disconnected =
   1.185 +                ptwr_info[cpu].disconnected_pteidx =
   1.186                      (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   1.187                  PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              "
   1.188                               "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   1.189                               frame_table[pfn].u.inuse.type_info,
   1.190                               frame_table[pfn].count_info,
   1.191                               frame_table[pfn].u.inuse.domain->domain));
   1.192 -                ptwr_info[cpu].writable_l1 = addr;
   1.193 +                ptwr_info[cpu].disconnected_l1va = addr;
   1.194                  pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) <<
   1.195                                        PAGE_SHIFT);
   1.196                  memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e,
   1.197 @@ -1739,34 +1735,31 @@ void ptwr_status(void)
   1.198      l2_pgentry_t *pl2e;
   1.199      int cpu = smp_processor_id();
   1.200  
   1.201 -    for ( i = 0; i < ptwr_info[cpu].writable_idx; i++ )
   1.202 -    {
   1.203 -        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.204 -            [ptwr_info[cpu].writables[i]>>PAGE_SHIFT];
   1.205 +    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   1.206 +        [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT];
   1.207  
   1.208 -        if ( __get_user(pte, writable_pte) ) {
   1.209 -            MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.210 -            domain_crash();
   1.211 -        }
   1.212 -
   1.213 -        pfn = pte >> PAGE_SHIFT;
   1.214 -        page = &frame_table[pfn];
   1.215 -        printk("need to alloc l1 page %p\n", page);
   1.216 -        /* make pt page writable */
   1.217 -        printk("need to make read-only l1-page at %p is %08lx\n",
   1.218 -               writable_pte, pte);
   1.219 +    if ( __get_user(pte, writable_pte) ) {
   1.220 +        MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte);
   1.221 +        domain_crash();
   1.222      }
   1.223  
   1.224 -    if ( ptwr_info[cpu].disconnected == ENTRIES_PER_L2_PAGETABLE )
   1.225 +    pfn = pte >> PAGE_SHIFT;
   1.226 +    page = &frame_table[pfn];
   1.227 +    printk("need to alloc l1 page %p\n", page);
   1.228 +    /* make pt page writable */
   1.229 +    printk("need to make read-only l1-page at %p is %08lx\n",
   1.230 +           writable_pte, pte);
   1.231 +
   1.232 +    if ( ptwr_info[cpu].disconnected_pteidx < 0 )
   1.233          return;
   1.234  
   1.235      printk("disconnected space: space %08lx\n",
   1.236 -           ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT);
   1.237 -    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
   1.238 +           ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT);
   1.239 +    pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx];
   1.240  
   1.241 -    if ( __get_user(pte, (unsigned long *)ptwr_info[cpu].writable_l1) ) {
   1.242 +    if ( __get_user(pte, (unsigned long *)ptwr_info[cpu].disconnected_l1va) ) {
   1.243          MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *)
   1.244 -                ptwr_info[cpu].writable_l1);
   1.245 +                ptwr_info[cpu].disconnected_l1va);
   1.246          domain_crash();
   1.247      }
   1.248      pfn = pte >> PAGE_SHIFT;
     2.1 --- a/xen/arch/x86/traps.c	Tue Sep 07 20:24:46 2004 +0000
     2.2 +++ b/xen/arch/x86/traps.c	Wed Sep 08 09:49:46 2004 +0000
     2.3 @@ -351,9 +351,10 @@ 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) == ptwr_info[cpu].disconnected ))
     2.8 +        if ( unlikely((addr >> L2_PAGETABLE_SHIFT) ==
     2.9 +                      ptwr_info[cpu].disconnected_pteidx ))
    2.10          {
    2.11 -            ptwr_reconnect_disconnected(addr);
    2.12 +            ptwr_reconnect_disconnected();
    2.13              return;
    2.14          }
    2.15  
     3.1 --- a/xen/include/asm-x86/mm.h	Tue Sep 07 20:24:46 2004 +0000
     3.2 +++ b/xen/include/asm-x86/mm.h	Wed Sep 08 09:49:46 2004 +0000
     3.3 @@ -370,14 +370,12 @@ extern vm_assist_info_t vm_assist_info[]
     3.4  
     3.5  
     3.6  /* Writable Pagetables */
     3.7 -#define	PTWR_NR_WRITABLES 1
     3.8  typedef struct {
     3.9 -    unsigned long disconnected;
    3.10 +    long disconnected_pteidx;
    3.11      l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE];
    3.12 -    unsigned long writable_l1;
    3.13 -    unsigned long writables[PTWR_NR_WRITABLES];
    3.14 -    int writable_idx;
    3.15 -    l1_pgentry_t writable_page[PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE];
    3.16 +    unsigned long disconnected_l1va;
    3.17 +    unsigned long writable_l1va;
    3.18 +    l1_pgentry_t writable_page[ENTRIES_PER_L1_PAGETABLE];
    3.19  } __cacheline_aligned ptwr_info_t;
    3.20  
    3.21  extern ptwr_info_t ptwr_info[];
    3.22 @@ -385,19 +383,19 @@ extern ptwr_info_t ptwr_info[];
    3.23  #define PTWR_CLEANUP_ACTIVE	1
    3.24  #define PTWR_CLEANUP_INACTIVE	2
    3.25  
    3.26 -void ptwr_reconnect_disconnected(unsigned long addr);
    3.27 +void ptwr_reconnect_disconnected(void);
    3.28  void ptwr_flush_inactive(void);
    3.29  int ptwr_do_page_fault(unsigned long);
    3.30  
    3.31 -#define __cleanup_writable_pagetable(_what)                               \
    3.32 -do {                                                                      \
    3.33 -    int cpu = smp_processor_id();                                         \
    3.34 -    if ((_what) & PTWR_CLEANUP_ACTIVE)                                    \
    3.35 -        if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE)      \
    3.36 -            ptwr_reconnect_disconnected(0L);                              \
    3.37 -    if ((_what) & PTWR_CLEANUP_INACTIVE)                                  \
    3.38 -        if (ptwr_info[cpu].writable_idx)                                  \
    3.39 -            ptwr_flush_inactive();                                        \
    3.40 +#define __cleanup_writable_pagetable(_what)                                 \
    3.41 +do {                                                                        \
    3.42 +    int cpu = smp_processor_id();                                           \
    3.43 +    if ((_what) & PTWR_CLEANUP_ACTIVE)                                      \
    3.44 +        if (ptwr_info[cpu].disconnected_pteidx >= 0)                        \
    3.45 +            ptwr_reconnect_disconnected();                                  \
    3.46 +    if ((_what) & PTWR_CLEANUP_INACTIVE)                                    \
    3.47 +        if (ptwr_info[cpu].writable_l1va)                                   \
    3.48 +            ptwr_flush_inactive();                                          \
    3.49  } while ( 0 )
    3.50  
    3.51  #define cleanup_writable_pagetable(_d, _w)                                \