[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/shadow: move OOS flag bit positions
commit d68e1070c3e8f4af7a31040f08bdd98e6d6eac1d Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Nov 20 14:59:13 2018 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Nov 20 14:59:13 2018 +0100 x86/shadow: move OOS flag bit positions In preparation of reducing struct page_info's shadow_flags field to 16 bits, lower the bit positions used for SHF_out_of_sync and SHF_oos_may_write. Instead of also adjusting the open coded use in _get_page_type(), introduce shadow_prepare_page_type_change() to contain knowledge of the bit positions to shadow code. This is part of XSA-280. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Tim Deegan <tim@xxxxxxx> --- xen/arch/x86/mm.c | 13 ++----------- xen/arch/x86/mm/shadow/common.c | 23 +++++++++++++++++++++++ xen/arch/x86/mm/shadow/private.h | 4 ++-- xen/include/asm-x86/shadow.h | 8 ++++++++ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 1545baf20b..126a4d2ef5 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2709,17 +2709,8 @@ static int _get_page_type(struct page_info *page, unsigned long type, { struct domain *d = page_get_owner(page); - /* - * Normally we should never let a page go from type count 0 - * to type count 1 when it is shadowed. One exception: - * out-of-sync shadowed pages are allowed to become - * writeable. - */ - if ( d && shadow_mode_enabled(d) - && (page->count_info & PGC_page_table) - && !((page->shadow_flags & (1u<<29)) - && type == PGT_writable_page) ) - shadow_remove_all_shadows(d, page_to_mfn(page)); + if ( d && shadow_mode_enabled(d) ) + shadow_prepare_page_type_change(d, page, type); ASSERT(!(x & PGT_pae_xen_l2)); if ( (x & PGT_type_mask) != type ) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index d54a848919..958a4b7fbe 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -749,6 +749,9 @@ int sh_unsync(struct vcpu *v, mfn_t gmfn) || !v->domain->arch.paging.shadow.oos_active ) return 0; + BUILD_BUG_ON(!(typeof(pg->shadow_flags))SHF_out_of_sync); + BUILD_BUG_ON(!(typeof(pg->shadow_flags))SHF_oos_may_write); + pg->shadow_flags |= SHF_out_of_sync|SHF_oos_may_write; oos_hash_add(v, gmfn); perfc_incr(shadow_unsync); @@ -2413,6 +2416,26 @@ void sh_remove_shadows(struct domain *d, mfn_t gmfn, int fast, int all) paging_unlock(d); } +void shadow_prepare_page_type_change(struct domain *d, struct page_info *page, + unsigned long new_type) +{ + if ( !(page->count_info & PGC_page_table) ) + return; + +#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) + /* + * Normally we should never let a page go from type count 0 to type + * count 1 when it is shadowed. One exception: out-of-sync shadowed + * pages are allowed to become writeable. + */ + if ( (page->shadow_flags & SHF_oos_may_write) && + new_type == PGT_writable_page ) + return; +#endif + + shadow_remove_all_shadows(d, page_to_mfn(page)); +} + static void sh_remove_all_shadows_and_parents(struct domain *d, mfn_t gmfn) /* Even harsher: this is a HVM page that we thing is no longer a pagetable. diff --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h index a1fae50929..701ab494df 100644 --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -285,8 +285,8 @@ static inline void sh_terminate_list(struct page_list_head *tmp_list) * codepath is called during that time and is sensitive to oos issues, it may * need to use the second flag. */ -#define SHF_out_of_sync (1u<<30) -#define SHF_oos_may_write (1u<<29) +#define SHF_out_of_sync (1u << (SH_type_max_shadow + 1)) +#define SHF_oos_may_write (1u << (SH_type_max_shadow + 2)) #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) */ diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index de1bae1108..0d9f6632e7 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -81,6 +81,10 @@ void shadow_final_teardown(struct domain *d); void sh_remove_shadows(struct domain *d, mfn_t gmfn, int fast, int all); +/* Adjust shadows ready for a guest page to change its type. */ +void shadow_prepare_page_type_change(struct domain *d, struct page_info *page, + unsigned long new_type); + /* Discard _all_ mappings from the domain's shadows. */ void shadow_blow_tables_per_domain(struct domain *d); @@ -105,6 +109,10 @@ int shadow_set_allocation(struct domain *d, unsigned int pages, static inline void sh_remove_shadows(struct domain *d, mfn_t gmfn, int fast, int all) {} +static inline void shadow_prepare_page_type_change(struct domain *d, + struct page_info *page, + unsigned long new_type) {} + static inline void shadow_blow_tables_per_domain(struct domain *d) {} static inline int shadow_domctl(struct domain *d, -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |