[RFC PATCH 39/56] x86/sync_core: Add sync_core_nmi_safe()

David Kaplan
2025-10-13T14:36:19Z

As noted in the existing comment, sync_core() is not NMI-safe due to the
use of IRET. sync_core_nmi_safe() uses MOV-CR2 which can be safely used in
NMI context. This is needed when modifying kernel code within an NMI
handler.

IRET was initially chosen because it works even under environments like Xen
PV. But Xen PV will not support CONFIG_DYNAMIC_MITIGATIONS and the need
for NMI-based kernel patching.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
---
arch/x86/include/asm/sync_core.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h
index 96bda43538ee..f4e2f868d71a 100644
--- a/arch/x86/include/asm/sync_core.h
+++ b/arch/x86/include/asm/sync_core.h
@@ -88,6 +88,20 @@ static __always_inline void sync_core(void)
iret_to_self();
}

+/*
+ * NMI safe version of sync_core()
+ *
+ * sync_core() may do iret_to_self() which will unmask NMI.
+ * sync_core_nmi_safe() uses MOV-to-CR2 and is safe to use in NMI context.
+ *
+ * As noted in the comments above, this sequence may fault at CPL3 (i.e. Xen
+ * PV). Therefore it should only be used if outside of those environments.
+ */
+static inline void sync_core_nmi_safe(void)
+{
+ native_read_cr2();
+}
+
/*
* Ensure that a core serializing instruction is issued before returning
* to user-mode. x86 implements return to user-space through sysexit,
--
2.34.1