All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: George Dunlap <dunlapg@umich.edu>
Cc: "George Dunlap" <gwd@xenproject.org>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Roger Pau Monné" <roger@xenproject.org>,
	"Alejandro Vallejo" <agarciav@amd.com>,
	"Teddy Astie" <teddy.astie@vates.tech>,
	"Anthony PERARD" <anthony.perard@vates.tech>,
	"Michal Orzel" <michal.orzel@amd.com>,
	"Julien Grall" <julien@xen.org>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	xen-devel@lists.xenproject.org
Subject: Re: [PATCH v2 01/14] x86/domain_page: introduce IRQs-off variants of {,un}map_domain_page()
Date: Thu, 3 Sep 2026 16:07:33 +0200	[thread overview]
Message-ID: <918e1522-3028-4d8c-9ba3-1c679b61861a@suse.com> (raw)
In-Reply-To: <20260901-asi-part2-1-ecc269f268b7@xenproject.org>

On 02.09.2026 11:43, George Dunlap wrote:
> From: George Dunlap <gwd@xenproject.org>
> 
> Currently, map_domain_page() cannot be called in the context switch
> path.  However, Xen already needs to update the slot of an incoming PV
> vcpu's GDT during context switch; and when we soon switch to per-vCPU
> root pagetables, we'll have to modify two more places.
> 
> Xen currently solves the problem by special-casing the GDT/LDT L1
> tables to be allocated from the xenheap, and stashing a pointer to its
> address in the xenheap in the domain struct.  Rather than add more Xen
> pagetable pages to the xenheap, introduce a version of map_domain_page
> which can be called from the context switch path.
> 
> The reason map_domain_page() cannot be called from the context switch
> path is x86's lazy context-switch state.  Mapcache mappings are
> created in the page-tables that are loaded on the pCPU.  When Xen is
> in a lazy context-switch state, current is the idle vCPU while the
> previously-running vCPU's page-tables remain loaded.  If in this
> state, another pcpu wants access to the lazily-swapped-out vcpu's
> state, it will send a FLUSH_VCPU_STATE IPI to the processor, which
> will call sync_local_execstate().
> 
> sync_local_execstate() is implemented internally by calling a full
> __context_switch().  In addition to copying the processor state into
> the vcpu structure, this also switches the loaded pagetables to the
> idle vcpu's, which would in turn cause mappings created before the IPI
> to disappear mid-use.  Therefore, mappings cannot be held in the
> mapcache when a FLUSH_VCPU_STATE IPI may execute.  To this end,
> map_domain_page() calls sync_local_execstate() itself proactively when
> it detects a lazy context-switch state.  This guarantees that the
> pagetables will remain consistent at least until the next context
> switch.
> 
> But of course, that synchronization must not be triggered from the
> context switch path itself: sync_local_execstate() ends up in
> __context_switch(), so a call made while a context switch is in
> progress would recurse, and the assertions along that path (current
> being the idle vCPU) don't hold there either.
> 
> A full synchronization is sufficient to prevent a FLUSH_VCPU_STATE IPI
> from switching the pagetables; however, it is not necessary.  It
> suffices to maintain interrupts disabled from before the page is
> mapped until after it is unmapped.  This condition is satisfied for
> the mappings used on the context switch path.
> 
> Introduce {,un}map_domain_page_irqoff() variants for callers which
> guarantee that interrupts remain disabled from the map until the
> matching unmap.  Under that guarantee the synchronization is
> unnecessary rather than merely inconvenient: no IPI can be delivered
> while the mapping is in use, so the lazy state cannot change under the
> caller's feet, and this_cpu(pgtable_vcpu) accurately identifies the
> mapcache to use (see 622c9a5ba95d "x86/mm: accurately track which vCPU
> page-tables are loaded").  The variants assert that interrupts are
> disabled on entry; the rest of the contract remains the caller's
> responsibility.
> 
> This will be used by the next patch, which introduces a function which
> will be used to modify the incoming vCPU's per-domain mappings from
> within __context_switch(); it will also be used in future ASI
> patches (tearing down and establishing per-CPU stack mappings during
> context switch).
> 
> No functional change for existing callers.
> 
> Assisted-by: Claude Code:claude-fable-5
> Signed-off-by: George Dunlap <gwd@xenproject.org>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one aspect for further consideration:

> @@ -59,7 +68,7 @@ static inline struct vcpu *mapcache_current_vcpu(void)
>  #define MAPCACHE_L1ENT(idx) \
>      __linear_l1_table[l1_linear_offset(MAPCACHE_VIRT_START + pfn_to_paddr(idx))]
>  
> -void *map_domain_page(mfn_t mfn)
> +static void *do_map_domain_page(mfn_t mfn, bool irqs_off)
>  {

do_...() commonly (but sadly not consistently) mark top-level hypercall
handlers. Personally I'd prefer if the "do" (but not the underscore) were
dropped here and ...

> @@ -165,7 +174,19 @@ void *map_domain_page(mfn_t mfn)
>      return (void *)MAPCACHE_VIRT_START + pfn_to_paddr(idx);
>  }
>  
> -void unmap_domain_page(const void *ptr)
> +void *map_domain_page(mfn_t mfn)
> +{
> +    return do_map_domain_page(mfn, false);
> +}
> +
> +void *map_domain_page_irqoff(mfn_t mfn)
> +{
> +    ASSERT(!local_irq_is_enabled());
> +
> +    return do_map_domain_page(mfn, true);
> +}
> +
> +static void do_unmap_domain_page(const void *ptr, bool irqs_off)

... here. Identifiers with a single leading underscore (and no following
upper-case letter) are designated for use by static functions, after all.

Jan


  reply	other threads:[~2026-09-03 14:08 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02  9:43 [PATCH v2 00/14] x86: Address Space Isolation, part 2: asi= option and per-vCPU page tables George Dunlap
2026-09-02  9:43 ` [PATCH v2 01/14] x86/domain_page: introduce IRQs-off variants of {,un}map_domain_page() George Dunlap
2026-09-03 14:07   ` Jan Beulich [this message]
2026-09-03 19:56     ` George Dunlap
2026-09-02  9:43 ` [PATCH v2 02/14] x86/mm: introduce populate_perdomain_mapping() George Dunlap
2026-09-03 15:57   ` Jan Beulich
2026-09-03 21:27     ` George Dunlap
2026-09-04  5:58       ` Jan Beulich
2026-09-04  5:47   ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 03/14] x86/pv: use populate_perdomain_mapping() to map the Xen GDT George Dunlap
2026-09-03 16:11   ` Jan Beulich
2026-09-03 22:35     ` George Dunlap
2026-09-04  6:00       ` Jan Beulich
2026-09-04  6:54         ` Jürgen Groß
2026-09-04  8:06           ` George Dunlap
2026-09-04  8:29             ` Jan Beulich
2026-09-04  8:50               ` George Dunlap
2026-09-04 10:11                 ` Jan Beulich
2026-09-04 10:34                 ` Roger Pau Monné
2026-09-07 13:58                   ` George Dunlap
2026-09-02  9:43 ` [PATCH v2 04/14] x86/pv: set/clear guest GDT mappings using populate_perdomain_mapping() George Dunlap
2026-09-07 12:50   ` Jan Beulich
2026-09-07 13:51     ` George Dunlap
2026-09-07 14:57       ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 05/14] x86/pv: update guest LDT mappings using {populate,destroy}_perdomain_mapping() George Dunlap
2026-09-07 16:06   ` Jan Beulich
2026-09-09 19:29     ` George Dunlap
2026-09-02  9:43 ` [PATCH v2 06/14] x86/pv: remove stashing of GDT/LDT L1 page-tables George Dunlap
2026-09-08 14:29   ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 07/14] x86/mm: simplify create_perdomain_mapping() interface George Dunlap
2026-09-08 14:39   ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 08/14] x86/mm: purge unneeded destroy_perdomain_mapping() George Dunlap
2026-09-08 15:03   ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 09/14] x86/mm: prepare destroy_perdomain_mapping() for per-vCPU perdomain areas George Dunlap
2026-09-08 15:36   ` Jan Beulich
2026-09-10 11:38     ` George Dunlap
2026-09-10 11:54       ` Jan Beulich
2026-09-02  9:43 ` [PATCH v2 10/14] x86/domain_page: drop redundant create_perdomain_mapping() call George Dunlap
2026-09-08 15:55   ` Jan Beulich
2026-09-10 11:52     ` George Dunlap
2026-09-02  9:43 ` [PATCH v2 11/14] x86/mm: prepare create_perdomain_mapping() for per-vCPU perdomain areas George Dunlap
2026-09-02  9:43 ` [PATCH v2 12/14] x86/spec-ctrl: introduce Address Space Isolation command line option George Dunlap
2026-09-02  9:43 ` [PATCH v2 13/14] x86/pv: clear the XPTI root_pgt per-domain slot on context-switch out George Dunlap
2026-09-02  9:43 ` [PATCH v2 14/14] x86/mm: introduce per-vCPU L3 page-table George Dunlap

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=918e1522-3028-4d8c-9ba3-1c679b61861a@suse.com \
    --to=jbeulich@suse.com \
    --cc=agarciav@amd.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@vates.tech \
    --cc=dunlapg@umich.edu \
    --cc=gwd@xenproject.org \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=roger@xenproject.org \
    --cc=sstabellini@kernel.org \
    --cc=teddy.astie@vates.tech \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.