direct-io.hg
changeset 11648:5f42b4824e45
[XEN] Fix interaction between tlbflush timestamp and shadow flags
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
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 */