[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.2] x86: fix determination of bit count for struct domain allocations
commit 2bd02cd208f9e644409fb5a1041efc14f09426b0 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Apr 9 11:39:08 2014 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Apr 9 11:39:08 2014 +0200 x86: fix determination of bit count for struct domain allocations We can't just add in the hole shift value, as the hole may be at or above the 44-bit boundary. Instead we need to determine the total bit count until reaching 32 significant (not squashed out) bits in PFN representations. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> master commit: b3d2f8b2cba9fce5bc8995612d0d13fcefec7769 master date: 2014-03-24 10:48:03 +0100 --- xen/arch/x86/domain.c | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2dfea87..fdf550f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -181,6 +181,30 @@ void dump_pageframe_info(struct domain *d) spin_unlock(&d->page_alloc_lock); } +/* + * The hole may be at or above the 44-bit boundary, so we need to determine + * the total bit count until reaching 32 significant (not squashed out) bits + * in PFN representations. + * Note that the way "bits" gets initialized/updated/bounds-checked guarantees + * that the function will never return zero, and hence will never be called + * more than once (which is important due to it being deliberately placed in + * .init.text). + */ +static unsigned int __init noinline _domain_struct_bits(void) +{ + unsigned int bits = 32 + PAGE_SHIFT; +#ifdef __x86_64__ + unsigned int sig = hweight32(~pfn_hole_mask); + unsigned int mask = pfn_hole_mask >> 32; + + for ( ; bits < BITS_PER_LONG && sig < 32; ++bits, mask >>= 1 ) + if ( !(mask & 1) ) + ++sig; +#endif + + return bits; +} + struct domain *alloc_domain_struct(void) { struct domain *d; @@ -188,11 +212,11 @@ struct domain *alloc_domain_struct(void) * We pack the PDX of the domain structure into a 32-bit field within * the page_info structure. Hence the MEMF_bits() restriction. */ - unsigned int bits = 32 + PAGE_SHIFT; + static unsigned int __read_mostly bits; + + if ( unlikely(!bits) ) + bits = _domain_struct_bits(); -#ifdef __x86_64__ - bits += pfn_pdx_hole_shift; -#endif BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE); d = alloc_xenheap_pages(0, MEMF_bits(bits)); if ( d != NULL ) -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.2 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |