[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 0/7] x86: Address Space Isolation, part 1: per-domain area mapping rework



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/20240726152206.28411-1-roger.pau@xxxxxxxxxx/
[2] 
https://lore.kernel.org/xen-devel/20250108142659.99490-1-roger.pau@xxxxxxxxxx/

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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.