[PATCH 0/7] x86: Address Space Isolation, part 1: per-domain area mapping rework
George Dunlap <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <[email protected]> |
This is the first batch of patches continuing the x86 Address Space
Isolation (ASI) work that Roger posted as "x86: adventures in Address
Space Isolation" (v1 [1], v2 [2]). I've taken over finishing it up
and getting it upstream.
Rather than re-posting the whole stack (nearly 60 patches) each time,
I'd like to run this as a rolling series: post a reviewable slice from
the front, drop patches as they are committed, and append the next
ones as they mature. Each batch should stand on its own; the cover
letter of each will say where it sits in the larger picture.
A "map" of the entire series -- grouped into logical chunks, with the
dependencies between patches -- is maintained here:
https://xenbits.xenproject.org/people/gdunlap/asi-series-deps.html
Note that the graph above is a work in progress; dependency lines may
change as more of the series is vetted. Note also that the full
series includes a design doc as patch 1; that's not ready for
publication yet, so patches 1-7 of this series correspond to nodes 2-8
of the graph.
The problem this slice addresses: the per-domain area already has
central machinery for building its page-tables and for managing the
backing pages it owns itself (create_perdomain_mapping() and friends);
what it lacks is a way to install a caller's own pages at a chosen
address. The PV GDT and LDT code fills that gap privately, by having
create_perdomain_mapping() hand back aliases of the L1 tables it
builds and stashing them in d->arch.pv.gdt_ldt_l1tab; mapping updates
are then written through the stash, bypassing the interface. That
arrangement assumes a single, domain-wide set of per-domain
page-tables, which stops holding once the per-domain area becomes
per-vCPU (the next slices).
This slice closes the gap centrally:
- Patch 1 moves the per-domain page-table allocations from the
domheap to the xenheap. The page-tables (not the data pages they
map) are then reachable through their always-mapped alias from any
context, so walking them needs no mapcache -- including from the
context switch.
- Patch 2 introduces populate_perdomain_mapping() on top: a single
writer for the per-domain area, installing caller-owned pages at a
chosen address by walking the always-mapped page-tables.
- Patches 3-5 convert the Xen-GDT slot, the guest GDT, and the guest
LDT paths to it.
- Patch 6 removes the stash. Patch 7 simplifies
create_perdomain_mapping(), whose L1-capture mode existed only to
build the stash.
One point reviewers may want to look at specifically: patch 1 changes
where the per-domain page-tables are allocated from, and its commit
message discusses the (minor) NUMA-placement consequence.
Relative to v2: patch 1 is new -- v2 kept the page-tables in the
domheap and walked them through map_domain_page(), with a linear-map
fast path for the currently-running vCPU; making the page-tables
always-mapped lets one plain walk serve every caller and context, and
the context switch keeps its existing structure. The populate patch
is split from its first user; the LDT demand-map now goes through
populate_perdomain_mapping() rather than writing linear entries;
pv_destroy_gdt() keeps mapping torn-down slots read-only to the zero
page (in v2 they became empty -- a guest-visible partial revert of
cf6d39f819); and the domain -> vCPU parameter switches move to the
next slice. Per-patch changes are noted below each patch's "---".
Testing:
- Each patch builds (x86_64, CONFIG_DEBUG=y); tier-1 qemu boot at
the tip.
- The series passes the Xen GitLab CI pipeline, including the
hardware runner:
https://gitlab.com/xen-project/hardware/xen-staging/-/pipelines/2776674713
- On an Intel NUC, debug build: XTF pv64 and pv32pae suites (the
latter with cet=no-shstk,no-ibt pv=32, since CET disables PV32);
plus an LDT exerciser in a PV Linux guest (modify_ldt() with 1-16
page LDTs, demand-faulting every page, LAR beyond the limit,
shrinking, teardown; also with the guest's vCPUs bounced across
pCPUs) -- thousands of rounds, no assertions or "unable to map"
reports.
[1] https://lore.kernel.org/xen-devel/[email protected]/
[2] https://lore.kernel.org/xen-devel/[email protected]/
George Dunlap (1):
x86/mm: allocate the per-domain page-tables from the xenheap
Roger Pau Monné (6):
x86/mm: introduce populate_perdomain_mapping()
x86/pv: use populate_perdomain_mapping() to map the Xen GDT
x86/pv: set/clear guest GDT mappings using
populate_perdomain_mapping()
x86/pv: update guest LDT mappings using
{populate,destroy}_perdomain_mapping()
x86/pv: remove stashing of GDT/LDT L1 page-tables
x86/mm: simplify create_perdomain_mapping() interface
xen/arch/x86/domain.c | 17 ++-
xen/arch/x86/domain_page.c | 10 +-
xen/arch/x86/hvm/hvm.c | 2 +-
xen/arch/x86/include/asm/desc.h | 6 +-
xen/arch/x86/include/asm/domain.h | 14 +-
xen/arch/x86/include/asm/mm.h | 9 +-
xen/arch/x86/mm.c | 225 +++++++++++++++++-----------
xen/arch/x86/pv/descriptor-tables.c | 57 ++++---
xen/arch/x86/pv/domain.c | 16 +-
xen/arch/x86/pv/mm.c | 16 +-
xen/arch/x86/smpboot.c | 14 +-
xen/arch/x86/traps.c | 4 +-
xen/arch/x86/x86_64/mm.c | 3 +-
13 files changed, 221 insertions(+), 172 deletions(-)
base-commit: 669f8c502aeaa538f8407013ba04461e71361ed4
--
2.55.0