[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Fix potential race in unshadow code
# HG changeset patch # User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> # Date 1171972300 0 # Node ID 266d203d7f39d69b14a5c020974cd843802592e8 # Parent 4b9680c58d738fa69b285b80c42e7e245ec1512c [XEN] Fix potential race in unshadow code And add some diagnostic printout in case it happens again Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> --- xen/arch/x86/mm/shadow/common.c | 36 +++++++++++++++++++++++------------- 1 files changed, 23 insertions(+), 13 deletions(-) diff -r 4b9680c58d73 -r 266d203d7f39 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Tue Feb 20 09:41:32 2007 +0000 +++ b/xen/arch/x86/mm/shadow/common.c Tue Feb 20 11:51:40 2007 +0000 @@ -2066,10 +2066,6 @@ void sh_remove_shadows(struct vcpu *v, m ASSERT(!(all && fast)); - /* Bail out now if the page is not shadowed */ - if ( (pg->count_info & PGC_page_table) == 0 ) - return; - /* Although this is an externally visible function, we do not know * whether the shadow lock will be held when it is called (since it * can be called via put_page_type when we clear a shadow l1e). @@ -2080,6 +2076,13 @@ void sh_remove_shadows(struct vcpu *v, m SHADOW_PRINTK("d=%d, v=%d, gmfn=%05lx\n", v->domain->domain_id, v->vcpu_id, mfn_x(gmfn)); + /* Bail out now if the page is not shadowed */ + if ( (pg->count_info & PGC_page_table) == 0 ) + { + if ( do_locking ) shadow_unlock(v->domain); + return; + } + /* Search for this shadow in all appropriate shadows */ perfc_incrc(shadow_unshadow); sh_flags = pg->shadow_flags; @@ -2088,15 +2091,22 @@ void sh_remove_shadows(struct vcpu *v, m * This call to hash_foreach() looks dangerous but is in fact OK: each * call will remove at most one shadow, and terminate immediately when * it does remove it, so we never walk the hash after doing a deletion. */ -#define DO_UNSHADOW(_type) do { \ - t = (_type); \ - smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ - if ( sh_type_is_pinnable(v, t) ) \ - sh_unpin(v, smfn); \ - else \ - sh_remove_shadow_via_pointer(v, smfn); \ - if ( (pg->count_info & PGC_page_table) && !fast ) \ - hash_foreach(v, masks[t], callbacks, smfn); \ +#define DO_UNSHADOW(_type) do { \ + t = (_type); \ + smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ + if ( unlikely(!mfn_valid(smfn)) ) \ + { \ + SHADOW_ERROR(": gmfn %#lx has flags 0x%"PRIx32 \ + " but no type-0x%"PRIx32" shadow\n", \ + mfn_x(gmfn), sh_flags, t); \ + break; \ + } \ + if ( sh_type_is_pinnable(v, t) ) \ + sh_unpin(v, smfn); \ + else \ + sh_remove_shadow_via_pointer(v, smfn); \ + if ( (pg->count_info & PGC_page_table) && !fast ) \ + hash_foreach(v, masks[t], callbacks, smfn); \ } while (0) if ( sh_flags & SHF_L1_32 ) DO_UNSHADOW(SH_type_l1_32_shadow); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |