> Jan Beulich > 14 March 2014 15:23 > 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; This logic took a few looks to be sure what it was doing, let alone correct. Without the patch comment I'd be even a bit more lost. I think the changeset comment, or similar, should be included as a code comment for this new function. I'm sure given there is only one hole there is a simpler form of this based on checking whether bottom_shift > 44. But this is more general I suppose, so probably better despite being harder to understand. Acked-by: Keir Fraser > + 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)); > > >