Re: [PATCH v10 3/6] x86/sev: Disable CPU hotplug while SNP is active
From: Jethro Beekman
Date: Wed Jul 01 2026 - 05:42:10 EST
Hi Ashish,
I don't believe my concern has been addressed
https://lore.kernel.org/lkml/0df3b665-3a9c-4c46-a7aa-14388e8e1577@xxxxxxxxxxxx/
--
Jethro Beekman | CTO | Fortanix
On 2026-06-30 20:11, Ashish Kalra wrote:
> From: Ashish Kalra <ashish.kalra@xxxxxxx>
>
> While SNP is active, every memory write is checked against the RMP to
> protect SEV-SNP guest memory. A core performs these RMP checks only once
> SNP has been initialized via SNP_INIT and the SNP-enable bit in SYSCFG is
> set on that core; the firmware requires the SNP-enable bit to be set on
> every present CPU before SNP initialization. A core that is not
> SNP-enabled and not SNP-initialized performs no RMP checks at all, so
> there is no valid configuration with SNP active and any CPU exempt from
> RMP checks.
>
> The firmware determines which CPUs are present from the processor and the
> BIOS/UEFI configuration (e.g. SMT disabled in the BIOS) and enumerates
> them at SNP init; it is not aware of the OS bringing CPUs online or
> offline afterwards. SNP_INIT fails unless SnpEn is set on all CPUs, so a
> CPU that is offline at SNP init does not have SnpEn set, SNP_INIT fails,
> and there can be no SNP guest memory. OS CPU hotplug can thus diverge
> from the firmware's expectations and break SNP.
>
> Tie CPU hotplug to the SNP-enable bit: disable it in snp_prepare() before
> SNP is enabled, and re-enable it in snp_shutdown() once the firmware has
> disabled SNP. If snp_prepare() fails before enabling SNP it re-enables
> hotplug itself; once SNP is enabled hotplug stays disabled, including
> across a failed SNP_INIT and across the legacy SNP_SHUTDOWN_EX path, both
> of which leave SNP enabled. A kexec target that boots with SNP already
> enabled disables hotplug once in snp_rmptable_init(), since snp_prepare()
> bails when SNP is already enabled.
>
> This also keeps the CPU set stable for the asynchronous RMPOPT scan added
> later in this series, and ensures cpus_read_lock() in the scan is
> uncontended.
>
> Suggested-by: Thomas Lendacky <thomas.lendacky@xxxxxxx>
> Signed-off-by: Ashish Kalra <ashish.kalra@xxxxxxx>
> ---
> arch/x86/virt/svm/sev.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
> index dab6e1c290bc..04a58ac4339c 100644
> --- a/arch/x86/virt/svm/sev.c
> +++ b/arch/x86/virt/svm/sev.c
> @@ -535,6 +535,15 @@ int snp_prepare(void)
>
> clear_rmp();
>
> + /*
> + * Disable CPU hotplug before enabling SNP, so no CPU can come online
> + * without SnpEn while SNP is enabled; it is re-enabled in snp_shutdown()
> + * once SNP is disabled. Must be before cpus_read_lock():
> + * cpu_hotplug_disable() takes cpu_add_remove_lock, which nests above
> + * cpu_hotplug_lock.
> + */
> + cpu_hotplug_disable();
> +
> cpus_read_lock();
>
> if (!cpumask_equal(cpu_online_mask, cpu_present_mask)) {
> @@ -560,6 +569,10 @@ int snp_prepare(void)
> unlock:
> cpus_read_unlock();
>
> + /* Re-enable CPU hotplug; SnpEn was never set. */
> + if (ret)
> + cpu_hotplug_enable();
> +
> return ret;
> }
> EXPORT_SYMBOL_FOR_MODULES(snp_prepare, "ccp");
> @@ -587,6 +600,13 @@ void snp_shutdown(void)
>
> rmpopt_cleanup();
>
> + /*
> + * Re-enable CPU hotplug now that the firmware has disabled SNP; CPU
> + * hotplug is not re-enabled for a legacy SNP shutdown. After
> + * rmpopt_cleanup() so RMPOPT_BASE is cleared with hotplug still disabled.
> + */
> + cpu_hotplug_enable();
> +
> clear_rmp();
> on_each_cpu(mfd_reconfigure, NULL, 1);
> }
> @@ -645,6 +665,8 @@ EXPORT_SYMBOL_FOR_MODULES(snp_setup_rmpopt, "ccp");
> */
> int __init snp_rmptable_init(void)
> {
> + u64 val;
> +
> if (WARN_ON_ONCE(!cc_platform_has(CC_ATTR_HOST_SEV_SNP)))
> return -ENOSYS;
>
> @@ -654,6 +676,15 @@ int __init snp_rmptable_init(void)
> if (!setup_rmptable())
> return -ENOSYS;
>
> + /*
> + * On a kexec boot SNP may already be enabled (legacy firmware leaves
> + * SnpEn set across shutdown), in which case snp_prepare() bails without
> + * disabling CPU hotplug, so disable it here.
> + */
> + rdmsrq(MSR_AMD64_SYSCFG, val);
> + if (val & MSR_AMD64_SYSCFG_SNP_EN)
> + cpu_hotplug_disable();
> +
> /*
> * Setting crash_kexec_post_notifiers to 'true' to ensure that SNP panic
> * notifier is invoked to do SNP IOMMU shutdown before kdump.
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature