ia64/xen-unstable

changeset 4192:e38db244d654

bitkeeper revision 1.1236.32.10 (4239772aZ9Ayf3Cwr_6ubXtSI1oZ9Q)

Initial commit for trying to get a translated dom0 up and running.

Signed-off-by: michael.fetterman@cl.cam.ac.uk
author mafetter@fleming.research
date Thu Mar 17 12:25:14 2005 +0000 (2005-03-17)
parents d617bb4a2907
children 7f9cdb03e7fd
files xen/arch/x86/audit.c xen/arch/x86/domain.c xen/arch/x86/mm.c xen/arch/x86/shadow.c xen/arch/x86/traps.c xen/arch/x86/vmx_io.c xen/arch/x86/x86_32/domain_build.c xen/arch/x86/x86_64/domain_build.c xen/include/asm-x86/domain.h xen/include/asm-x86/mm.h xen/include/asm-x86/shadow.h xen/include/xen/perfc_defn.h
line diff
     1.1 --- a/xen/arch/x86/audit.c	Wed Mar 16 01:17:37 2005 +0000
     1.2 +++ b/xen/arch/x86/audit.c	Thu Mar 17 12:25:14 2005 +0000
     1.3 @@ -36,6 +36,7 @@ static int ttot=0, ctot=0, io_mappings=0
     1.4  static int l1, l2, oos_count, page_count;
     1.5  
     1.6  #define FILE_AND_LINE 0
     1.7 +//#define MFN_TO_WATCH 0x4700
     1.8  
     1.9  #if FILE_AND_LINE
    1.10  #define adjust(_p, _a) _adjust((_p), (_a), __FILE__, __LINE__)
    1.11 @@ -51,9 +52,17 @@ int audit_adjust_pgtables(struct domain 
    1.12  {
    1.13      int errors = 0;
    1.14      int shadow_enabled = shadow_mode_enabled(d) ? 1 : 0;
    1.15 +    int l2limit;
    1.16  
    1.17      void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS)
    1.18      {
    1.19 +#ifdef MFN_TO_WATCH
    1.20 +        if (page_to_pfn(page) == MFN_TO_WATCH)
    1.21 +        {
    1.22 +            APRINTK("adjust(mfn=%p, dir=%d, adjtype=%d) MFN_TO_WATCH",
    1.23 +                    page_to_pfn(page), dir, adjtype);
    1.24 +        }
    1.25 +#endif
    1.26          if ( adjtype )
    1.27          {
    1.28              // adjust the type count
    1.29 @@ -97,7 +106,7 @@ int audit_adjust_pgtables(struct domain 
    1.30  
    1.31          if ( count < 0 )
    1.32          {
    1.33 -            APRINTK("Audit %d: general count went below zero pfn=%x t=%x ot=%x",
    1.34 +            APRINTK("Audit %d: general count went below zero mfn=%x t=%x ot=%x",
    1.35                      d->id, page-frame_table,
    1.36                      page->u.inuse.type_info,
    1.37                      page->tlbflush_timestamp);
    1.38 @@ -105,7 +114,7 @@ int audit_adjust_pgtables(struct domain 
    1.39          }
    1.40          else if ( (count & ~PGT_count_mask) != 0 )
    1.41          {
    1.42 -            APRINTK("Audit %d: general count overflowed pfn=%x t=%x ot=%x",
    1.43 +            APRINTK("Audit %d: general count overflowed mfn=%x t=%x ot=%x",
    1.44                      d->id, page-frame_table,
    1.45                      page->u.inuse.type_info,
    1.46                      page->tlbflush_timestamp);
    1.47 @@ -115,17 +124,12 @@ int audit_adjust_pgtables(struct domain 
    1.48              page->count_info += dir;
    1.49      }
    1.50  
    1.51 -    void adjust_l2_page(unsigned long mfn, int adjtype)
    1.52 +    void adjust_l2_page(unsigned long mfn)
    1.53      {
    1.54          unsigned long *pt = map_domain_mem(mfn << PAGE_SHIFT);
    1.55 -        int i, limit;
    1.56 +        int i;
    1.57  
    1.58 -        if ( shadow_mode_external(d) )
    1.59 -            limit = L2_PAGETABLE_ENTRIES;
    1.60 -        else
    1.61 -            limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
    1.62 -
    1.63 -        for ( i = 0; i < limit; i++ )
    1.64 +        for ( i = 0; i < l2limit; i++ )
    1.65          {
    1.66              if ( pt[i] & _PAGE_PRESENT )
    1.67              {
    1.68 @@ -180,7 +184,61 @@ int audit_adjust_pgtables(struct domain 
    1.69                      }
    1.70                  }
    1.71  
    1.72 -                adjust(l1page, adjtype);
    1.73 +                adjust(l1page, !shadow_enabled);
    1.74 +            }
    1.75 +        }
    1.76 +
    1.77 +        if ( shadow_mode_translate(d) && !shadow_mode_external(d) )
    1.78 +        {
    1.79 +            unsigned long hl2mfn =
    1.80 +                pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT;
    1.81 +            struct pfn_info *hl2page = pfn_to_page(hl2mfn);
    1.82 +            adjust(hl2page, 0);
    1.83 +        }
    1.84 +
    1.85 +        unmap_domain_mem(pt);
    1.86 +    }
    1.87 +
    1.88 +    void adjust_hl2_page(unsigned long hl2mfn)
    1.89 +    {
    1.90 +        unsigned long *pt = map_domain_mem(hl2mfn << PAGE_SHIFT);
    1.91 +        int i;
    1.92 +
    1.93 +        for ( i = 0; i < l2limit; i++ )
    1.94 +        {
    1.95 +            if ( pt[i] & _PAGE_PRESENT )
    1.96 +            {
    1.97 +                unsigned long gmfn = pt[i] >> PAGE_SHIFT;
    1.98 +                struct pfn_info *gpage = pfn_to_page(gmfn);
    1.99 +
   1.100 +                if ( gmfn < 0x100 )
   1.101 +                {
   1.102 +                    lowmem_mappings++;
   1.103 +                    continue;
   1.104 +                }
   1.105 +
   1.106 +                if ( gmfn > max_page )
   1.107 +                {
   1.108 +                    io_mappings++;
   1.109 +                    continue;
   1.110 +                }
   1.111 +
   1.112 +                if ( noisy )
   1.113 +                {
   1.114 +                    if ( page_get_owner(gpage) != d )
   1.115 +                    {
   1.116 +                        printk("Audit %d: [hl2mfn=%p,i=%x] Skip foreign page "
   1.117 +                               "dom=%p (id=%d) mfn=%p c=%08x t=%08x\n",
   1.118 +                               d->id, hl2mfn, i,
   1.119 +                               page_get_owner(gpage),
   1.120 +                               page_get_owner(gpage)->id,
   1.121 +                               gmfn,
   1.122 +                               gpage->count_info,
   1.123 +                               gpage->u.inuse.type_info);
   1.124 +                        continue;
   1.125 +                    }
   1.126 +                }
   1.127 +                adjust(gpage, 0);
   1.128              }
   1.129          }
   1.130  
   1.131 @@ -281,13 +339,17 @@ int audit_adjust_pgtables(struct domain 
   1.132                  case PGT_snapshot:
   1.133                      break;
   1.134                  case PGT_l1_shadow:
   1.135 -                case PGT_hl2_shadow:
   1.136                      adjust_l1_page(smfn);
   1.137                      if ( page->u.inuse.type_info & PGT_pinned )
   1.138                          adjust(page, 0);
   1.139                      break;
   1.140 +                case PGT_hl2_shadow:
   1.141 +                    adjust_hl2_page(smfn);
   1.142 +                    if ( page->u.inuse.type_info & PGT_pinned )
   1.143 +                        adjust(page, 0);
   1.144 +                    break;
   1.145                  case PGT_l2_shadow:
   1.146 -                    adjust_l2_page(smfn, 0);
   1.147 +                    adjust_l2_page(smfn);
   1.148                      if ( page->u.inuse.type_info & PGT_pinned )
   1.149                          adjust(page, 0);
   1.150                      break;
   1.151 @@ -317,6 +379,9 @@ int audit_adjust_pgtables(struct domain 
   1.152              if ( !(oos->writable_pl1e & (sizeof(l1_pgentry_t)-1)) )
   1.153                  adjust(pfn_to_page(oos->writable_pl1e >> PAGE_SHIFT), 0);
   1.154  
   1.155 +            if ( oos->snapshot_mfn != SHADOW_SNAPSHOT_ELSEWHERE )
   1.156 +                adjust(pfn_to_page(oos->snapshot_mfn), 0);
   1.157 +
   1.158              oos = oos->next;
   1.159              oos_count++;
   1.160          }
   1.161 @@ -400,7 +465,7 @@ int audit_adjust_pgtables(struct domain 
   1.162                      adjust(page, 1);
   1.163  
   1.164                  if ( page->u.inuse.type_info & PGT_validated )
   1.165 -                    adjust_l2_page(mfn, 1);
   1.166 +                    adjust_l2_page(mfn);
   1.167  
   1.168                  break;
   1.169  
   1.170 @@ -468,6 +533,11 @@ int audit_adjust_pgtables(struct domain 
   1.171          }
   1.172      }
   1.173  
   1.174 +    if ( shadow_mode_external(d) )
   1.175 +        l2limit = L2_PAGETABLE_ENTRIES;
   1.176 +    else
   1.177 +        l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
   1.178 +
   1.179      adjust_for_pgtbase();
   1.180  
   1.181      adjust_guest_pages();
   1.182 @@ -484,7 +554,7 @@ int audit_adjust_pgtables(struct domain 
   1.183  
   1.184  #ifndef NDEBUG
   1.185  
   1.186 -void _audit_domain(struct domain *d, int flags, const char *file, int line)
   1.187 +void _audit_domain(struct domain *d, int flags)
   1.188  {
   1.189      void scan_for_pfn_in_mfn(struct domain *d, unsigned long xmfn,
   1.190                               unsigned long mfn)
   1.191 @@ -569,6 +639,14 @@ void _audit_domain(struct domain *d, int
   1.192      struct pfn_info *page;
   1.193      int errors = 0;
   1.194  
   1.195 +    if ( (d != current->domain) && shadow_mode_translate(d) )
   1.196 +    {
   1.197 +        printk("skipping audit domain of translated domain %d "
   1.198 +               "from other context\n",
   1.199 +               d->id);
   1.200 +        return;
   1.201 +    }
   1.202 +
   1.203      if ( d != current->domain )
   1.204          domain_pause(d);
   1.205      synchronise_pagetables(~0UL);
   1.206 @@ -740,11 +818,10 @@ void _audit_domain(struct domain *d, int
   1.207                  page_type = a->gpfn_and_flags & PGT_type_mask;
   1.208  
   1.209                  switch ( page_type ) {
   1.210 -                case PGT_snapshot:
   1.211 -                    // XXX -- what should we check here?
   1.212 -                    break;
   1.213                  case PGT_l1_shadow:
   1.214                  case PGT_l2_shadow:
   1.215 +                case PGT_hl2_shadow:
   1.216 +                case PGT_snapshot:
   1.217                      if ( ((page->u.inuse.type_info & PGT_type_mask) != page_type ) ||
   1.218                           (page->count_info != 0) )
   1.219                      {
   1.220 @@ -756,7 +833,6 @@ void _audit_domain(struct domain *d, int
   1.221                      }
   1.222                      break;
   1.223  
   1.224 -                case PGT_hl2_shadow: // haven't thought about this case yet.
   1.225                  default:
   1.226                      BUG();
   1.227                      break;
   1.228 @@ -781,9 +857,9 @@ void _audit_domain(struct domain *d, int
   1.229      spin_unlock(&d->page_alloc_lock);
   1.230  
   1.231      if ( !(flags & AUDIT_QUIET) )
   1.232 -        printk("Audit dom%d (%s:%d) Done. "
   1.233 +        printk("Audit dom%d Done. "
   1.234                 "pages=%d oos=%d l1=%d l2=%d ctot=%d ttot=%d\n",
   1.235 -               d->id, file, line, page_count, oos_count, l1, l2, ctot, ttot );
   1.236 +               d->id, page_count, oos_count, l1, l2, ctot, ttot);
   1.237  
   1.238      if ( !(flags & AUDIT_ALREADY_LOCKED) )
   1.239          shadow_unlock(d);
     2.1 --- a/xen/arch/x86/domain.c	Wed Mar 16 01:17:37 2005 +0000
     2.2 +++ b/xen/arch/x86/domain.c	Thu Mar 17 12:25:14 2005 +0000
     2.3 @@ -344,8 +344,6 @@ static int vmx_final_setup_guest(struct 
     2.4          shadow_mode_enable(ed->domain, SHM_enable|SHM_translate|SHM_external);
     2.5      }
     2.6  
     2.7 -    update_pagetables(ed);
     2.8 -
     2.9      return 0;
    2.10  
    2.11  out:
    2.12 @@ -416,7 +414,7 @@ int arch_final_setup_guest(
    2.13      ed->arch.failsafe_address  = c->failsafe_callback_eip;
    2.14  
    2.15      phys_basetab = c->pt_base;
    2.16 -    ed->arch.guest_table = ed->arch.phys_table = mk_pagetable(phys_basetab);
    2.17 +    ed->arch.guest_table = mk_pagetable(phys_basetab);
    2.18  
    2.19      if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
    2.20                              PGT_base_page_table) )
    2.21 @@ -435,8 +433,22 @@ int arch_final_setup_guest(
    2.22      }
    2.23  
    2.24  #ifdef CONFIG_VMX
    2.25 -    if (c->flags & ECF_VMX_GUEST)
    2.26 -        return vmx_final_setup_guest(ed, c);
    2.27 +    if ( c->flags & ECF_VMX_GUEST )
    2.28 +    {
    2.29 +        int error;
    2.30 +
    2.31 +        // VMX uses the initially provided page tables as the P2M map.
    2.32 +        //
    2.33 +        // XXX: This creates a security issue -- Xen can't necessarily
    2.34 +        //      trust the VMX domain builder.  Xen should validate this
    2.35 +        //      page table, and/or build the table itself, or ???
    2.36 +        //
    2.37 +        if ( !pagetable_val(d->arch.phys_table) )
    2.38 +            d->arch.phys_table = ed->arch.guest_table;
    2.39 +
    2.40 +        if ( (error = vmx_final_setup_guest(ed, c)) )
    2.41 +            return error;
    2.42 +    }
    2.43  #endif
    2.44  
    2.45      update_pagetables(ed);
     3.1 --- a/xen/arch/x86/mm.c	Wed Mar 16 01:17:37 2005 +0000
     3.2 +++ b/xen/arch/x86/mm.c	Thu Mar 17 12:25:14 2005 +0000
     3.3 @@ -268,7 +268,7 @@ int map_ldt_shadow_page(unsigned int off
     3.4      if ( unlikely(shadow_mode_enabled(d)) )
     3.5      {
     3.6          shadow_lock(d);
     3.7 -        shadow_remove_all_write_access(d, PGT_l1_shadow, PGT_l1_shadow, gpfn);
     3.8 +        shadow_remove_all_write_access(d, PGT_l1_shadow, PGT_l1_shadow, gpfn, gmfn);
     3.9      }
    3.10  
    3.11      res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
     4.1 --- a/xen/arch/x86/shadow.c	Wed Mar 16 01:17:37 2005 +0000
     4.2 +++ b/xen/arch/x86/shadow.c	Thu Mar 17 12:25:14 2005 +0000
     4.3 @@ -71,10 +71,10 @@ shadow_promote(struct domain *d, unsigne
     4.4          max_type = PGT_l1_shadow;
     4.5      }
     4.6      FSH_LOG("shadow_promote gpfn=%p gmfn=%p nt=%p min=%p max=%p",
     4.7 -            gmfn, gmfn, new_type, min_type, max_type);
     4.8 +            gpfn, gmfn, new_type, min_type, max_type);
     4.9  
    4.10      if ( min_type <= max_type )
    4.11 -        shadow_remove_all_write_access(d, min_type, max_type, gpfn);
    4.12 +        shadow_remove_all_write_access(d, min_type, max_type, gpfn, gmfn);
    4.13  
    4.14      // To convert this page to use as a page table, the writable count
    4.15      // should now be zero.  Test this by grabbing the page as an page table,
    4.16 @@ -257,7 +257,7 @@ alloc_shadow_page(struct domain *d,
    4.17          break;
    4.18      }
    4.19  
    4.20 -    set_shadow_status(d, gpfn, smfn, psh_type);
    4.21 +    set_shadow_status(d, gpfn, gmfn, smfn, psh_type);
    4.22  
    4.23      if ( pin )
    4.24          shadow_pin(smfn);
    4.25 @@ -567,7 +567,7 @@ static void alloc_monitor_pagetable(stru
    4.26  
    4.27      // map the phys_to_machine map into the Read-Only MPT space for this domain
    4.28      mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
    4.29 -        mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR);
    4.30 +        mk_l2_pgentry(pagetable_val(d->arch.phys_table) | __PAGE_HYPERVISOR);
    4.31  
    4.32      ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
    4.33      ed->arch.monitor_vtable = mpl2e;
    4.34 @@ -607,9 +607,79 @@ void free_monitor_pagetable(struct exec_
    4.35      ed->arch.monitor_vtable = 0;
    4.36  }
    4.37  
    4.38 +static int
    4.39 +alloc_p2m_table(struct domain *d)
    4.40 +{
    4.41 +    struct list_head *list_ent;
    4.42 +    struct pfn_info *page, *l2page, *l1page;
    4.43 +    l2_pgentry_t *l2, l2e, last_l2e = mk_l2_pgentry(0);
    4.44 +    l1_pgentry_t *l1 = NULL;
    4.45 +    unsigned long va, mfn, pfn;
    4.46 +
    4.47 +    l2page = alloc_domheap_page(NULL);
    4.48 +    if ( !l2page )
    4.49 +        return 0;
    4.50 +    d->arch.phys_table = mk_pagetable(page_to_pfn(l2page) << PAGE_SHIFT);
    4.51 +    l2 = map_domain_mem(page_to_pfn(l2page) << PAGE_SHIFT);
    4.52 +    memset(l2, 0, PAGE_SIZE);
    4.53 +
    4.54 +    list_ent = d->page_list.next;
    4.55 +    while ( list_ent != &d->page_list )
    4.56 +    {
    4.57 +        page = list_entry(list_ent, struct pfn_info, list);
    4.58 +        mfn = page_to_pfn(page);
    4.59 +        pfn = machine_to_phys_mapping[mfn];
    4.60 +        ASSERT(pfn != INVALID_M2P_ENTRY);
    4.61 +        ASSERT(pfn < (1u<<20));
    4.62 +
    4.63 +        va = pfn << PAGE_SHIFT;
    4.64 +        if ( !l2_pgentry_val(l2e = l2[l2_table_offset(va)]) )
    4.65 +        {
    4.66 +            l1page = alloc_domheap_page(NULL);
    4.67 +            if ( !l1page )
    4.68 +                return 0;
    4.69 +            l2e = l2[l2_table_offset(va)] =
    4.70 +                mk_l2_pgentry((page_to_pfn(l1page) << PAGE_SHIFT) |
    4.71 +                              __PAGE_HYPERVISOR);
    4.72 +        }
    4.73 +
    4.74 +        if ( l2_pgentry_val(last_l2e) != l2_pgentry_val(l2e) )
    4.75 +        {
    4.76 +            if ( l1 )
    4.77 +                unmap_domain_mem(l1);
    4.78 +            l1 = map_domain_mem(l2_pgentry_val(l2e) & PAGE_MASK);
    4.79 +            last_l2e = l2e;
    4.80 +        }
    4.81 +
    4.82 +        l1[l1_table_offset(va)] = mk_l1_pgentry((mfn << PAGE_SHIFT) |
    4.83 +                                                __PAGE_HYPERVISOR);
    4.84 +        list_ent = page->list.next;
    4.85 +    }
    4.86 +
    4.87 +    if ( l1 )
    4.88 +        unmap_domain_mem(l1);
    4.89 +    unmap_domain_mem(l2);
    4.90 +
    4.91 +    return 1;
    4.92 +}
    4.93 +
    4.94 +static void
    4.95 +free_p2m_table(struct domain *d)
    4.96 +{
    4.97 +    // uh, this needs some work...  :)
    4.98 +    BUG();
    4.99 +}
   4.100 +
   4.101  int __shadow_mode_enable(struct domain *d, unsigned int mode)
   4.102  {
   4.103      struct exec_domain *ed;
   4.104 +    int new_modes = (mode & ~d->arch.shadow_mode);
   4.105 +
   4.106 +    // Gotta be adding something to call this function.
   4.107 +    ASSERT(new_modes);
   4.108 +
   4.109 +    // can't take anything away by calling this function.
   4.110 +    ASSERT(!(d->arch.shadow_mode & ~mode));
   4.111  
   4.112      for_each_exec_domain(d, ed)
   4.113      {
   4.114 @@ -670,8 +740,9 @@ int __shadow_mode_enable(struct domain *
   4.115          }
   4.116      }
   4.117  
   4.118 -    if ( !d->arch.shadow_ht )
   4.119 +    if ( new_modes & SHM_enable )
   4.120      {
   4.121 +        ASSERT( !d->arch.shadow_ht );
   4.122          d->arch.shadow_ht = xmalloc_array(struct shadow_status, shadow_ht_buckets);
   4.123          if ( d->arch.shadow_ht == NULL )
   4.124              goto nomem;
   4.125 @@ -680,8 +751,9 @@ int __shadow_mode_enable(struct domain *
   4.126             shadow_ht_buckets * sizeof(struct shadow_status));
   4.127      }
   4.128  
   4.129 -    if ( shadow_mode_log_dirty(d) && !d->arch.shadow_dirty_bitmap )
   4.130 +    if ( new_modes & SHM_log_dirty )
   4.131      {
   4.132 +        ASSERT( !d->arch.shadow_dirty_bitmap );
   4.133          d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63;
   4.134          d->arch.shadow_dirty_bitmap = 
   4.135              xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size /
   4.136 @@ -695,8 +767,28 @@ int __shadow_mode_enable(struct domain *
   4.137                 d->arch.shadow_dirty_bitmap_size/8);
   4.138      }
   4.139  
   4.140 +    if ( new_modes & SHM_translate )
   4.141 +    {
   4.142 +        if ( !(new_modes & SHM_external) )
   4.143 +        {
   4.144 +            ASSERT( !pagetable_val(d->arch.phys_table) );
   4.145 +            if ( !alloc_p2m_table(d) )
   4.146 +            {
   4.147 +                printk("alloc_p2m_table failed (out-of-memory?)\n");
   4.148 +                goto nomem;
   4.149 +            }
   4.150 +        }
   4.151 +        else
   4.152 +        {
   4.153 +            // external guests provide their own memory for their P2M maps.
   4.154 +            //
   4.155 +            unsigned long mfn = pagetable_val(d->arch.phys_table)>>PAGE_SHIFT;
   4.156 +            ASSERT( d == page_get_owner(&frame_table[mfn]) );
   4.157 +        }
   4.158 +    }
   4.159 +
   4.160      printk("audit1\n");
   4.161 -    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK, __FILE__, __LINE__);
   4.162 +    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK);
   4.163      printk("audit1 done\n");
   4.164  
   4.165      // Get rid of any shadow pages from any previous shadow mode.
   4.166 @@ -704,11 +796,12 @@ int __shadow_mode_enable(struct domain *
   4.167      free_shadow_pages(d);
   4.168  
   4.169      printk("audit2\n");
   4.170 -    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK, __FILE__, __LINE__);
   4.171 +    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK);
   4.172      printk("audit2 done\n");
   4.173  
   4.174      // Turn off writable page tables.
   4.175      // It doesn't mix with shadow mode.
   4.176 +    // And shadow mode offers a superset of functionality.
   4.177      //
   4.178      vm_assist(d, VMASST_CMD_disable, VMASST_TYPE_writable_pagetables);
   4.179  
   4.180 @@ -749,15 +842,27 @@ int __shadow_mode_enable(struct domain *
   4.181      audit_adjust_pgtables(d, 1, 1);
   4.182  
   4.183      printk("audit3\n");
   4.184 -    _audit_domain(d, AUDIT_ALREADY_LOCKED, __FILE__, __LINE__);
   4.185 +    _audit_domain(d, AUDIT_ALREADY_LOCKED);
   4.186      printk("audit3 done\n");
   4.187  
   4.188      return 0;
   4.189  
   4.190   nomem:
   4.191 -    if ( d->arch.shadow_ht != NULL )
   4.192 +    if ( (new_modes & SHM_enable) && (d->arch.shadow_ht != NULL) )
   4.193 +    {
   4.194          xfree(d->arch.shadow_ht);
   4.195 -    d->arch.shadow_ht = NULL;
   4.196 +        d->arch.shadow_ht = NULL;
   4.197 +    }
   4.198 +    if ( (new_modes & SHM_log_dirty) && (d->arch.shadow_dirty_bitmap != NULL) )
   4.199 +    {
   4.200 +        xfree(d->arch.shadow_dirty_bitmap);
   4.201 +        d->arch.shadow_dirty_bitmap = NULL;
   4.202 +    }
   4.203 +    if ( (new_modes & SHM_translate) && !(new_modes & SHM_external) &&
   4.204 +         pagetable_val(d->arch.phys_table) )
   4.205 +    {
   4.206 +        free_p2m_table(d);
   4.207 +    }
   4.208      return -ENOMEM;
   4.209  }
   4.210  
   4.211 @@ -770,6 +875,57 @@ int shadow_mode_enable(struct domain *d,
   4.212      return rc;
   4.213  }
   4.214  
   4.215 +static void
   4.216 +translate_l1pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l1mfn)
   4.217 +{
   4.218 +    int i;
   4.219 +    l1_pgentry_t *l1;
   4.220 +
   4.221 +    l1 = map_domain_mem(l1mfn << PAGE_SHIFT);
   4.222 +    for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
   4.223 +    {
   4.224 +        if ( is_guest_l1_slot(i) &&
   4.225 +             (l1_pgentry_val(l1[i]) & _PAGE_PRESENT) )
   4.226 +        {
   4.227 +            unsigned long mfn = l1_pgentry_val(l1[i]) >> PAGE_SHIFT;
   4.228 +            unsigned long gpfn = __mfn_to_gpfn(d, mfn);
   4.229 +            ASSERT((l1_pgentry_val(p2m[gpfn]) >> PAGE_SHIFT) == mfn);
   4.230 +            l1[i] = mk_l1_pgentry((gpfn << PAGE_SHIFT) |
   4.231 +                                  (l1_pgentry_val(l1[i]) & ~PAGE_MASK));
   4.232 +        }
   4.233 +    }
   4.234 +    unmap_domain_mem(l1);
   4.235 +}
   4.236 +
   4.237 +// This is not general enough to handle arbitrary pagetables
   4.238 +// with shared L1 pages, etc., but it is sufficient for bringing
   4.239 +// up dom0.
   4.240 +//
   4.241 +void
   4.242 +translate_l2pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn)
   4.243 +{
   4.244 +    int i;
   4.245 +    l2_pgentry_t *l2;
   4.246 +
   4.247 +    ASSERT(shadow_mode_translate(d) && !shadow_mode_external(d));
   4.248 +
   4.249 +    l2 = map_domain_mem(l2mfn << PAGE_SHIFT);
   4.250 +    for (i = 0; i < L2_PAGETABLE_ENTRIES; i++)
   4.251 +    {
   4.252 +        if ( is_guest_l2_slot(i) &&
   4.253 +             (l2_pgentry_val(l2[i]) & _PAGE_PRESENT) )
   4.254 +        {
   4.255 +            unsigned long mfn = l2_pgentry_val(l2[i]) >> PAGE_SHIFT;
   4.256 +            unsigned long gpfn = __mfn_to_gpfn(d, mfn);
   4.257 +            ASSERT((l1_pgentry_val(p2m[gpfn]) >> PAGE_SHIFT) == mfn);
   4.258 +            l2[i] = mk_l2_pgentry((gpfn << PAGE_SHIFT) |
   4.259 +                                  (l2_pgentry_val(l2[i]) & ~PAGE_MASK));
   4.260 +            translate_l1pgtable(d, p2m, mfn);
   4.261 +        }
   4.262 +    }
   4.263 +    unmap_domain_mem(l2);
   4.264 +}
   4.265 +
   4.266  static void free_shadow_ht_entries(struct domain *d)
   4.267  {
   4.268      struct shadow_status *x, *n;
   4.269 @@ -1019,6 +1175,42 @@ void vmx_shadow_clear_state(struct domai
   4.270  }
   4.271  
   4.272  static unsigned long
   4.273 +gpfn_to_mfn_safe(struct domain *d, unsigned long gpfn)
   4.274 +{
   4.275 +    ASSERT( shadow_mode_translate(d) );
   4.276 +
   4.277 +    perfc_incrc(gpfn_to_mfn_safe);
   4.278 +
   4.279 +    unsigned long va = gpfn << PAGE_SHIFT;
   4.280 +    unsigned long phystab = pagetable_val(d->arch.phys_table);
   4.281 +    l2_pgentry_t *l2 = map_domain_mem(phystab);
   4.282 +    l2_pgentry_t l2e = l2[l2_table_offset(va)];
   4.283 +    unmap_domain_mem(l2);
   4.284 +    if ( !(l2_pgentry_val(l2e) & _PAGE_PRESENT) )
   4.285 +    {
   4.286 +        printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => 0 l2e=%p\n",
   4.287 +               d->id, gpfn, l2_pgentry_val(l2e));
   4.288 +        return 0;
   4.289 +    }
   4.290 +    unsigned long l1tab = l2_pgentry_val(l2e) & PAGE_MASK;
   4.291 +    l1_pgentry_t *l1 = map_domain_mem(l1tab);
   4.292 +    l1_pgentry_t l1e = l1[l1_table_offset(va)];
   4.293 +    unmap_domain_mem(l1);
   4.294 +
   4.295 +    printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => %p phystab=%p l2e=%p l1tab=%p, l1e=%p\n",
   4.296 +           d->id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, phystab, l2e, l1tab, l1e);
   4.297 +
   4.298 +    if ( !(l1_pgentry_val(l1e) & _PAGE_PRESENT) )
   4.299 +    {
   4.300 +        printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => 0 l1e=%p\n",
   4.301 +               d->id, gpfn, l1_pgentry_val(l1e));
   4.302 +        return 0;
   4.303 +    }
   4.304 +
   4.305 +    return l1_pgentry_val(l1e) >> PAGE_SHIFT;
   4.306 +}
   4.307 +
   4.308 +static unsigned long
   4.309  shadow_hl2_table(struct domain *d, unsigned long gpfn, unsigned long gmfn,
   4.310                  unsigned long smfn)
   4.311  {
   4.312 @@ -1037,9 +1229,7 @@ shadow_hl2_table(struct domain *d, unsig
   4.313  
   4.314      perfc_incrc(shadow_hl2_table_count);
   4.315  
   4.316 -    ASSERT( pagetable_val(current->arch.guest_table) == (gmfn << PAGE_SHIFT) );
   4.317 -    gl2 = current->arch.guest_vtable;
   4.318 -
   4.319 +    gl2 = map_domain_mem(gmfn << PAGE_SHIFT);
   4.320      hl2 = map_domain_mem(hl2mfn << PAGE_SHIFT);
   4.321  
   4.322      if ( shadow_mode_external(d) )
   4.323 @@ -1047,19 +1237,48 @@ shadow_hl2_table(struct domain *d, unsig
   4.324      else
   4.325          limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
   4.326  
   4.327 -    for ( i = 0; i < limit; i++ )
   4.328 +    if ( unlikely(current->domain != d) && !shadow_mode_external(d) )
   4.329      {
   4.330 -        unsigned long gl2e = l2_pgentry_val(gl2[i]);
   4.331 -        unsigned long mfn;
   4.332 -
   4.333 -        if ( gl2e & _PAGE_PRESENT )
   4.334 +        // Can't use __gpfn_to_mfn() if we don't have one of this domain's
   4.335 +        // page tables currently installed.  What a pain in the neck!
   4.336 +        //
   4.337 +        // This isn't common -- it only happens during shadow mode setup
   4.338 +        // and mode changes.
   4.339 +        //
   4.340 +        perfc_incrc(shadow_hl2_other_domain);
   4.341 +        for ( i = 0; i < limit; i++ )
   4.342          {
   4.343 -            mfn = __gpfn_to_mfn(d, gl2e >> PAGE_SHIFT);
   4.344 -            hl2[i] = mk_l1_pgentry((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.345 -            get_page(pfn_to_page(mfn), d);
   4.346 +            unsigned long gl2e = l2_pgentry_val(gl2[i]);
   4.347 +            unsigned long mfn;
   4.348 +
   4.349 +            if ( (gl2e & _PAGE_PRESENT) &&
   4.350 +                 (mfn = gpfn_to_mfn_safe(d, gl2e >> PAGE_SHIFT)) )
   4.351 +            {
   4.352 +                hl2[i] = mk_l1_pgentry((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.353 +                get_page(pfn_to_page(mfn), d);
   4.354 +            }
   4.355 +            else
   4.356 +            {
   4.357 +                hl2[i] = mk_l1_pgentry(0);
   4.358 +            }
   4.359          }
   4.360 -        else
   4.361 -            hl2[i] = mk_l1_pgentry(0);
   4.362 +    }
   4.363 +    else
   4.364 +    {
   4.365 +        for ( i = 0; i < limit; i++ )
   4.366 +        {
   4.367 +            unsigned long gl2e = l2_pgentry_val(gl2[i]);
   4.368 +            unsigned long mfn;
   4.369 +
   4.370 +            if ( (gl2e & _PAGE_PRESENT) &&
   4.371 +                 (mfn = __gpfn_to_mfn(d, gl2e >> PAGE_SHIFT)) )
   4.372 +            {
   4.373 +                hl2[i] = mk_l1_pgentry((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.374 +                get_page(pfn_to_page(mfn), d);
   4.375 +            }
   4.376 +            else
   4.377 +                hl2[i] = mk_l1_pgentry(0);
   4.378 +        }
   4.379      }
   4.380  
   4.381      if ( !shadow_mode_external(d) )
   4.382 @@ -1078,6 +1297,7 @@ shadow_hl2_table(struct domain *d, unsig
   4.383      }
   4.384  
   4.385      unmap_domain_mem(hl2);
   4.386 +    unmap_domain_mem(gl2);
   4.387  
   4.388      return hl2mfn;
   4.389  }
   4.390 @@ -1122,10 +1342,23 @@ static unsigned long shadow_l2_table(
   4.391                 &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
   4.392                 HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
   4.393  
   4.394 +        spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
   4.395 +            mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.396 +
   4.397 +        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
   4.398 +            mk_l2_pgentry(__pa(page_get_owner(
   4.399 +                &frame_table[gmfn])->arch.mm_perdomain_pt) |
   4.400 +                          __PAGE_HYPERVISOR);
   4.401 +
   4.402          if ( shadow_mode_translate(d) ) // NB: not external
   4.403          {
   4.404              unsigned long hl2mfn;
   4.405 -            if ( unlikely(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow)) )
   4.406 +
   4.407 +            spl2e[l2_table_offset(RO_MPT_VIRT_START)] =
   4.408 +                mk_l2_pgentry(pagetable_val(d->arch.phys_table) |
   4.409 +                              __PAGE_HYPERVISOR);
   4.410 +
   4.411 +            if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
   4.412                  hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
   4.413  
   4.414              // shadow_mode_translate (but not external) sl2 tables hold a
   4.415 @@ -1140,14 +1373,6 @@ static unsigned long shadow_l2_table(
   4.416          else
   4.417              spl2e[l2_table_offset(LINEAR_PT_VIRT_START)] =
   4.418                  mk_l2_pgentry((gmfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.419 -
   4.420 -        spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
   4.421 -            mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.422 -
   4.423 -        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
   4.424 -            mk_l2_pgentry(__pa(page_get_owner(
   4.425 -                &frame_table[gmfn])->arch.mm_perdomain_pt) |
   4.426 -                          __PAGE_HYPERVISOR);
   4.427      }
   4.428      else
   4.429      {
   4.430 @@ -1304,7 +1529,7 @@ shadow_alloc_oos_entry(struct domain *d)
   4.431      return f;
   4.432  }
   4.433  
   4.434 -static unsigned long
   4.435 +static inline unsigned long
   4.436  shadow_make_snapshot(
   4.437      struct domain *d, unsigned long gpfn, unsigned long gmfn)
   4.438  {
   4.439 @@ -1554,11 +1779,11 @@ static u32 remove_all_write_access_in_pt
   4.440  }
   4.441  
   4.442  u32 shadow_remove_all_write_access(
   4.443 -    struct domain *d, unsigned min_type, unsigned max_type, unsigned long gpfn)
   4.444 +    struct domain *d, unsigned min_type, unsigned max_type,
   4.445 +    unsigned long gpfn, unsigned long gmfn)
   4.446  {
   4.447      int i;
   4.448      struct shadow_status *a;
   4.449 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
   4.450      unsigned long sl1mfn = __shadow_status(d, gpfn, PGT_l1_shadow);
   4.451      u32 count = 0;
   4.452  
   4.453 @@ -2004,6 +2229,8 @@ void __update_pagetables(struct exec_dom
   4.454  
   4.455          ASSERT( shadow_mode_translate(d) );
   4.456  
   4.457 +        BUG(); // ref counts for hl2mfn and smfn need to be maintained!
   4.458 +
   4.459          mpl2e[l2_table_offset(LINEAR_PT_VIRT_START)] =
   4.460              mk_l2_pgentry((hl2mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   4.461  
   4.462 @@ -2038,10 +2265,10 @@ int shadow_status_noswap;
   4.463  
   4.464  #define FAIL(_f, _a...)                                                      \
   4.465      do {                                                                     \
   4.466 -        printk("XXX %s-FAIL (%d,%d)" _f "\n"                                 \
   4.467 +        printk("XXX %s-FAIL (%d,%d,%d)" _f "\n"                              \
   4.468                 "g=%08lx s=%08lx &g=%08lx &s=%08lx"                           \
   4.469                 " v2m(&g)=%08lx v2m(&s)=%08lx ea=%08lx\n",                    \
   4.470 -               sh_check_name, level, l1_idx, ## _a ,                         \
   4.471 +               sh_check_name, level, l2_idx, l1_idx, ## _a ,                 \
   4.472                 gpte, spte, pgpte, pspte,                                     \
   4.473                 v2m(pgpte), v2m(pspte),                                       \
   4.474                 (l2_idx << L2_PAGETABLE_SHIFT) |                              \
   4.475 @@ -2076,7 +2303,8 @@ static int check_pte(
   4.476      if ( (spte & mask) != (gpte & mask) )
   4.477          FAIL("Corrupt?");
   4.478  
   4.479 -    if ( (spte & _PAGE_DIRTY ) && !(gpte & _PAGE_DIRTY) && !oos_ptes )
   4.480 +    if ( (level == 1) &&
   4.481 +         (spte & _PAGE_DIRTY ) && !(gpte & _PAGE_DIRTY) && !oos_ptes )
   4.482          FAIL("Dirty coherence");
   4.483  
   4.484      if ( (spte & _PAGE_ACCESSED ) && !(gpte & _PAGE_ACCESSED) && !oos_ptes )
   4.485 @@ -2090,23 +2318,28 @@ static int check_pte(
   4.486  
   4.487      if ( (spte & _PAGE_RW ) && !(gpte & _PAGE_RW) && !oos_ptes )
   4.488      {
   4.489 -        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d oos_ptes=%d\n",
   4.490 +        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d "
   4.491 +               "oos_ptes=%d\n",
   4.492                 gpfn, gmfn, smfn,
   4.493                 frame_table[gmfn].u.inuse.type_info,
   4.494                 page_table_page, oos_ptes);
   4.495          FAIL("RW coherence");
   4.496      }
   4.497  
   4.498 -    if ( (spte & _PAGE_RW ) && !((gpte & _PAGE_RW) && (gpte & _PAGE_DIRTY)) && !oos_ptes )
   4.499 +    if ( (level == 1) &&
   4.500 +         (spte & _PAGE_RW ) &&
   4.501 +         !((gpte & _PAGE_RW) && (gpte & _PAGE_DIRTY)) &&
   4.502 +         !oos_ptes )
   4.503      {
   4.504 -        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d oos_ptes=%d\n",
   4.505 +        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d "
   4.506 +               "oos_ptes=%d\n",
   4.507                 gpfn, gmfn, smfn,
   4.508                 frame_table[gmfn].u.inuse.type_info,
   4.509                 page_table_page, oos_ptes);
   4.510          FAIL("RW2 coherence");
   4.511      }
   4.512   
   4.513 -    if ( gpfn == smfn )
   4.514 +    if ( gmfn == smfn )
   4.515      {
   4.516          if ( level > 1 )
   4.517              FAIL("Linear map ???");    /* XXX this will fail on BSD */
   4.518 @@ -2280,8 +2513,8 @@ int _check_pagetable(struct exec_domain 
   4.519      sh_l2_present = sh_l1_present = 0;
   4.520      perfc_incrc(check_pagetable);
   4.521  
   4.522 -    ptbase_pfn = gptbase >> PAGE_SHIFT;
   4.523 -    ptbase_mfn = __gpfn_to_mfn(d, ptbase_pfn);
   4.524 +    ptbase_mfn = gptbase >> PAGE_SHIFT;
   4.525 +    ptbase_pfn = __mfn_to_gpfn(d, ptbase_mfn);
   4.526  
   4.527      if ( !(smfn = __shadow_status(d, ptbase_pfn, PGT_base_page_table)) )
   4.528      {
     5.1 --- a/xen/arch/x86/traps.c	Wed Mar 16 01:17:37 2005 +0000
     5.2 +++ b/xen/arch/x86/traps.c	Thu Mar 17 12:25:14 2005 +0000
     5.3 @@ -298,7 +298,7 @@ asmlinkage int do_page_fault(struct xen_
     5.4      }
     5.5  
     5.6      if ( unlikely(shadow_mode_enabled(d)) &&
     5.7 -         ((addr < PAGE_OFFSET) || shadow_mode_external(d)) &&
     5.8 +         ((addr < HYPERVISOR_VIRT_START) || shadow_mode_external(d)) &&
     5.9           shadow_fault(addr, regs) )
    5.10      {
    5.11          return EXCRET_fault_fixed;
     6.1 --- a/xen/arch/x86/vmx_io.c	Wed Mar 16 01:17:37 2005 +0000
     6.2 +++ b/xen/arch/x86/vmx_io.c	Thu Mar 17 12:25:14 2005 +0000
     6.3 @@ -391,7 +391,7 @@ void vmx_do_resume(struct exec_domain *d
     6.4          __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
     6.5      else
     6.6          // paging is not enabled in the guest
     6.7 -        __vmwrite(GUEST_CR3, pagetable_val(d->arch.phys_table));
     6.8 +        __vmwrite(GUEST_CR3, pagetable_val(d->domain->arch.phys_table));
     6.9  
    6.10      __vmwrite(HOST_CR3, pagetable_val(d->arch.monitor_table));
    6.11      __vmwrite(HOST_ESP, (unsigned long)get_stack_bottom());
     7.1 --- a/xen/arch/x86/x86_32/domain_build.c	Wed Mar 16 01:17:37 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_32/domain_build.c	Thu Mar 17 12:25:14 2005 +0000
     7.3 @@ -50,6 +50,7 @@ int construct_dom0(struct domain *d,
     7.4      char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */
     7.5  
     7.6      int shadow_dom0 = 1; // HACK ALERT !!  Force dom0 to run in shadow mode.
     7.7 +    int translate_dom0 = 1; // HACK ALERT !!  Force dom0 to run in shadow translate mode
     7.8  
     7.9      /*
    7.10       * This fully describes the memory layout of the initial domain. All 
    7.11 @@ -73,6 +74,7 @@ int construct_dom0(struct domain *d,
    7.12      unsigned long mpt_alloc;
    7.13  
    7.14      extern void physdev_init_dom0(struct domain *);
    7.15 +    extern void translate_l2pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
    7.16  
    7.17      /* Sanity! */
    7.18      if ( d->id != 0 ) 
    7.19 @@ -314,7 +316,7 @@ int construct_dom0(struct domain *d,
    7.20          d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
    7.21      d->shared_info->n_vcpu = smp_num_cpus;
    7.22  
    7.23 -    /* setup shadow and monitor tables */
    7.24 +    /* setup monitor table */
    7.25      update_pagetables(ed);
    7.26  
    7.27      /* Install the new page tables. */
    7.28 @@ -388,9 +390,27 @@ int construct_dom0(struct domain *d,
    7.29  
    7.30      new_thread(ed, dsi.v_kernentry, vstack_end, vstartinfo_start);
    7.31  
    7.32 -    if ( shadow_dom0 )
    7.33 +    if ( shadow_dom0 || translate_dom0 )
    7.34      {
    7.35 -        shadow_mode_enable(d, SHM_enable); 
    7.36 +        shadow_mode_enable(d, (translate_dom0
    7.37 +                               ? SHM_enable | SHM_translate
    7.38 +                               : SHM_enable));
    7.39 +        if ( translate_dom0 )
    7.40 +        {
    7.41 +            // map this domain's p2m table into current page table,
    7.42 +            // so that we can easily access it.
    7.43 +            //
    7.44 +            ASSERT( root_pgentry_val(idle_pg_table[1]) == 0 );
    7.45 +            ASSERT( pagetable_val(d->arch.phys_table) );
    7.46 +            idle_pg_table[1] = mk_root_pgentry(
    7.47 +                pagetable_val(d->arch.phys_table) | __PAGE_HYPERVISOR);
    7.48 +            translate_l2pgtable(d, (l1_pgentry_t *)(1u << L2_PAGETABLE_SHIFT),
    7.49 +                                pagetable_val(ed->arch.guest_table)
    7.50 +                                >> PAGE_SHIFT);
    7.51 +            idle_pg_table[1] = mk_root_pgentry(0);
    7.52 +            local_flush_tlb();
    7.53 +        }
    7.54 +
    7.55          update_pagetables(ed); /* XXX SMP */
    7.56      }
    7.57  
     8.1 --- a/xen/arch/x86/x86_64/domain_build.c	Wed Mar 16 01:17:37 2005 +0000
     8.2 +++ b/xen/arch/x86/x86_64/domain_build.c	Thu Mar 17 12:25:14 2005 +0000
     8.3 @@ -328,7 +328,7 @@ int construct_dom0(struct domain *d,
     8.4          d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
     8.5      d->shared_info->n_vcpu = smp_num_cpus;
     8.6  
     8.7 -    /* Set up shadow and monitor tables. */
     8.8 +    /* Set up monitor table. */
     8.9      update_pagetables(ed);
    8.10  
    8.11      /* Install the new page tables. */
     9.1 --- a/xen/include/asm-x86/domain.h	Wed Mar 16 01:17:37 2005 +0000
     9.2 +++ b/xen/include/asm-x86/domain.h	Thu Mar 17 12:25:14 2005 +0000
     9.3 @@ -50,6 +50,8 @@ struct arch_domain
     9.4      struct out_of_sync_entry *out_of_sync_extras;
     9.5      unsigned int out_of_sync_extras_count;
     9.6  
     9.7 +    pagetable_t  phys_table;               /* guest 1:1 pagetable */
     9.8 +
     9.9  } __cacheline_aligned;
    9.10  
    9.11  struct arch_exec_domain
    9.12 @@ -115,8 +117,6 @@ struct arch_exec_domain
    9.13      pagetable_t  shadow_table;          /* (MA) shadow of guest */
    9.14      pagetable_t  monitor_table;         /* (MA) used in hypervisor */
    9.15  
    9.16 -    pagetable_t  phys_table;            /* guest 1:1 pagetable */
    9.17 -
    9.18      l2_pgentry_t *guest_vtable;         /* virtual address of pagetable */
    9.19      l2_pgentry_t *shadow_vtable;        /* virtual address of shadow_table */
    9.20      l2_pgentry_t *monitor_vtable;		/* virtual address of monitor_table */
    10.1 --- a/xen/include/asm-x86/mm.h	Wed Mar 16 01:17:37 2005 +0000
    10.2 +++ b/xen/include/asm-x86/mm.h	Thu Mar 17 12:25:14 2005 +0000
    10.3 @@ -155,7 +155,7 @@ void free_page_type(struct pfn_info *pag
    10.4  extern void invalidate_shadow_ldt(struct exec_domain *d);
    10.5  extern u32 shadow_remove_all_write_access(
    10.6      struct domain *d, unsigned min_type, unsigned max_type,
    10.7 -    unsigned long gpfn);
    10.8 +    unsigned long gpfn, unsigned long gmfn);
    10.9  extern u32 shadow_remove_all_access( struct domain *d, unsigned long gmfn);
   10.10  
   10.11  static inline void put_page(struct pfn_info *page)
   10.12 @@ -361,15 +361,15 @@ int audit_adjust_pgtables(struct domain 
   10.13  #define AUDIT_ERRORS_OK      ( 1u << 1 )
   10.14  #define AUDIT_QUIET          ( 1u << 2 )
   10.15  
   10.16 -void _audit_domain(struct domain *d, int flags, const char *file, int line);
   10.17 -#define audit_domain(_d) _audit_domain((_d), 0, __FILE__, __LINE__)
   10.18 +void _audit_domain(struct domain *d, int flags);
   10.19 +#define audit_domain(_d) _audit_domain((_d), 0)
   10.20  void audit_domains(void);
   10.21  
   10.22  #else
   10.23  
   10.24 -#define _audit_domain(_d, _f, _file, _line) ((void)0)
   10.25 -#define audit_domain(_d) ((void)0)
   10.26 -#define audit_domains()  ((void)0)
   10.27 +#define _audit_domain(_d, _f) ((void)0)
   10.28 +#define audit_domain(_d)      ((void)0)
   10.29 +#define audit_domains()       ((void)0)
   10.30  
   10.31  #endif
   10.32  
    11.1 --- a/xen/include/asm-x86/shadow.h	Wed Mar 16 01:17:37 2005 +0000
    11.2 +++ b/xen/include/asm-x86/shadow.h	Thu Mar 17 12:25:14 2005 +0000
    11.3 @@ -169,7 +169,8 @@ static inline void shadow_mode_disable(s
    11.4  
    11.5  #define __gpfn_to_mfn(_d, gpfn)                        \
    11.6      ( (shadow_mode_translate(_d))                      \
    11.7 -      ? phys_to_machine_mapping(gpfn)                  \
    11.8 +      ? ({ ASSERT(current->domain == (_d));            \
    11.9 +           phys_to_machine_mapping(gpfn); })           \
   11.10        : (gpfn) )
   11.11  
   11.12  /************************************************************************/
   11.13 @@ -541,10 +542,6 @@ static inline void l1pte_propagate_from_
   11.14      unsigned long mfn = __gpfn_to_mfn(d, pfn);
   11.15      unsigned long spte;
   11.16  
   11.17 -#if SHADOW_VERBOSE_DEBUG
   11.18 -    unsigned long old_spte = *spte_p;
   11.19 -#endif
   11.20 -
   11.21      spte = 0;
   11.22  
   11.23      if ( mfn &&
   11.24 @@ -560,12 +557,12 @@ static inline void l1pte_propagate_from_
   11.25              spte &= ~_PAGE_RW;
   11.26          }
   11.27      }
   11.28 +#if 0
   11.29  
   11.30 -#if SHADOW_VERBOSE_DEBUG
   11.31 -    if ( old_spte || spte || gpte )
   11.32 -        SH_VLOG("l1pte_propagate_from_guest: gpte=0x%p, old spte=0x%p, new spte=0x%p", gpte, old_spte, spte);
   11.33 +    if ( spte || gpte )
   11.34 +        SH_VLOG("%s: gpte=0x%p, new spte=0x%p", __func__, gpte, spte);
   11.35 +
   11.36  #endif
   11.37 -
   11.38      *spte_p = spte;
   11.39  }
   11.40  
   11.41 @@ -582,7 +579,7 @@ static inline void l2pde_general(
   11.42      if ( (gpde & _PAGE_PRESENT) && (sl1mfn != 0) )
   11.43      {
   11.44          spde = (gpde & ~PAGE_MASK) | (sl1mfn << PAGE_SHIFT) | 
   11.45 -            _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
   11.46 +            _PAGE_RW | _PAGE_ACCESSED;
   11.47          gpde |= _PAGE_ACCESSED; /* N.B. PDEs do not have a dirty bit. */
   11.48  
   11.49          // XXX mafetter: Hmm...
   11.50 @@ -592,6 +589,9 @@ static inline void l2pde_general(
   11.51          *gpde_p = gpde;
   11.52      }
   11.53  
   11.54 +    if ( spde || gpde )
   11.55 +        SH_VLOG("%s: gpde=0x%p, new spde=0x%p", __func__, gpde, spde);
   11.56 +
   11.57      *spde_p = spde;
   11.58  }
   11.59  
   11.60 @@ -828,7 +828,9 @@ static inline unsigned long ___shadow_st
   11.61  static inline unsigned long __shadow_status(
   11.62      struct domain *d, unsigned long gpfn, unsigned long stype)
   11.63  {
   11.64 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
   11.65 +    unsigned long gmfn = ((current->domain == d)
   11.66 +                          ? __gpfn_to_mfn(d, gpfn)
   11.67 +                          : 0);
   11.68  
   11.69      ASSERT(spin_is_locked(&d->arch.shadow_lock));
   11.70      ASSERT(gpfn == (gpfn & PGT_mfn_mask));
   11.71 @@ -843,7 +845,7 @@ static inline unsigned long __shadow_sta
   11.72          return 0;
   11.73      }
   11.74  
   11.75 -    return ___shadow_status(d, gmfn, stype);
   11.76 +    return ___shadow_status(d, gpfn, stype);
   11.77  }
   11.78  
   11.79  /*
   11.80 @@ -1014,14 +1016,15 @@ static inline void delete_shadow_status(
   11.81  }
   11.82  
   11.83  static inline void set_shadow_status(
   11.84 -    struct domain *d, unsigned long gpfn,
   11.85 +    struct domain *d, unsigned long gpfn, unsigned long gmfn,
   11.86      unsigned long smfn, unsigned long stype)
   11.87  {
   11.88      struct shadow_status *x, *head, *extra;
   11.89      int i;
   11.90 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
   11.91      unsigned long key = gpfn | stype;
   11.92  
   11.93 +    SH_VVLOG("set gpfn=%p gmfn=%p smfn=%p t=%p\n", gpfn, gmfn, smfn, stype);
   11.94 +
   11.95      ASSERT(spin_is_locked(&d->arch.shadow_lock));
   11.96      ASSERT(gpfn && !(gpfn & ~PGT_mfn_mask));
   11.97      ASSERT(pfn_is_ram(gmfn)); // XXX need to be more graceful
    12.1 --- a/xen/include/xen/perfc_defn.h	Wed Mar 16 01:17:37 2005 +0000
    12.2 +++ b/xen/include/xen/perfc_defn.h	Thu Mar 17 12:25:14 2005 +0000
    12.3 @@ -66,3 +66,5 @@ PERFCOUNTER_CPU(validate_pte_calls,     
    12.4  PERFCOUNTER_CPU(validate_pte_changes,              "validate_pte makes changes")
    12.5  PERFCOUNTER_CPU(validate_pde_calls,                "calls to validate_pde_change")
    12.6  PERFCOUNTER_CPU(validate_pde_changes,              "validate_pde makes changes")
    12.7 +PERFCOUNTER_CPU(shadow_hl2_other_domain,           "shadow_hl2 from other domain")
    12.8 +PERFCOUNTER_CPU(gpfn_to_mfn_safe,                  "calls to gpfn_to_mfn_safe")