public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Nikunj A Dadhania <nikunj@amd.com>
To: <linux-kernel@vger.kernel.org>, <kvm@vger.kernel.org>,
	<bp@alien8.de>, <thomas.lendacky@amd.com>
Cc: <tglx@kernel.org>, <mingo@redhat.com>,
	<dave.hansen@linux.intel.com>, <hpa@zytor.com>, <xin@zytor.com>,
	<seanjc@google.com>, <pbonzini@redhat.com>, <x86@kernel.org>,
	<sohil.mehta@intel.com>, <jon.grimm@amd.com>, <nikunj@amd.com>
Subject: [PATCH v2 1/2] x86/cpu: Disable CR pinning during CPU bringup
Date: Thu, 26 Feb 2026 09:23:48 +0000	[thread overview]
Message-ID: <20260226092349.803491-2-nikunj@amd.com> (raw)
In-Reply-To: <20260226092349.803491-1-nikunj@amd.com>

From: Dave Hansen <dave.hansen@linux.intel.com>

== CR Pinning Background ==

Modern CPU hardening features like SMAP/SMEP are enabled by flipping
control register (CR) bits. Attackers find these features inconvenient and
often try to disable them.

CR-pinning is a kernel hardening feature that detects when
security-sensitive control bits are flipped off, complains about it, then
turns them back on. The CR-pinning checks are performed in the CR
manipulation helpers.

X86_CR4_FRED controls FRED enabling and is pinned. There is a single,
system-wide static key that controls CR-pinning behavior. The static key is
enabled by the boot CPU after it has established its CR configuration.

The end result is that CR-pinning is not active while initializing the boot
CPU but it is active while bringing up secondary CPUs.

== FRED Background ==

FRED is a new hardware entry/exit feature for the kernel. It is not on by
default and started out as Intel-only. AMD is just adding support now.

FRED has MSRs for configuration and is enabled by the pinned X86_CR4_FRED
bit. It should not be enabled until after MSRs are properly initialized.

== SEV Background ==

AMD SEV-ES and SEV-SNP use #VC (Virtualization Communication) exceptions to
handle operations that require hypervisor assistance. These exceptions
occur during various operations including MMIO access, CPUID instructions,
and certain memory accesses.

Writes to the console can generate #VC.

== Problem ==

CR-pinning implicitly enables FRED on secondary CPUs at a different point
than the boot CPU. This point is *before* the CPU has done an explicit
cr4_set_bits(X86_CR4_FRED) and before the MSRs are initialized. This means
that there is a window where no exceptions can be handled.

For SEV-ES/SNP and TDX guests, any console output during this window
triggers #VC or #VE exceptions that result in triple faults because the
exception handlers rely on FRED MSRs that aren't yet configured.

== Fix ==

Defer CR-pinning enforcement during secondary CPU bringup. This avoids any
implicit CR changes during CPU bringup, ensuring that FRED is not enabled
before it is configured and able to handle a #VC or #VE.

This also aligns boot and secondary CPU bringup.

CR-pinning is now enforced only when the CPU is online. cr4_init() is
called during secondary CPU bringup, while the CPU is still offline, so the
pinning logic in cr4_init() is redundant. Remove it and add WARN_ON_ONCE()
to catch any future break of this assumption.

Note: FRED is not on by default anywhere so this is not likely to be
causing many problems. The only reason this was noticed was that AMD
started to enable FRED and was turning it on.

Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Reported-by: Nikunj A Dadhania <nikunj@amd.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
[ Nikunj: Updated SEV background section wording ]
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Cc: stable@vger.kernel.org # 6.9+
---
 arch/x86/kernel/cpu/common.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1c3261cae40c..3ccc6416a11d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -434,6 +434,21 @@ static const unsigned long cr4_pinned_mask = X86_CR4_SMEP | X86_CR4_SMAP | X86_C
 static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
 static unsigned long cr4_pinned_bits __ro_after_init;
 
