|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 02/45] x86/mm: refuse to promote an L4 while the domain has no per-domain L3
On Thu, Oct 29, 2026 at 7:47 AM Jan Beulich <jbeulich@xxxxxxxx> wrote:
>
> On 29.10.2026 00:05, George Dunlap wrote:
> > init_xen_l4_slots() puts the domain's per-domain L3 in slot 260 of the
> > L4s it fills. Since fcf91ce9de66 ("x86/pv: don't populate the GDT/LDT
> > L3 slot at domain creation") a PV domain gets that L3 with its first
> > vCPU (pv_create_gdt_ldt_l1tab()). Only mapcache_domain_init() makes it
> > earlier, with the domain, and release builds skip that unless memory
> > hotplug is enabled or the host's memory reaches past the part of the
> > directmap PV guests can see. So in release builds on most hosts, an L4
> > that is promoted before XEN_DOMCTL_max_vcpus has created the domain's
> > vCPUs gets a slot 260 entry made from a NULL page (0x803e900000000063),
> > pointing far beyond the host's memory.
> >
> > Have promote_l4_table() return -EINVAL while the domain has no
> > per-domain L3, before taking any reference. The other callers of
> > init_xen_l4_slots() all run once the L3 exists; have init_xen_l4_slots()
> > check that with a BUG_ON(). An ASSERT() would not do: the case above
> > arises only in release builds. libxl is unaffected: it creates the
> > vCPUs before it builds or restores a domain.
>
> Isn't setup_compat_l4() similarly affected? XEN_DOMCTL_set_address_size
> may (in principle) be issued ahead of the domain having any vCPU-s.
setup_compat_l4() is called in a for_each_vcpu loop, so can't be run
if there are no vCPUs.
> Independent of that, how about pulling hvm_domain_initialise()'s
> create_perdomain_mapping() up into arch_domain_create() instead of the
> code additions you do?
So, let's see if we can solve it "properly". Constraints:
- Eventually, not all domains will have a domain-wide L3; some will
only have per-vCPU L3s.
- init_xen_l4_slots needs a domain always, but only needs a vcpu to
get the L3 of vcpu_pt domains.
- PV vcpu_pt domains don't need an L3 installed after
init_xen_l4_slots; they need to run on a clone of the L4 anyway.
So by the end of the series, we could arrange it like this:
non-vcpu_pt domains always allocate d->arch.l3_perdomain in
arch_domain_create. vcpu_pt domains always allocate
v->arch.l3_perdomain in arch_vcpu_create.
Have __init_xen_l4_slots() take a domain and an L3; if the L3 is NULL,
leave the perdomain slot empty.
Have init_xen_l4_slots() take a vcpu. BUG_ON(is_hvm_vcpu(v) &&
v->arch.asi.vcpu_pt && !v->arch.l3_perdomain), then pass the
appropriate l3 into __init_xen_l4_slots().
Have init_xen_l4_slots_pv() take a domain, and always pass the domain
and d->arch.l3_perdomain to __init_xen_l4_slots. This will be NULL
for PV vcpu_pt domains, but that's fine.
Then promote_l4_table() calls init_xen_l4_slots_pv() with a domain,
and loses both the checks at the top.
There are corner cases to sort out, like how idle domains get an L3;
but overall I think this makes everything more robust.
Thoughts?
-George
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |