ia64/xen-unstable

changeset 4153:4ff298f651de

bitkeeper revision 1.1236.32.4 (4236d5a4kQci3u8a878XDs-1qIBjPw)

Merge maf46@burn.cl.cam.ac.uk:xen-shadow-mode.bk
into fleming.research:/scratch/fleming/mafetter/scrub

Signed-off-by: michael.fetterman@cl.cam.ac.uk
author mafetter@fleming.research
date Tue Mar 15 12:31:32 2005 +0000 (2005-03-15)
parents dff04529e881 9a43f31bae0a
children 6b80eefad546
files xen/arch/x86/audit.c xen/arch/x86/mm.c xen/arch/x86/shadow.c 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	Mon Mar 14 22:10:10 2005 +0000
     1.2 +++ b/xen/arch/x86/audit.c	Tue Mar 15 12:31:32 2005 +0000
     1.3 @@ -25,25 +25,17 @@
     1.4  #include <xen/kernel.h>
     1.5  #include <xen/lib.h>
     1.6  #include <xen/mm.h>
     1.7 -//#include <xen/sched.h>
     1.8 -//#include <xen/errno.h>
     1.9  #include <xen/perfc.h>
    1.10 -//#include <xen/irq.h>
    1.11 -//#include <xen/softirq.h>
    1.12  #include <asm/shadow.h>
    1.13  #include <asm/page.h>
    1.14  #include <asm/flushtlb.h>
    1.15 -//#include <asm/io.h>
    1.16 -//#include <asm/uaccess.h>
    1.17 -//#include <asm/domain_page.h>
    1.18 -//#include <asm/ldt.h>
    1.19  
    1.20  // XXX SMP bug -- these should not be statics...
    1.21  //
    1.22  static int ttot=0, ctot=0, io_mappings=0, lowmem_mappings=0;
    1.23  static int l1, l2, oos_count, page_count;
    1.24  
    1.25 -#define FILE_AND_LINE 1
    1.26 +#define FILE_AND_LINE 0
    1.27  
    1.28  #if FILE_AND_LINE
    1.29  #define adjust(_p, _a) _adjust((_p), (_a), __FILE__, __LINE__)
    1.30 @@ -73,7 +65,7 @@ int audit_adjust_pgtables(struct domain 
    1.31              if ( page_get_owner(page) == NULL )
    1.32              {
    1.33                  APRINTK("adjust(mfn=%p, dir=%d, adjtype=%d) owner=NULL",
    1.34 -                        page_to_pfn(page), dir, adjtype, file, line);
    1.35 +                        page_to_pfn(page), dir, adjtype);
    1.36                  errors++;
    1.37              }
    1.38  
     2.1 --- a/xen/arch/x86/mm.c	Mon Mar 14 22:10:10 2005 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Tue Mar 15 12:31:32 2005 +0000
     2.3 @@ -1858,8 +1858,6 @@ int do_mmu_update(
     2.4                  break;
     2.5  #endif /* __x86_64__ */
     2.6              default:
     2.7 -                printk("do_mmu_update writable update: ma=%p val=%p\n",
     2.8 -                       req.ptr, req.val);
     2.9                  if ( likely(get_page_type(page, PGT_writable_page)) )
    2.10                  {
    2.11                      if ( shadow_mode_enabled(d) )
     3.1 --- a/xen/arch/x86/shadow.c	Mon Mar 14 22:10:10 2005 +0000
     3.2 +++ b/xen/arch/x86/shadow.c	Tue Mar 15 12:31:32 2005 +0000
     3.3 @@ -60,7 +60,7 @@ shadow_promote(struct domain *d, unsigne
     3.4          __shadow_sync_mfn(d, gmfn);
     3.5      }
     3.6  
     3.7 -    if ( unlikely(mfn_is_page_table(gmfn)) )
     3.8 +    if ( unlikely(page_is_page_table(page)) )
     3.9      {
    3.10          min_type = shadow_max_pgtable_type(d, gpfn) + PGT_l1_shadow;
    3.11          max_type = new_type;
    3.12 @@ -99,7 +99,7 @@ shadow_promote(struct domain *d, unsigne
    3.13      if ( get_page_type(page, PGT_base_page_table) )
    3.14      {
    3.15          put_page_type(page);
    3.16 -        set_bit(_PGC_page_table, &frame_table[gmfn].count_info);
    3.17 +        set_bit(_PGC_page_table, &page->count_info);
    3.18      }
    3.19      else
    3.20      {
    3.21 @@ -1197,7 +1197,7 @@ void shadow_map_l1_into_current_l2(unsig
    3.22          {
    3.23              l1pte_propagate_from_guest(d, gpl1e[i], &spl1e[i]);
    3.24              if ( spl1e[i] & _PAGE_PRESENT )
    3.25 -                get_page_from_l1e(mk_l1_pgentry(spl1e[i]), d);
    3.26 +                shadow_get_page_from_l1e(mk_l1_pgentry(spl1e[i]), d);
    3.27          }
    3.28      }
    3.29  }
    3.30 @@ -1503,7 +1503,7 @@ static u32 remove_all_write_access_in_pt
    3.31              unsigned long new = old & ~_PAGE_RW;
    3.32  
    3.33              if ( is_l1_shadow )
    3.34 -                get_page_from_l1e(mk_l1_pgentry(new), d);
    3.35 +                shadow_get_page_from_l1e(mk_l1_pgentry(new), d);
    3.36  
    3.37              count++;
    3.38              pt[i] = new;
    3.39 @@ -1724,7 +1724,8 @@ void __shadow_sync_all(struct domain *d)
    3.40          unsigned long opte = *ppte;
    3.41          unsigned long npte = opte & ~_PAGE_RW;
    3.42  
    3.43 -        get_page_from_l1e(mk_l1_pgentry(npte), d);
    3.44 +        if ( npte & _PAGE_PRESENT)
    3.45 +            shadow_get_page_from_l1e(mk_l1_pgentry(npte), d);
    3.46          *ppte = npte;
    3.47          put_page_from_l1e(mk_l1_pgentry(opte), d);
    3.48  
     4.1 --- a/xen/include/asm-x86/mm.h	Mon Mar 14 22:10:10 2005 +0000
     4.2 +++ b/xen/include/asm-x86/mm.h	Tue Mar 15 12:31:32 2005 +0000
     4.3 @@ -129,8 +129,6 @@ static inline u32 pickle_domptr(struct d
     4.4  #define page_get_owner(_p)    (unpickle_domptr((_p)->u.inuse._domain))
     4.5  #define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d))
     4.6  
     4.7 -#define page_out_of_sync(_p)  ((_p)->count_info & PGC_out_of_sync)
     4.8 -
     4.9  #define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
    4.10      do {                                                                    \
    4.11          page_set_owner((_pfn), (_dom));                                     \
    4.12 @@ -235,22 +233,6 @@ static inline int get_page_and_type(stru
    4.13      return rc;
    4.14  }
    4.15  
    4.16 -static inline int mfn_is_page_table(unsigned long mfn)
    4.17 -{
    4.18 -    if ( !pfn_is_ram(mfn) )
    4.19 -        return 0;
    4.20 -
    4.21 -    return frame_table[mfn].count_info & PGC_page_table;
    4.22 -}
    4.23 -
    4.24 -static inline int page_is_page_table(struct pfn_info *page)
    4.25 -{
    4.26 -    if ( !pfn_is_ram(page_to_pfn(page)) )
    4.27 -        return 0;
    4.28 -
    4.29 -    return page->count_info & PGC_page_table;
    4.30 -}
    4.31 -
    4.32  #define ASSERT_PAGE_IS_TYPE(_p, _t)                            \
    4.33      ASSERT(((_p)->u.inuse.type_info & PGT_type_mask) == (_t)); \
    4.34      ASSERT(((_p)->u.inuse.type_info & PGT_count_mask) != 0)
     5.1 --- a/xen/include/asm-x86/shadow.h	Mon Mar 14 22:10:10 2005 +0000
     5.2 +++ b/xen/include/asm-x86/shadow.h	Tue Mar 15 12:31:32 2005 +0000
     5.3 @@ -68,6 +68,33 @@ static inline unsigned long __shadow_sta
     5.4  
     5.5  extern void vmx_shadow_clear_state(struct domain *);
     5.6  
     5.7 +static inline int page_is_page_table(struct pfn_info *page)
     5.8 +{
     5.9 +    return page->count_info & PGC_page_table;
    5.10 +}
    5.11 +
    5.12 +static inline int mfn_is_page_table(unsigned long mfn)
    5.13 +{
    5.14 +    if ( !pfn_is_ram(mfn) )
    5.15 +        return 0;
    5.16 +
    5.17 +    return frame_table[mfn].count_info & PGC_page_table;
    5.18 +}
    5.19 +
    5.20 +static inline int page_out_of_sync(struct pfn_info *page)
    5.21 +{
    5.22 +    return page->count_info & PGC_out_of_sync;
    5.23 +}
    5.24 +
    5.25 +static inline int mfn_out_of_sync(unsigned long mfn)
    5.26 +{
    5.27 +    if ( !pfn_is_ram(mfn) )
    5.28 +        return 0;
    5.29 +
    5.30 +    return frame_table[mfn].count_info & PGC_out_of_sync;
    5.31 +}
    5.32 +
    5.33 +
    5.34  /************************************************************************/
    5.35  
    5.36  static void inline
    5.37 @@ -215,6 +242,36 @@ extern int shadow_status_noswap;
    5.38  
    5.39  /************************************************************************/
    5.40  
    5.41 +static inline int
    5.42 +shadow_get_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
    5.43 +{
    5.44 +    int res = get_page_from_l1e(l1e, d);
    5.45 +    unsigned long mfn;
    5.46 +    struct domain *owner;
    5.47 +
    5.48 +    ASSERT( l1_pgentry_val(l1e) & _PAGE_PRESENT );
    5.49 +
    5.50 +    if ( unlikely(!res) && IS_PRIV(d) && !shadow_mode_translate(d) &&
    5.51 +         !(l1_pgentry_val(l1e) & L1_DISALLOW_MASK) &&
    5.52 +         (mfn = l1_pgentry_to_pfn(l1e)) &&
    5.53 +         pfn_is_ram(mfn) &&
    5.54 +         (owner = page_get_owner(pfn_to_page(l1_pgentry_to_pfn(l1e)))) &&
    5.55 +         (d != owner) )
    5.56 +    {
    5.57 +        res = get_page_from_l1e(l1e, owner);
    5.58 +        printk("tried to map page from domain %d into shadow page tables "
    5.59 +               "of domain %d; %s\n",
    5.60 +               owner->id, d->id, res ? "success" : "failed");
    5.61 +    }
    5.62 +
    5.63 +    if ( unlikely(!res) )
    5.64 +        perfc_incrc(shadow_get_page_fail);
    5.65 +
    5.66 +    return res;
    5.67 +}
    5.68 +
    5.69 +/************************************************************************/
    5.70 +
    5.71  static inline void
    5.72  __shadow_get_l2e(
    5.73      struct exec_domain *ed, unsigned long va, unsigned long *psl2e)
    5.74 @@ -257,7 +314,7 @@ static inline void
    5.75          if ( (old_hl2e ^ new_hl2e) & (PAGE_MASK | _PAGE_PRESENT) )
    5.76          {
    5.77              if ( new_hl2e & _PAGE_PRESENT )
    5.78 -                get_page_from_l1e(mk_l1_pgentry(new_hl2e), ed->domain);
    5.79 +                shadow_get_page_from_l1e(mk_l1_pgentry(new_hl2e), ed->domain);
    5.80              if ( old_hl2e & _PAGE_PRESENT )
    5.81                  put_page_from_l1e(mk_l1_pgentry(old_hl2e), ed->domain);
    5.82          }
    5.83 @@ -541,9 +598,10 @@ static inline void l2pde_general(
    5.84  static inline void l2pde_propagate_from_guest(
    5.85      struct domain *d, unsigned long *gpde_p, unsigned long *spde_p)
    5.86  {
    5.87 -    unsigned long gpde = *gpde_p, sl1mfn;
    5.88 +    unsigned long gpde = *gpde_p, sl1mfn = 0;
    5.89  
    5.90 -    sl1mfn =  __shadow_status(d, gpde >> PAGE_SHIFT, PGT_l1_shadow);
    5.91 +    if ( gpde & _PAGE_PRESENT )
    5.92 +        sl1mfn =  __shadow_status(d, gpde >> PAGE_SHIFT, PGT_l1_shadow);
    5.93      l2pde_general(d, gpde_p, spde_p, sl1mfn);
    5.94  }
    5.95      
    5.96 @@ -559,7 +617,7 @@ validate_pte_change(
    5.97  {
    5.98      unsigned long old_spte, new_spte;
    5.99  
   5.100 -    perfc_incrc(validate_pte_change);
   5.101 +    perfc_incrc(validate_pte_calls);
   5.102  
   5.103  #if 0
   5.104      FSH_LOG("validate_pte(old=%p new=%p)\n", old_pte, new_pte);
   5.105 @@ -571,10 +629,13 @@ validate_pte_change(
   5.106  
   5.107      // only do the ref counting if something important changed.
   5.108      //
   5.109 -    if ( (old_spte ^ new_spte) & (PAGE_MASK | _PAGE_RW | _PAGE_PRESENT) )
   5.110 +    if ( ((old_spte | new_spte) & _PAGE_PRESENT ) &&
   5.111 +         ((old_spte ^ new_spte) & (PAGE_MASK | _PAGE_RW | _PAGE_PRESENT)) )
   5.112      {
   5.113 +        perfc_incrc(validate_pte_changes);
   5.114 +
   5.115          if ( new_spte & _PAGE_PRESENT )
   5.116 -            get_page_from_l1e(mk_l1_pgentry(new_spte), d);
   5.117 +            shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d);
   5.118          if ( old_spte & _PAGE_PRESENT )
   5.119              put_page_from_l1e(mk_l1_pgentry(old_spte), d);
   5.120      }
   5.121 @@ -594,15 +655,18 @@ validate_pde_change(
   5.122      unsigned long old_spde = *shadow_pde_p;
   5.123      unsigned long new_spde;
   5.124  
   5.125 -    perfc_incrc(validate_pde_change);
   5.126 +    perfc_incrc(validate_pde_calls);
   5.127  
   5.128      l2pde_propagate_from_guest(d, &new_pde, shadow_pde_p);
   5.129      new_spde = *shadow_pde_p;
   5.130  
   5.131      // only do the ref counting if something important changed.
   5.132      //
   5.133 -    if ( (old_spde ^ new_spde) & (PAGE_MASK | _PAGE_PRESENT) )
   5.134 +    if ( ((old_spde | new_spde) & _PAGE_PRESENT) &&
   5.135 +         ((old_spde ^ new_spde) & (PAGE_MASK | _PAGE_PRESENT)) )
   5.136      {
   5.137 +        perfc_incrc(validate_pde_changes);
   5.138 +
   5.139          if ( new_spde & _PAGE_PRESENT )
   5.140              get_shadow_ref(new_spde >> PAGE_SHIFT);
   5.141          if ( old_spde & _PAGE_PRESENT )
   5.142 @@ -696,16 +760,12 @@ static inline struct shadow_status *hash
   5.143   *      It returns the shadow's mfn, or zero if it doesn't exist.
   5.144   */
   5.145  
   5.146 -static inline unsigned long __shadow_status(
   5.147 +static inline unsigned long ___shadow_status(
   5.148      struct domain *d, unsigned long gpfn, unsigned long stype)
   5.149  {
   5.150      struct shadow_status *p, *x, *head;
   5.151      unsigned long key = gpfn | stype;
   5.152  
   5.153 -    ASSERT(spin_is_locked(&d->arch.shadow_lock));
   5.154 -    ASSERT(gpfn == (gpfn & PGT_mfn_mask));
   5.155 -    ASSERT(stype && !(stype & ~PGT_type_mask));
   5.156 -
   5.157      perfc_incrc(shadow_status_calls);
   5.158  
   5.159      x = head = hash_bucket(d, gpfn);
   5.160 @@ -755,6 +815,27 @@ static inline unsigned long __shadow_sta
   5.161      return 0;
   5.162  }
   5.163  
   5.164 +static inline unsigned long __shadow_status(
   5.165 +    struct domain *d, unsigned long gpfn, unsigned long stype)
   5.166 +{
   5.167 +    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
   5.168 +
   5.169 +    ASSERT(spin_is_locked(&d->arch.shadow_lock));
   5.170 +    ASSERT(gpfn == (gpfn & PGT_mfn_mask));
   5.171 +    ASSERT(stype && !(stype & ~PGT_type_mask));
   5.172 +
   5.173 +    if ( gmfn && ((stype != PGT_snapshot)
   5.174 +                  ? !mfn_is_page_table(gmfn)
   5.175 +                  : !mfn_out_of_sync(gmfn)) )
   5.176 +    {
   5.177 +        perfc_incrc(shadow_status_shortcut);
   5.178 +        ASSERT(___shadow_status(d, gpfn, stype) == 0);
   5.179 +        return 0;
   5.180 +    }
   5.181 +
   5.182 +    return ___shadow_status(d, gmfn, stype);
   5.183 +}
   5.184 +
   5.185  /*
   5.186   * Not clear if pull-to-front is worth while for this or not,
   5.187   * as it generally needs to scan the entire bucket anyway.
   5.188 @@ -1081,7 +1162,7 @@ shadow_set_l1e(unsigned long va, unsigne
   5.189      if ( (old_spte ^ new_spte) & (PAGE_MASK | _PAGE_RW | _PAGE_PRESENT) )
   5.190      {
   5.191          if ( new_spte & _PAGE_PRESENT )
   5.192 -            get_page_from_l1e(mk_l1_pgentry(new_spte), d);
   5.193 +            shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d);
   5.194          if ( old_spte & _PAGE_PRESENT )
   5.195              put_page_from_l1e(mk_l1_pgentry(old_spte), d);
   5.196      }
     6.1 --- a/xen/include/xen/perfc_defn.h	Mon Mar 14 22:10:10 2005 +0000
     6.2 +++ b/xen/include/xen/perfc_defn.h	Tue Mar 15 12:31:32 2005 +0000
     6.3 @@ -38,11 +38,13 @@ PERFSTATUS( shadow_l1_pages, "current # 
     6.4  PERFSTATUS( hl2_table_pages, "current # hl2 pages" )
     6.5  PERFSTATUS( snapshot_pages,  "current # fshadow snapshot pages" )
     6.6  
     6.7 -PERFCOUNTER_CPU(shadow_status_calls,    "calls to __shadow_status" )
     6.8 +PERFCOUNTER_CPU(shadow_status_shortcut, "fastpath miss on shadow cache")
     6.9 +PERFCOUNTER_CPU(shadow_status_calls,    "calls to ___shadow_status" )
    6.10  PERFCOUNTER_CPU(shadow_status_miss,     "missed shadow cache" )
    6.11  PERFCOUNTER_CPU(shadow_status_hit_head, "hits on head of bucket" )
    6.12  PERFCOUNTER_CPU(check_pagetable,        "calls to check_pagetable" )
    6.13  PERFCOUNTER_CPU(check_all_pagetables,   "calls to check_all_pagetables" )
    6.14 +PERFCOUNTER_CPU(shadow_get_page_fail,   "shadow_get_page_from_l1e fails" )
    6.15  
    6.16  PERFCOUNTER_CPU(shadow_sync_all,                   "calls to shadow_sync_all")
    6.17  PERFCOUNTER_CPU(shadow_make_snapshot,              "snapshots created")
    6.18 @@ -58,5 +60,7 @@ PERFCOUNTER_CPU(shadow_fault_bail_pde_no
    6.19  PERFCOUNTER_CPU(shadow_fault_bail_pte_not_present, "sf bailed due to pte not present")
    6.20  PERFCOUNTER_CPU(shadow_fault_bail_ro_mapping,      "sf bailed due to a ro mapping")
    6.21  PERFCOUNTER_CPU(shadow_fault_fixed,                "sf fixed the pgfault")
    6.22 -PERFCOUNTER_CPU(validate_pte_change,               "calls to validate_pte_change")
    6.23 -PERFCOUNTER_CPU(validate_pde_change,               "calls to validate_pde_change")
    6.24 +PERFCOUNTER_CPU(validate_pte_calls,                "calls to validate_pte_change")
    6.25 +PERFCOUNTER_CPU(validate_pte_changes,              "validate_pte makes changes")
    6.26 +PERFCOUNTER_CPU(validate_pde_calls,                "calls to validate_pde_change")
    6.27 +PERFCOUNTER_CPU(validate_pde_changes,              "validate_pde makes changes")