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

From: Ashish Kalra

Date: Tue Oct 13 2026 - 16:27:58 EST


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 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>
---

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();
}

--
2.43.0