Re: [PATCH 1/2] x86/sev: Clear RMPOPT when segmented RMP is disabled by firmware

From: Tom Lendacky

Date: Wed Oct 14 2026 - 09:41:33 EST


On 10/13/26 10:44, Ashish Kalra wrote:
> From: Ashish Kalra <ashish.kalra@xxxxxxx>
>
> snp_probe_rmptable_info() only clears X86_FEATURE_RMPOPT when the platform
> does not advertise X86_FEATURE_SEGMENTED_RMP, or when the segmented RMP
> table probe fails. It misses the case where the platform advertises
> segmented RMP but the firmware has it disabled (MSR_AMD64_RMP_CFG's
> SEG_RMP_ENABLED bit is clear), so the system runs with a contiguous RMP:
> that path falls through to the contiguous probe with X86_FEATURE_RMPOPT
> still set.
>
> X86_FEATURE_RMPOPT is a CPUID bit advertised independently of whether
> segmented RMP is enabled, but RMPOPT requires an enabled segmented RMP.
> With the capability left set, the RMPOPT initcall programs RMPOPT_BASE and
> issues the RMPOPT instruction, both of which #GP on a contiguous RMP:
>
> unchecked MSR access error: WRMSR to 0xc0010139 ...
> general protection fault ... snp_enable_rmpopt
>
> Clear X86_FEATURE_RMPOPT on the common contiguous fall-through so it covers
> both "segmented RMP not supported" and "segmented RMP supported but
> disabled by firmware". The clear runs at BSP init before alternatives, so

The clearing of the RMPOPT feature runs at BSP initialization, before
alternatives patching, so the ...

(Not sure this last line is even really needed, though)

> the subsequent cpu_feature_enabled(X86_FEATURE_RMPOPT) checks observe it.
>
> Fixes: 15d974be0a3b ("x86/sev: Initialize RMPOPT configuration MSRs")
> Signed-off-by: Ashish Kalra <ashish.kalra@xxxxxxx>

Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>

> ---
>
> Note: this restores the snp_probe_rmptable_info() structure from the
> posted series (v16 3/5), where a single setup_clear_cpu_cap() on the
> common contiguous fall-through covered the "SEGMENTED_RMP advertised but
> disabled by firmware" case (called out in the v16 cover letter). When
> applied, 15d974be0a3b narrowed that clear into an else branch and dropped
> that case.
> arch/x86/virt/svm/sev.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
> index bd70c4d0b774..43e4945e6cdf 100644
> --- a/arch/x86/virt/svm/sev.c
> +++ b/arch/x86/virt/svm/sev.c
> @@ -827,10 +827,16 @@ bool snp_probe_rmptable_info(void)
> setup_clear_cpu_cap(X86_FEATURE_RMPOPT);
> return false;
> }
> - } else {
> - setup_clear_cpu_cap(X86_FEATURE_RMPOPT);
> }
>
> + /*
> + * Segmented RMP is either not supported on the platform or is
> + * disabled by the firmware. RMPOPT is not supported without
> + * segmented RMP, so drop the capability before it reaches the
> + * initcall and faults programming RMPOPT_BASE / issuing RMPOPT.
> + */
> + setup_clear_cpu_cap(X86_FEATURE_RMPOPT);
> +
> return probe_contiguous_rmptable_info();
> }
>