|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86/PV32: restore PAE-extended-CR3 logic
commit a773adedbd913966e812bddcd6b223c2e4ce3061
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon Feb 12 09:37:18 2024 +0100
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Feb 12 09:37:18 2024 +0100
x86/PV32: restore PAE-extended-CR3 logic
While the PAE-extended-CR3 VM assist is a 32-bit only concept, it still
applies to guests also when run on a 64-bit hypervisor: The "extended
CR3" format has to be used there as well, to fit the address in the only
32-bit wide register there. As a result it was a mistake that the check
was never enabled for that case, and was then mistakenly deleted in the
course of removal of 32-bit-Xen code (218adf199e68 ["x86: We can assume
CONFIG_PAGING_LEVELS==4"]).
Similarly during Dom0 construction kernel awareness needs to be taken
into account, and respective code was again mistakenly never enabled for
32-bit Dom0 when running on 64-bit Xen (and thus wrongly deleted by
5d1181a5ea5e ["xen: Remove x86_32 build target"]).
At the same time restrict enabling of the assist for Dom0 to just the
32-bit case. Furthermore there's no need for an atomic update there.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
xen/arch/x86/mm.c | 17 +++++++++++++++++
xen/arch/x86/pv/dom0_build.c | 11 +++++++----
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index b56e0d8065..4d6d7bfe4f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1504,6 +1504,23 @@ static int promote_l3_table(struct page_info *page)
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);
/*
diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
index 5bbed3a36a..16d08c6796 100644
--- a/xen/arch/x86/pv/dom0_build.c
+++ b/xen/arch/x86/pv/dom0_build.c
@@ -495,12 +495,12 @@ int __init dom0_construct_pv(struct domain *d,
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,
@@ -599,7 +599,10 @@ int __init dom0_construct_pv(struct domain *d,
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));
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |