unsigned int partial_flags = page->partial_flags;
l3_pgentry_t l3e = l3e_empty();
+ /*
+ * PAE pgdirs above 4GB are unacceptable if a 32-bit guest does not
+ * understand the weird 'extended cr3' format for dealing with high-order
+ * address bits. We cut some slack for control tools (before vcpu0 is
+ * initialised).
+ */
+ if ( is_pv_32bit_domain(d) &&
+ unlikely(!VM_ASSIST(d, pae_extended_cr3)) &&
+ mfn_x(l3mfn) >= PFN_DOWN(GB(4)) &&
+ d->vcpu[0] && d->vcpu[0]->is_initialised )
+ {
+ gdprintk(XENLOG_WARNING,
+ "PAE pgd must be below 4GB (%#lx >= 0x100000)",
+ mfn_x(l3mfn));
+ return -ERANGE;
+ }
+
pl3e = map_domain_page(l3mfn);
/*
nr_pages = dom0_compute_nr_pages(d, &parms, initrd_len);
- if ( parms.pae == XEN_PAE_EXTCR3 )
- set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
-
#ifdef CONFIG_PV32
if ( elf_32bit(&elf) )
{
+ if ( parms.pae == XEN_PAE_EXTCR3 )
+ __set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
+
if ( !pv_shim && (parms.virt_hv_start_low != UNSET_ADDR) )
{
unsigned long value = ROUNDUP(parms.virt_hv_start_low,
vphysmap_start = parms.p2m_base;
vphysmap_end = vphysmap_start + nr_pages * sizeof(unsigned long);
}
- page = alloc_domheap_pages(d, order, MEMF_no_scrub);
+ page = alloc_domheap_pages(d, order,
+ MEMF_no_scrub |
+ (VM_ASSIST(d, pae_extended_cr3) ||
+ !compat ? 0 : MEMF_bits(32)));
if ( page == NULL )
panic("Not enough RAM for domain 0 allocation\n");
alloc_spfn = mfn_x(page_to_mfn(page));