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 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -180,6 +180,19 @@ void dump_pageframe_info(struct domain * spin_unlock(&d->page_alloc_lock); } +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 +200,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));