[RFC PATCH 40/56] x86/alternative: Use sync_core_nmi_safe()

David Kaplan posted 56 patches 2 months, 1 week ago
[RFC PATCH 40/56] x86/alternative: Use sync_core_nmi_safe()
Posted by David Kaplan 2 months, 1 week ago
Re-patching is done under NMI context so the NMI-safe version of
sync_core() must be used.

Signed-off-by: David Kaplan <david.kaplan@amd.com>
---
 arch/x86/kernel/alternative.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index b67116ae883c..2d48d750d4d9 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2585,7 +2585,11 @@ void __init_or_module text_poke_early(void *addr, const void *opcode,
 	} else {
 		local_irq_save(flags);
 		memcpy(addr, opcode, len);
-		sync_core();
+		/* Re-patching occurs in NMI context so we can't do IRET. */
+		if (repatch_in_progress)
+			sync_core_nmi_safe();
+		else
+			sync_core();
 		local_irq_restore(flags);
 
 		/*
-- 
2.34.1
Re: [RFC PATCH 40/56] x86/alternative: Use sync_core_nmi_safe()
Posted by Peter Zijlstra 2 months ago
On Mon, Oct 13, 2025 at 09:34:28AM -0500, David Kaplan wrote:
> Re-patching is done under NMI context so the NMI-safe version of
> sync_core() must be used.
> 
> Signed-off-by: David Kaplan <david.kaplan@amd.com>
> ---
>  arch/x86/kernel/alternative.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
> index b67116ae883c..2d48d750d4d9 100644
> --- a/arch/x86/kernel/alternative.c
> +++ b/arch/x86/kernel/alternative.c
> @@ -2585,7 +2585,11 @@ void __init_or_module text_poke_early(void *addr, const void *opcode,
>  	} else {
>  		local_irq_save(flags);
>  		memcpy(addr, opcode, len);
> -		sync_core();
> +		/* Re-patching occurs in NMI context so we can't do IRET. */
> +		if (repatch_in_progress)
> +			sync_core_nmi_safe();
> +		else
> +			sync_core();
>  		local_irq_restore(flags);
>  

Can we please keep this in sync_core()? Something like:

static __always_inline void sync_core(void)
{
	if (static_cpu_has(X86_FEATURE_SERIALIZE)) {
		serialize();
		return;
	}

+	if (repatch_in_progress) {
+		sync_core_nmi_safe();
+		return;
+	}
+
	iret_to_self();
}

That way all the modern stuff that has SERIALIZE will still use that.