[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 14/20] x86/shadow: Alter sh_remove_l?_shadow() to take a domain
This involves introducing the domain variant of hash_foreach() Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> --- xen/arch/x86/mm/shadow/common.c | 52 +++++++++++++++++++++++++++++++++++++-- xen/arch/x86/mm/shadow/multi.c | 9 +++---- xen/arch/x86/mm/shadow/multi.h | 6 ++--- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index e522b60..3810b75 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -1998,6 +1998,7 @@ void shadow_hash_delete(struct domain *d, unsigned long n, unsigned int t, } typedef int (*hash_vcpu_callback_t)(struct vcpu *v, mfn_t smfn, mfn_t other_mfn); +typedef int (*hash_domain_callback_t)(struct domain *d, mfn_t smfn, mfn_t other_mfn); static void hash_vcpu_foreach(struct vcpu *v, unsigned int callback_mask, const hash_vcpu_callback_t callbacks[], @@ -2046,6 +2047,53 @@ static void hash_vcpu_foreach(struct vcpu *v, unsigned int callback_mask, d->arch.paging.shadow.hash_walking = 0; } +static void hash_domain_foreach(struct domain *d, + unsigned int callback_mask, + const hash_domain_callback_t callbacks[], + mfn_t callback_mfn) +/* Walk the hash table looking at the types of the entries and + * calling the appropriate callback function for each entry. + * The mask determines which shadow types we call back for, and the array + * of callbacks tells us which function to call. + * Any callback may return non-zero to let us skip the rest of the scan. + * + * WARNING: Callbacks MUST NOT add or remove hash entries unless they + * then return non-zero to terminate the scan. */ +{ + int i, done = 0; + struct page_info *x; + + ASSERT(paging_locked_by_me(d)); + + /* Can be called via p2m code &c after shadow teardown. */ + if ( unlikely(!d->arch.paging.shadow.hash_table) ) + return; + + /* Say we're here, to stop hash-lookups reordering the chains */ + ASSERT(d->arch.paging.shadow.hash_walking == 0); + d->arch.paging.shadow.hash_walking = 1; + + for ( i = 0; i < SHADOW_HASH_BUCKETS; i++ ) + { + /* WARNING: This is not safe against changes to the hash table. + * The callback *must* return non-zero if it has inserted or + * deleted anything from the hash (lookups are OK, though). */ + for ( x = d->arch.paging.shadow.hash_table[i]; x; x = next_shadow(x) ) + { + if ( callback_mask & (1 << x->u.sh.type) ) + { + ASSERT(x->u.sh.type <= 15); + ASSERT(callbacks[x->u.sh.type] != NULL); + done = callbacks[x->u.sh.type](d, page_to_mfn(x), + callback_mfn); + if ( done ) break; + } + } + if ( done ) break; + } + d->arch.paging.shadow.hash_walking = 0; +} + /**************************************************************************/ /* Destroy a shadow page: simple dispatcher to call the per-type destructor @@ -2537,7 +2585,7 @@ void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int fast, int all) /* Dispatch table for getting per-type functions: each level must * be called with the function to remove a lower-level shadow. */ - static const hash_vcpu_callback_t callbacks[SH_type_unused] = { + static const hash_domain_callback_t callbacks[SH_type_unused] = { NULL, /* none */ NULL, /* l1_32 */ NULL, /* fl1_32 */ @@ -2621,7 +2669,7 @@ void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int fast, int all) if( !fast \ && (pg->count_info & PGC_page_table) \ && (pg->shadow_flags & (1 << t)) ) \ - hash_vcpu_foreach(v, masks[t], callbacks, smfn); \ + hash_domain_foreach(d, masks[t], callbacks, smfn); \ } while (0) DO_UNSHADOW(SH_type_l2_32_shadow); diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 469ad25..ab6ebe2 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -4373,10 +4373,9 @@ void sh_clear_shadow_entry(struct domain *d, void *ep, mfn_t smfn) } } -int sh_remove_l1_shadow(struct vcpu *v, mfn_t sl2mfn, mfn_t sl1mfn) +int sh_remove_l1_shadow(struct domain *d, mfn_t sl2mfn, mfn_t sl1mfn) /* Remove all mappings of this l1 shadow from this l2 shadow */ { - struct domain *d = v->domain; shadow_l2e_t *sl2e; int done = 0; int flags; @@ -4397,10 +4396,9 @@ int sh_remove_l1_shadow(struct vcpu *v, mfn_t sl2mfn, mfn_t sl1mfn) } #if GUEST_PAGING_LEVELS >= 4 -int sh_remove_l2_shadow(struct vcpu *v, mfn_t sl3mfn, mfn_t sl2mfn) +int sh_remove_l2_shadow(struct domain *d, mfn_t sl3mfn, mfn_t sl2mfn) /* Remove all mappings of this l2 shadow from this l3 shadow */ { - struct domain *d = v->domain; shadow_l3e_t *sl3e; int done = 0; int flags; @@ -4420,10 +4418,9 @@ int sh_remove_l2_shadow(struct vcpu *v, mfn_t sl3mfn, mfn_t sl2mfn) return done; } -int sh_remove_l3_shadow(struct vcpu *v, mfn_t sl4mfn, mfn_t sl3mfn) +int sh_remove_l3_shadow(struct domain *d, mfn_t sl4mfn, mfn_t sl3mfn) /* Remove all mappings of this l3 shadow from this l4 shadow */ { - struct domain *d = v->domain; shadow_l4e_t *sl4e; int done = 0; int flags; diff --git a/xen/arch/x86/mm/shadow/multi.h b/xen/arch/x86/mm/shadow/multi.h index e33948c..8bb8ece 100644 --- a/xen/arch/x86/mm/shadow/multi.h +++ b/xen/arch/x86/mm/shadow/multi.h @@ -73,13 +73,13 @@ SHADOW_INTERNAL_NAME(sh_clear_shadow_entry, GUEST_LEVELS) extern int SHADOW_INTERNAL_NAME(sh_remove_l1_shadow, GUEST_LEVELS) - (struct vcpu *v, mfn_t sl2mfn, mfn_t sl1mfn); + (struct domain *d, mfn_t sl2mfn, mfn_t sl1mfn); extern int SHADOW_INTERNAL_NAME(sh_remove_l2_shadow, GUEST_LEVELS) - (struct vcpu *v, mfn_t sl3mfn, mfn_t sl2mfn); + (struct domain *d, mfn_t sl3mfn, mfn_t sl2mfn); extern int SHADOW_INTERNAL_NAME(sh_remove_l3_shadow, GUEST_LEVELS) - (struct vcpu *v, mfn_t sl4mfn, mfn_t sl3mfn); + (struct domain *d, mfn_t sl4mfn, mfn_t sl3mfn); #if SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES int -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |