ia64/xen-unstable
changeset 14020:266d203d7f39
[XEN] Fix potential race in unshadow code
And add some diagnostic printout in case it happens again
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
And add some diagnostic printout in case it happens again
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author | Tim Deegan <Tim.Deegan@xensource.com> |
---|---|
date | Tue Feb 20 11:51:40 2007 +0000 (2007-02-20) |
parents | 4b9680c58d73 |
children | 4990b2236f06 |
files | xen/arch/x86/mm/shadow/common.c |
line diff
1.1 --- a/xen/arch/x86/mm/shadow/common.c Tue Feb 20 09:41:32 2007 +0000 1.2 +++ b/xen/arch/x86/mm/shadow/common.c Tue Feb 20 11:51:40 2007 +0000 1.3 @@ -2066,10 +2066,6 @@ void sh_remove_shadows(struct vcpu *v, m 1.4 1.5 ASSERT(!(all && fast)); 1.6 1.7 - /* Bail out now if the page is not shadowed */ 1.8 - if ( (pg->count_info & PGC_page_table) == 0 ) 1.9 - return; 1.10 - 1.11 /* Although this is an externally visible function, we do not know 1.12 * whether the shadow lock will be held when it is called (since it 1.13 * can be called via put_page_type when we clear a shadow l1e). 1.14 @@ -2080,6 +2076,13 @@ void sh_remove_shadows(struct vcpu *v, m 1.15 SHADOW_PRINTK("d=%d, v=%d, gmfn=%05lx\n", 1.16 v->domain->domain_id, v->vcpu_id, mfn_x(gmfn)); 1.17 1.18 + /* Bail out now if the page is not shadowed */ 1.19 + if ( (pg->count_info & PGC_page_table) == 0 ) 1.20 + { 1.21 + if ( do_locking ) shadow_unlock(v->domain); 1.22 + return; 1.23 + } 1.24 + 1.25 /* Search for this shadow in all appropriate shadows */ 1.26 perfc_incrc(shadow_unshadow); 1.27 sh_flags = pg->shadow_flags; 1.28 @@ -2088,15 +2091,22 @@ void sh_remove_shadows(struct vcpu *v, m 1.29 * This call to hash_foreach() looks dangerous but is in fact OK: each 1.30 * call will remove at most one shadow, and terminate immediately when 1.31 * it does remove it, so we never walk the hash after doing a deletion. */ 1.32 -#define DO_UNSHADOW(_type) do { \ 1.33 - t = (_type); \ 1.34 - smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ 1.35 - if ( sh_type_is_pinnable(v, t) ) \ 1.36 - sh_unpin(v, smfn); \ 1.37 - else \ 1.38 - sh_remove_shadow_via_pointer(v, smfn); \ 1.39 - if ( (pg->count_info & PGC_page_table) && !fast ) \ 1.40 - hash_foreach(v, masks[t], callbacks, smfn); \ 1.41 +#define DO_UNSHADOW(_type) do { \ 1.42 + t = (_type); \ 1.43 + smfn = shadow_hash_lookup(v, mfn_x(gmfn), t); \ 1.44 + if ( unlikely(!mfn_valid(smfn)) ) \ 1.45 + { \ 1.46 + SHADOW_ERROR(": gmfn %#lx has flags 0x%"PRIx32 \ 1.47 + " but no type-0x%"PRIx32" shadow\n", \ 1.48 + mfn_x(gmfn), sh_flags, t); \ 1.49 + break; \ 1.50 + } \ 1.51 + if ( sh_type_is_pinnable(v, t) ) \ 1.52 + sh_unpin(v, smfn); \ 1.53 + else \ 1.54 + sh_remove_shadow_via_pointer(v, smfn); \ 1.55 + if ( (pg->count_info & PGC_page_table) && !fast ) \ 1.56 + hash_foreach(v, masks[t], callbacks, smfn); \ 1.57 } while (0) 1.58 1.59 if ( sh_flags & SHF_L1_32 ) DO_UNSHADOW(SH_type_l1_32_shadow);