From: "Roger Pau Monné" <roger@xenproject.org>
To: George Dunlap <gwd@xenproject.org>
Cc: xen-devel@lists.xenproject.org,
"Roger Pau Monné" <roger.pau@citrix.com>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Anthony PERARD" <anthony.perard@vates.tech>,
"Michal Orzel" <michal.orzel@amd.com>,
"Jan Beulich" <jbeulich@suse.com>,
"Julien Grall" <julien@xen.org>,
"Stefano Stabellini" <sstabellini@kernel.org>,
"Teddy Astie" <teddy.astie@vates.tech>
Subject: Re: [PATCH v4 07/30] x86/spec-ctrl: introduce Address Space Isolation command line option
Date: Fri, 23 Oct 2026 09:45:41 +0200 [thread overview]
Message-ID: <atsQpSipkOwSZfX5@Mac.lan> (raw)
In-Reply-To: <20261019-asi-hvm-v4-7-b68b66652266@xenproject.org>
On Mon, Oct 19, 2026 at 08:42:38PM +0100, George Dunlap wrote:
> From: Roger Pau Monné <roger.pau@citrix.com>
>
> Introduce the `asi=` command line option, and the opt_vcpu_pt_hvm and
> opt_pvh_vcpu_pt_hwdom knobs plus the per-domain d->arch.asi.vcpu_pt
> setting they control. The option is introduced ahead of the
> functionality it enables, so that the newly added code can be keyed on
> it from the start; all knobs currently default to off, and enabling any
> of them adds a boot-time warning that the feature is not functional and
> is meant for development only.
>
> The mechanisms this option controls apply to HVM domains: an HVM vCPU
> already runs on its own monitor table, so a per-vCPU per-domain area
> needs no work at context switch. d->arch.asi.vcpu_pt is therefore only
> ever set for HVM domains, a PVH hardware domain included; PV domains,
> a PV hardware domain included, are unaffected.
>
> Besides the plain boolean, `pv=`, `hvm=` and `dom0=` select the features
> for PV domains or HVM domains other than the hardware domain, or for the
> hardware domain, PV or PVH. None of the features applies to PV domains,
> so `pv=` has no effect, and `dom0=` acts on a PVH hardware domain only.
>
> The boot log gains "ASI features for ..." lines for Dom0 and HVM
> domains, so hardware-domain-only configurations remain visible.
>
> Further per-mechanism tokens arrive with their mechanisms in later
> patches.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Assisted-by: Claude Code:claude-fable-5, Claude Code:claude-opus-4-8, Claude Code:claude-opus-5-5
> Signed-off-by: George Dunlap <gwd@xenproject.org>
I don't have a strong opinion on the comments below, I think it would
be nice to adjust some as they likely lead to less churn in the
followup patches.
> ---
> Changes in v4:
> - Docs: "domains" throughout, not "guests" (Roger).
> - Group the per-domain settings as one-bit fields of d->arch.asi
> (Roger).
> - Rename opt_vcpu_pt_hwdom to opt_pvh_vcpu_pt_hwdom: it acts on a PVH
> hardware domain only (Jan).
I would leave opt_vcpu_pt_hwdom as-is. The fact it only acts on a PVH
hardware domain is a transient implementation short-coming. I don't
think it's worth introducing a separate opt_pv_vcpu_pt_hwdom when PV
dom0 support is added, or having to rename opt_pvh_vcpu_pt_hwdom ->
opt_vcpu_pt_hwdom.
> - parse_asi(): break in the success branch and fall through to
> default:, rather than a default: label after an else (MISRA C:2012
> Rule 16.2; Jan).
> - Message: enabling a knob adds a boot-time warning; it does not taint
> (Roger).
> - Add the pv= and dom0= sub-options here, beside hvm= (Roger).
>
> Changes in v3:
> - HVM only: drop the PV knob and its interaction with XPTI. vCPU-PT
> applies to HVM domains and to a PVH hardware domain; the Dom0 boot
> log line says None for a PV one.
>
> Changes in v2:
> - Added to the series
>
> Changes since the previously posted version:
> - Include the hardware domain in the development warning and the boot
> log summary.
> - Make the opt_vcpu_pt_* knobs plain booleans preinitialised to false,
> dropping the late -1 resolution.
> - Documentation: mention possible protection against unmitigated
> attacks, and state that hvm= does not affect the hardware domain.
> - Rewrite the commit message.
> ---
> docs/misc/xen-command-line.pandoc | 29 ++++++++++
> xen/arch/x86/include/asm/domain.h | 6 ++
> xen/arch/x86/include/asm/spec_ctrl.h | 2 +
> xen/arch/x86/spec_ctrl.c | 82 ++++++++++++++++++++++++++++
> 4 files changed, 119 insertions(+)
>
> diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
> index a6f08463d1..839d06da26 100644
> --- a/docs/misc/xen-command-line.pandoc
> +++ b/docs/misc/xen-command-line.pandoc
> @@ -202,6 +202,35 @@ to appropriate auditing by Xen. Argo is disabled by default.
> This option is disabled by default, to protect domains from a DoS by a
> buggy or malicious other domain spamming the ring.
>
> +### asi (x86)
> +> `= List of [ <bool>, {pv,hvm,dom0}=<bool>,
> +> vcpu-pt=<bool> | vcpu-pt=hvm=<bool> ]`
> +
> +> Default: `false`
> +
> +Offers control over whether the hypervisor will engage in Address Space
> +Isolation, by not having potentially sensitive information permanently mapped
> +in the VMM page-tables. Using this option might avoid the need to apply
> +mitigations for certain speculative related attacks, at the cost of mapping
> +sensitive information on-demand. It might also offer some protection against
> +unmitigated speculation-related attacks.
> +
> +The mechanisms currently implemented apply to HVM domains, including a PVH
> +hardware domain. PV domains, including a PV hardware domain, are unaffected.
I think we might want to drop this. It's an incomplete in-development
feature: we don't need to mention explicitly what is and what is not
implemented in the command line documentation for the time being.
> +
> +* `pv=`, `hvm=` and `dom0=` enable the features for PV domains or HVM domains
> + other than the hardware domain, or for the hardware domain, PV or PVH. The
> + plain boolean does all three: `asi=1,dom0=0` leaves the hardware domain
> + out. The forms naming no domain type (an un-suffixed `vcpu-pt=<bool>`)
> + cover the hardware domain too.
> +
> +**WARNING: manual de-selection of enabled options will invalidate any
> +protection offered by the feature. The fine grained options provided below
> +are meant to be used for debugging purposes only.**
> +
> +* `vcpu-pt` gives each vCPU its own per-domain area: the per-domain slot of
> + each vCPU's monitor table maps a region private to that vCPU.
> +
> ### asid (x86)
> > `= <boolean>`
>
> diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
> index 212daae1f5..12f79feb42 100644
> --- a/xen/arch/x86/include/asm/domain.h
> +++ b/xen/arch/x86/include/asm/domain.h
> @@ -474,6 +474,12 @@ struct arch_domain
> /* Don't unconditionally inject #GP for unhandled MSRs. */
> bool msr_relaxed;
>
> + /* Fine grained ASI related options. */
> + struct {
> + /* Give each vCPU its own per-domain area (HVM only). */
I would drop the HVM only part, it's a transient implementation
limitation, not a design one.
> + bool vcpu_pt:1;
> + } asi;
> +
> /* Emulated devices enabled bitmap. */
> uint32_t emulation_flags;
> } __cacheline_aligned;
> diff --git a/xen/arch/x86/include/asm/spec_ctrl.h b/xen/arch/x86/include/asm/spec_ctrl.h
> index 8f82533c41..d84f985e82 100644
> --- a/xen/arch/x86/include/asm/spec_ctrl.h
> +++ b/xen/arch/x86/include/asm/spec_ctrl.h
> @@ -87,6 +87,8 @@ extern uint8_t default_scf;
>
> extern int8_t opt_xpti_hwdom, opt_xpti_domu;
>
> +extern bool opt_pvh_vcpu_pt_hwdom, opt_vcpu_pt_hvm;
> +
> extern bool cpu_has_bug_l1tf;
> extern int8_t opt_pv_l1tf_hwdom, opt_pv_l1tf_domu;
> extern bool opt_bp_spec_reduce;
> diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
> index bc8538a56f..66c878212a 100644
> --- a/xen/arch/x86/spec_ctrl.c
> +++ b/xen/arch/x86/spec_ctrl.c
> @@ -86,6 +86,10 @@ bool __ro_after_init opt_bp_spec_reduce = true;
>
> static bool __initdata opt_ibpb_alt;
>
> +/* Give each vCPU of an HVM domain its own per-domain area (vCPU-PT). */
> +bool __ro_after_init opt_vcpu_pt_hvm;
> +bool __ro_after_init opt_pvh_vcpu_pt_hwdom;
> +
> static int __init cf_check parse_spec_ctrl(const char *s)
> {
> const char *ss;
> @@ -487,6 +491,69 @@ static int __init cf_check parse_pv_l1tf(const char *s)
> }
> custom_param("pv-l1tf", parse_pv_l1tf);
>
> +static int __init cf_check parse_asi(const char *s)
> +{
> + const char *ss;
> + int val, rc = 0;
> +
> + /* Interpret 'asi' alone in its positive boolean form. */
> + if ( *s == '\0' )
> + opt_pvh_vcpu_pt_hwdom = opt_vcpu_pt_hvm = true;
> +
> + do {
> + ss = strchr(s, ',');
> + if ( !ss )
> + ss = strchr(s, '\0');
> +
> + val = parse_bool(s, ss);
> + switch ( val )
> + {
> + case 0:
> + case 1:
> + opt_pvh_vcpu_pt_hwdom = opt_vcpu_pt_hvm = val;
> + break;
> +
> + default:
> + if ( (val = parse_boolean("pv", s, ss)) >= 0 )
> + /* PV domains are unaffected. */;
You might want to print a message saying that the option is ignored
for PV? It will go into the console buffer at least.
> + else if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
> + opt_vcpu_pt_hvm = val;
> + else if ( (val = parse_boolean("dom0", s, ss)) >= 0 )
> + opt_pvh_vcpu_pt_hwdom = val;
> + else if ( (val = parse_boolean("vcpu-pt", s, ss)) != -1 )
> + {
> + switch ( val )
> + {
> + case 1:
> + case 0:
> + opt_pvh_vcpu_pt_hwdom = opt_vcpu_pt_hvm = val;
> + break;
> +
> + case -2:
> + s += strlen("vcpu-pt=");
> + if ( (val = parse_boolean("hvm", s, ss)) >= 0 )
> + {
> + opt_vcpu_pt_hvm = val;
> + break;
> + }
> + fallthrough;
> + default:
> + rc = -EINVAL;
> + break;
> + }
> + }
> + else if ( *s )
> + rc = -EINVAL;
> + break;
> + }
> +
> + s = ss + 1;
> + } while ( *ss );
> +
> + return rc;
> +}
> +custom_param("asi", parse_asi);
> +
> static void __init print_details(enum ind_thunk thunk)
> {
> unsigned int _7d0 = 0, _7d2 = 0, e8b = 0, e21a = 0, e21c = 0, max = 0, tmp;
> @@ -680,6 +747,13 @@ static void __init print_details(enum ind_thunk thunk)
> opt_pv_l1tf_hwdom ? "enabled" : "disabled",
> opt_pv_l1tf_domu ? "enabled" : "disabled");
> #endif
> +
> + printk(" ASI features for Dom0:%s\n",
> + opt_dom0_pvh && opt_pvh_vcpu_pt_hwdom ? " vCPU-PT" : " None");
> +#ifdef CONFIG_HVM
> + printk(" ASI features for HVM VMs:%s\n",
> + opt_vcpu_pt_hvm ? " vCPU-PT" : " None");
> +#endif
opt_vcpu_pt_hvm is defined unconditionally, so you might as well use:
if ( IS_ENABLED(CONFIG_HVM) )
printk(" ASI features for HVM VMs:%s\n", ...
Which is a bit nicer than the ifdefs?
> }
>
> static bool __init check_smt_enabled(void)
> @@ -1866,6 +1940,9 @@ void spec_ctrl_init_domain(struct domain *d)
> if ( pv )
> d->arch.pv.xpti = is_hardware_domain(d) ? opt_xpti_hwdom
> : opt_xpti_domu;
> +
> + d->arch.asi.vcpu_pt = !pv && (is_hardware_domain(d) ? opt_pvh_vcpu_pt_hwdom
> + : opt_vcpu_pt_hvm);
> }
>
> void __init init_speculation_mitigations(void)
> @@ -2158,6 +2235,11 @@ void __init init_speculation_mitigations(void)
> hw_smt_enabled && default_xen_spec_ctrl )
> setup_force_cpu_cap(X86_FEATURE_SC_MSR_IDLE);
>
> + if ( opt_pvh_vcpu_pt_hwdom || opt_vcpu_pt_hvm )
> + warning_add(
> + "Address Space Isolation is not functional, this option is\n"
> + "intended to be used only for development purposes.\n");
I wonder, could we add the warning in parse_asi() itself? I know if
would then also trigger for asi=0, but would avoid having to remember
to expand the condition here every time a new option is added?
Thanks, Roger.
next prev parent reply other threads:[~2026-10-23 7:46 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 19:42 [PATCH v4 00/30] ASI: HVM per-vCPU areas, sparse-view directmap, per-vCPU state area George Dunlap
2026-10-19 19:42 ` [PATCH v4 01/30] x86/PoD: map one page at a time in p2m_pod_zero_check() George Dunlap
2026-10-22 14:54 ` Roger Pau Monné
2026-10-19 19:42 ` [PATCH v4 02/30] x86/mm: refuse to promote an L4 while the domain has no vCPU George Dunlap
2026-10-23 7:05 ` Roger Pau Monné
2026-10-26 10:28 ` George Dunlap
2026-10-19 19:42 ` [PATCH v4 03/30] x86/mm: purge unneeded destroy_perdomain_mapping() George Dunlap
2026-10-19 19:42 ` [PATCH v4 04/30] x86/mm: prepare destroy_perdomain_mapping() for per-vCPU perdomain areas George Dunlap
2026-10-19 19:42 ` [PATCH v4 05/30] x86/domain_page: drop redundant create_perdomain_mapping() call George Dunlap
2026-10-19 19:42 ` [PATCH v4 06/30] x86/mm: prepare create_perdomain_mapping() for per-vCPU perdomain areas George Dunlap
2026-10-19 19:42 ` [PATCH v4 07/30] x86/spec-ctrl: introduce Address Space Isolation command line option George Dunlap
2026-10-23 7:45 ` Roger Pau Monné [this message]
2026-10-26 10:40 ` George Dunlap
2026-10-19 19:42 ` [PATCH v4 08/30] x86/mm: have init_xen_l4_slots() take a vCPU in place of the domain George Dunlap
2026-10-19 19:42 ` [PATCH v4 09/30] x86/hvm: introduce per-vCPU L3 page-table George Dunlap
2026-10-19 19:42 ` [PATCH v4 10/30] x86/domain_page: drop redundant is_pv_vcpu() checks George Dunlap
2026-10-19 19:42 ` [PATCH v4 11/30] x86/domain_page: prepare the mapcache for per-vCPU accounting George Dunlap
2026-10-19 19:42 ` [PATCH v4 12/30] x86/domain_page: move struct mapcache_vcpu to struct arch_vcpu George Dunlap
2026-10-19 19:42 ` [PATCH v4 13/30] x86/domain_page: don't unmap a mapcache entry that is not present George Dunlap
2026-10-19 19:42 ` [PATCH v4 14/30] x86/hvm: introduce per-vCPU mapcache for vCPU-PT domains George Dunlap
2026-10-19 19:42 ` [PATCH v4 15/30] x86/mm: let Xen's page-table walker operate on a given root George Dunlap
2026-10-19 19:42 ` [PATCH v4 16/30] x86/mm: build and maintain a sparse view of the directmap George Dunlap
2026-10-19 19:42 ` [PATCH v4 17/30] x86/domain_page: key the directmap fast paths on the loaded view George Dunlap
2026-10-19 19:42 ` [PATCH v4 18/30] x86/domain_page: clear a mapcache slot at its last unmap George Dunlap
2026-10-19 19:42 ` [PATCH v4 19/30] x86/mm: run guest contexts on the sparse directmap view George Dunlap
2026-10-19 19:42 ` [PATCH v4 20/30] x86/spec-ctrl: wire the sparse directmap view into the asi= option George Dunlap
2026-10-19 19:42 ` [PATCH v4 21/30] xen/xmalloc: return an emptied region after dropping the pool lock George Dunlap
2026-10-19 19:42 ` [PATCH v4 22/30] x86/mm: split a sparse directmap superpage with a page being freed George Dunlap
2026-10-19 19:42 ` [PATCH v4 23/30] x86/mm: introduce populate_perdomain_mapping() George Dunlap
2026-10-19 19:42 ` [PATCH v4 24/30] x86/mm: introduce a per-vCPU state window in the perdomain area George Dunlap
2026-10-19 19:42 ` [PATCH v4 25/30] x86/svm: introduce svm_vmcb_map() and svm_vmcb_unmap() George Dunlap
2026-10-19 19:42 ` [PATCH v4 26/30] x86/svm: clear the VMCB clean bits in svm_ctxt_switch_from() George Dunlap
2026-10-21 9:21 ` Ross Lagerwall
2026-10-21 16:02 ` George Dunlap
2026-10-21 16:57 ` Andrew Cooper
2026-10-19 19:42 ` [PATCH v4 27/30] x86/svm: restore guest debug registers in svm_do_resume() George Dunlap
2026-10-19 19:42 ` [PATCH v4 28/30] x86/svm: drop svm_vmcb_dump()'s paddr and the unused VCPU_svm_vmcb George Dunlap
2026-10-19 19:43 ` [PATCH v4 29/30] x86/svm: allocate VMCBs from the domain heap behind the vCPU state window George Dunlap
2026-10-19 19:43 ` [PATCH v4 30/30] x86/vmx: move the guest MSR load/save list off always-mapped memory 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=atsQpSipkOwSZfX5@Mac.lan \
--to=roger@xenproject.org \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=gwd@xenproject.org \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=roger.pau@citrix.com \
--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.