setup_max_pdx(raw_max_page);
if ( highmem_start )
- xenheap_max_mfn(PFN_DOWN(highmem_start));
+ xenheap_max_mfn(PFN_DOWN(highmem_start - 1));
/*
* Walk every RAM region and map it in its entirety (on x86/64, at least)
numa_initmem_init(0, raw_max_page);
- end_boot_allocator();
- system_state = SYS_STATE_boot;
-
if ( max_page - 1 > virt_to_mfn(HYPERVISOR_VIRT_END - 1) )
{
unsigned long limit = virt_to_mfn(HYPERVISOR_VIRT_END - 1);
if ( !highmem_start )
xenheap_max_mfn(limit);
+ end_boot_allocator();
+
/* Pass the remaining memory to the allocator. */
for ( i = 0; i < boot_e820.nr_map; i++ )
{
opt_tmem = 0;
}
}
+ else
+ end_boot_allocator();
+
+ system_state = SYS_STATE_boot;
vm_init();
console_init_ring();
spin_unlock(&heap_lock);
}
+static bool_t __read_mostly first_node_initialised;
+#ifndef CONFIG_SEPARATE_XENHEAP
+static unsigned int __read_mostly xenheap_bits;
+#else
+#define xenheap_bits 0
+#endif
+
static unsigned long init_node_heap(int node, unsigned long mfn,
unsigned long nr, bool_t *use_tail)
{
/* First node to be discovered has its heap metadata statically alloced. */
static heap_by_zone_and_order_t _heap_static;
static unsigned long avail_static[NR_ZONES];
- static int first_node_initialised;
unsigned long needed = (sizeof(**_heap) +
sizeof(**avail) * NR_ZONES +
PAGE_SIZE - 1) >> PAGE_SHIFT;
}
#ifdef DIRECTMAP_VIRT_END
else if ( *use_tail && nr >= needed &&
- (mfn + nr) <= (virt_to_mfn(eva - 1) + 1) )
+ (mfn + nr) <= (virt_to_mfn(eva - 1) + 1) &&
+ (!xenheap_bits ||
+ !((mfn + nr - 1) >> (xenheap_bits - PAGE_SHIFT))) )
{
_heap[node] = mfn_to_virt(mfn + nr - needed);
avail[node] = mfn_to_virt(mfn + nr - 1) +
PAGE_SIZE - sizeof(**avail) * NR_ZONES;
}
else if ( nr >= needed &&
- (mfn + needed) <= (virt_to_mfn(eva - 1) + 1) )
+ (mfn + needed) <= (virt_to_mfn(eva - 1) + 1) &&
+ (!xenheap_bits ||
+ !((mfn + needed - 1) >> (xenheap_bits - PAGE_SHIFT))) )
{
_heap[node] = mfn_to_virt(mfn);
avail[node] = mfn_to_virt(mfn + needed - 1) +
#else
-static unsigned int __read_mostly xenheap_bits;
-
void __init xenheap_max_mfn(unsigned long mfn)
{
- xenheap_bits = flsl(mfn) + PAGE_SHIFT;
+ ASSERT(!first_node_initialised);
+ ASSERT(!xenheap_bits);
+ BUILD_BUG_ON(PADDR_BITS >= BITS_PER_LONG);
+ xenheap_bits = min(flsl(mfn + 1) - 1 + PAGE_SHIFT, PADDR_BITS);
+ printk(XENLOG_INFO "Xen heap: %u bits\n", xenheap_bits);
}
void init_xenheap_pages(paddr_t ps, paddr_t pe)