ia64/xen-unstable

changeset 11665:5f42b4824e45

[XEN] Fix interaction between tlbflush timestamp and shadow flags
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <tim.deegan@xensource.com>
date Thu Sep 28 17:09:11 2006 +0100 (2006-09-28)
parents 14111cab38fd
children b6ee084892da
files xen/arch/x86/mm.c xen/arch/x86/mm/shadow/common.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Thu Sep 28 13:45:49 2006 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Thu Sep 28 17:09:11 2006 +0100
     1.3 @@ -1544,9 +1544,7 @@ void free_page_type(struct page_info *pa
     1.4  
     1.5              gmfn = mfn_to_gmfn(owner, page_to_mfn(page));
     1.6              ASSERT(VALID_M2P(gmfn));
     1.7 -            shadow_lock(owner);
     1.8              shadow_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
     1.9 -            shadow_unlock(owner);
    1.10          }
    1.11      }
    1.12  
    1.13 @@ -1618,8 +1616,8 @@ void put_page_type(struct page_info *pag
    1.14               *  2. Shadow mode reuses this field for shadowed page tables to
    1.15               *     store flags info -- we don't want to conflict with that.
    1.16               */
    1.17 -            if ( !shadow_mode_enabled(page_get_owner(page)) ||
    1.18 -                 ((nx & PGT_type_mask) == PGT_writable_page) )
    1.19 +            if ( !(shadow_mode_enabled(page_get_owner(page)) &&
    1.20 +                   (page->count_info & PGC_page_table)) )
    1.21                  page->tlbflush_timestamp = tlbflush_current_time();
    1.22          }
    1.23      }
    1.24 @@ -1644,6 +1642,12 @@ int get_page_type(struct page_info *page
    1.25          }
    1.26          else if ( unlikely((x & PGT_count_mask) == 0) )
    1.27          {
    1.28 +            struct domain *d = page_get_owner(page);
    1.29 +
    1.30 +            /* Never allow a shadowed frame to go from type count 0 to 1 */
    1.31 +            if ( d && shadow_mode_enabled(d) )
    1.32 +                shadow_remove_all_shadows(d->vcpu[0], _mfn(page_to_mfn(page)));
    1.33 +
    1.34              ASSERT(!(x & PGT_pae_xen_l2));
    1.35              if ( (x & PGT_type_mask) != type )
    1.36              {
    1.37 @@ -1652,8 +1656,9 @@ int get_page_type(struct page_info *page
    1.38                   * may be unnecessary (e.g., page was GDT/LDT) but those 
    1.39                   * circumstances should be very rare.
    1.40                   */
    1.41 -                cpumask_t mask =
    1.42 -                    page_get_owner(page)->domain_dirty_cpumask;
    1.43 +                cpumask_t mask = d->domain_dirty_cpumask;
    1.44 +
    1.45 +                /* Don't flush if the timestamp is old enough */
    1.46                  tlbflush_filter(mask, page->tlbflush_timestamp);
    1.47  
    1.48                  if ( unlikely(!cpus_empty(mask)) &&
     2.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Sep 28 13:45:49 2006 +0100
     2.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Sep 28 17:09:11 2006 +0100
     2.3 @@ -256,7 +256,11 @@ void shadow_demote(struct vcpu *v, mfn_t
     2.4      clear_bit(type >> PGC_SH_type_shift, &page->shadow_flags);
     2.5  
     2.6      if ( (page->shadow_flags & SHF_page_type_mask) == 0 )
     2.7 +    {
     2.8 +        /* tlbflush timestamp field is valid again */
     2.9 +        page->tlbflush_timestamp = tlbflush_current_time();
    2.10          clear_bit(_PGC_page_table, &page->count_info);
    2.11 +    }
    2.12  }
    2.13  
    2.14  /**************************************************************************/
     3.1 --- a/xen/include/asm-x86/shadow.h	Thu Sep 28 13:45:49 2006 +0100
     3.2 +++ b/xen/include/asm-x86/shadow.h	Thu Sep 28 17:09:11 2006 +0100
     3.3 @@ -481,7 +481,12 @@ shadow_remove_all_shadows_and_parents(st
     3.4  extern void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int all);
     3.5  static inline void shadow_remove_all_shadows(struct vcpu *v, mfn_t gmfn)
     3.6  {
     3.7 +    int was_locked = shadow_lock_is_acquired(v->domain);
     3.8 +    if ( !was_locked )
     3.9 +        shadow_lock(v->domain);
    3.10      sh_remove_shadows(v, gmfn, 1);
    3.11 +    if ( !was_locked )
    3.12 +        shadow_unlock(v->domain);
    3.13  }
    3.14  
    3.15  /* Add a page to a domain */