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

Re: [PATCH v2 01/14] x86/domain_page: introduce IRQs-off variants of {,un}map_domain_page()


  • To: George Dunlap <dunlapg@xxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 3 Sep 2026 16:07:33 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Transfer-Encoding:Content-Type:In-Reply-To:Autocrypt:From:Content-Language:References:Cc:To:Subject:User-Agent:MIME-Version:Date:Message-ID"
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: George Dunlap <gwd@xxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>, Alejandro Vallejo <agarciav@xxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 03 Sep 2026 14:07:49 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 02.09.2026 11:43, George Dunlap wrote:
> From: George Dunlap <gwd@xxxxxxxxxxxxxx>
> 
> 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@xxxxxxxxxxxxxx>

Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
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



 


Rackspace

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