+static bool cr_pinning_enabled(void)
+{
+	if (!static_branch_likely(&cr_pinning))
+		return false;
+
+	/*
+	 * Do not enforce pinning during CPU bringup. It might
+	 * turn on features that are not set up yet, like FRED.
+	 */
+	if (!cpu_online(smp_processor_id()))
+		return false;
+
+	return true;
+}
+
 void native_write_cr0(unsigned long val)
 {
 	unsigned long bits_missing = 0;
@@ -441,7 +456,7 @@ void native_write_cr0(unsigned long val)
 set_register:
 	asm volatile("mov %0,%%cr0": "+r" (val) : : "memory");
 
-	if (static_branch_likely(&cr_pinning)) {
+	if (cr_pinning_enabled()) {
 		if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) {
 			bits_missing = X86_CR0_WP;
 			val |= bits_missing;
@@ -460,7 +475,7 @@ void __no_profile native_write_cr4(unsigned long val)
 set_register:
 	asm volatile("mov %0,%%cr4": "+r" (val) : : "memory");
 
-	if (static_branch_likely(&cr_pinning)) {
+	if (cr_pinning_enabled()) {
 		if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) {
 			bits_changed = (val & cr4_pinned_mask) ^ cr4_pinned_bits;
 			val = (val & ~cr4_pinned_mask) | cr4_pinned_bits;
@@ -502,8 +517,8 @@ void cr4_init(void)
 
 	if (boot_cpu_has(X86_FEATURE_PCID))
 		cr4 |= X86_CR4_PCIDE;
-	if (static_branch_likely(&cr_pinning))
-		cr4 = (cr4 & ~cr4_pinned_mask) | cr4_pinned_bits;
+
+	WARN_ON_ONCE(cr_pinning_enabled());
 
 	__write_cr4(cr4);
 
-- 
2.48.1


  reply	other threads:[~2026-02-26  9:24 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-26  9:23 [PATCH v2 0/2] x86/fred: Fix SEV-ES/SNP guest boot failures Nikunj A Dadhania
2026-02-26  9:23 ` Nikunj A Dadhania [this message]
2026-03-09 13:46   ` [PATCH v2 1/2] x86/cpu: Disable CR pinning during CPU bringup Borislav Petkov
2026-03-09 15:38     ` Dave Hansen
2026-03-09 16:15       ` Borislav Petkov
2026-03-09 18:03         ` Dave Hansen
2026-03-09 18:40           ` Tom Lendacky
2026-03-09 19:27             ` Dave Hansen
2026-03-11 10:41               ` Nikunj A. Dadhania
2026-03-11 14:07                 ` Dave Hansen
2026-03-11 15:42                   ` Nikunj A. Dadhania
2026-03-11 17:28                     ` Dave Hansen
2026-03-12  7:21                       ` Nikunj A. Dadhania
2026-03-12  7:26                         ` Nikunj A. Dadhania
2026-03-12 14:08                       ` Nikunj A. Dadhania
2026-03-12 14:20                         ` Dave Hansen
2026-03-12 14:53                           ` Nikunj A. Dadhania
2026-03-12 15:02                             ` Dave Hansen
2026-03-12 19:06                               ` David Laight
2026-03-16 20:27                           ` Chang S. Bae
2026-03-16 21:43                             ` Dave Hansen
2026-03-17  4:12                               ` Nikunj A. Dadhania
2026-03-17 14:26                                 ` Borislav Petkov
2026-03-17 15:31                                 ` Dave Hansen
2026-03-17 16:54                                   ` Borislav Petkov
2026-03-18  8:19                                     ` Nikunj A. Dadhania
2026-03-17 17:04                               ` Chang S. Bae
2026-03-17 17:51                                 ` Chang S. Bae
2026-03-12 18:09                         ` Sohil Mehta
2026-03-13  8:35                           ` Nikunj A. Dadhania
2026-03-13 18:05                             ` Sohil Mehta
2026-03-13 19:10                               ` Borislav Petkov
2026-03-17 17:06                             ` Chang S. Bae
2026-02-26  9:23 ` [PATCH v2 2/2] x86/fred: Fix early boot failures on SEV-ES/SNP guests Nikunj A Dadhania
2026-02-26 14:14   ` Tom Lendacky
2026-02-27  4:14     ` Nikunj A. Dadhania

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=20260226092349.803491-2-nikunj@amd.com \
    --to=nikunj@amd.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jon.grimm@amd.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=sohil.mehta@intel.com \
    --cc=tglx@kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    --cc=xin@zytor.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox