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

From: Ashish Kalra

Date: Wed Oct 14 2026 - 17:15:06 EST


From: Ashish Kalra <ashish.kalra@xxxxxxx>

Segmented RMP has two independent states: the CPU *advertises* support via
the X86_FEATURE_SEGMENTED_RMP CPUID bit, and the firmware *enables* it via
MSR_AMD64_RMP_CFG[SEG_RMP_ENABLED]. A platform can advertise segmented RMP
(CPUID bit set) while the firmware leaves it disabled (SEG_RMP_ENABLED
clear) -- e.g. through a BIOS option to disable Segmented RMP -- in which
case the system runs with a contiguous RMP.

snp_probe_rmptable_info() clears X86_FEATURE_RMPOPT only when the CPU does
not advertise segmented RMP, or when the segmented RMP table probe fails.
It misses the advertised-but-firmware-disabled case: 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".

Fixes: 15d974be0a3b ("x86/sev: Initialize RMPOPT configuration MSRs")
Signed-off-by: Ashish Kalra <ashish.kalra@xxxxxxx>
Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>
---

Note: 15d974be0a3b as applied narrowed the contiguous fall-through clear
into an else branch, dropping the "SEGMENTED_RMP advertised but disabled by
firmware" case the posted series (v16 3/5) covered; this restores it.
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