[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: fix determination of bit count for struct domain allocations
commit b3d2f8b2cba9fce5bc8995612d0d13fcefec7769 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Mon Mar 24 10:48:03 2014 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Mon Mar 24 10:48:03 2014 +0100 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> --- xen/arch/x86/domain.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 0d563de..b48f2dc 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -180,6 +180,28 @@ 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; + 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; + + return bits; +} + struct domain *alloc_domain_struct(void) { struct domain *d; @@ -187,7 +209,10 @@ 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 + pfn_pdx_hole_shift; + static unsigned int __read_mostly bits; + + if ( unlikely(!bits) ) + bits = _domain_struct_bits(); BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE); d = alloc_xenheap_pages(0, MEMF_bits(bits)); -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |