public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org, Juergen Gross <jgross@suse.com>,
	"H . Peter Anvin" <hpa@zytor.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Borislav Petkov <bp@alien8.de>,
	Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH 11/49] x86/alternatives: Remove the confusing, inaccurate & unnecessary 'temp_mm_state_t' abstraction
Date: Tue, 1 Apr 2025 21:06:08 +0200	[thread overview]
Message-ID: <Z-w5INj77OkbFDQe@gmail.com> (raw)
In-Reply-To: <20250401143624.GI5880@noisy.programming.kicks-ass.net>


* Peter Zijlstra <peterz@infradead.org> wrote:

> On Fri, Mar 28, 2025 at 02:26:26PM +0100, Ingo Molnar wrote:
> > So the temp_mm_state_t abstraction used by use_temporary_mm() and
> > unuse_temporary_mm() is super confusing:
> 
> I thing I see what you're saying, but we also still have these patches
> pending:
> 
>   https://lkml.kernel.org/r/20241119162527.952745944@infradead.org
> 
> :-(

Yeah, so I think we should do your queue on top of mine, the
whole temp_mm_state_t abstraction was rather nonsensical,
and we shouldn't be iterating confusing code...

I've ported patches #1 and #3 from your queue on top, see
attached below - these should be the two that represent 99%
of the conflicts between these two efforts AFAICS.

Does that work for you?

Thanks,

	Ingo

================>
From: Peter Zijlstra <peterz@infradead.org>
Date: Tue, 19 Nov 2024 17:25:28 +0100
Subject: [PATCH] x86/mm: Add mm argument to unuse_temporary_mm()

In commit 209954cbc7d0 ("x86/mm/tlb: Update mm_cpumask lazily")
unuse_temporary_mm() grew the assumption that it gets used on
poking_nn exclusively. While this is currently true, lets not hard
code this assumption.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20241119163035.322525475@infradead.org
---
 arch/x86/kernel/alternative.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 5b1a6252a4b9..cfffcb80f564 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2161,14 +2161,14 @@ static inline struct mm_struct *use_temporary_mm(struct mm_struct *temp_mm)
 __ro_after_init struct mm_struct *text_poke_mm;
 __ro_after_init unsigned long text_poke_mm_addr;
 
-static inline void unuse_temporary_mm(struct mm_struct *prev_mm)
+static inline void unuse_temporary_mm(struct mm_struct *mm, struct mm_struct *prev_mm)
 {
 	lockdep_assert_irqs_disabled();
 
 	switch_mm_irqs_off(NULL, prev_mm, current);
 
 	/* Clear the cpumask, to indicate no TLB flushing is needed anywhere */
-	cpumask_clear_cpu(raw_smp_processor_id(), mm_cpumask(text_poke_mm));
+	cpumask_clear_cpu(raw_smp_processor_id(), mm_cpumask(mm));
 
 	/*
 	 * Restore the breakpoints if they were disabled before the temporary mm
@@ -2275,7 +2275,7 @@ static void *__text_poke(text_poke_f func, void *addr, const void *src, size_t l
 	 * instruction that already allows the core to see the updated version.
 	 * Xen-PV is assumed to serialize execution in a similar manner.
 	 */
-	unuse_temporary_mm(prev_mm);
+	unuse_temporary_mm(text_poke_mm, prev_mm);
 
 	/*
 	 * Flushing the TLB might involve IPIs, which would require enabled


======================================>
From: Andy Lutomirski <luto@kernel.org>
Date: Tue, 19 Nov 2024 17:25:30 +0100
Subject: [PATCH] x86/mm: Make use/unuse_temporary_mm() non-static

This prepares them for use outside of the alternative machinery.
The code is unchanged.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/d1205bc7e165e249c52b7fe8cb1254f06e8a0e2a.1641659630.git.luto@kernel.org
Link: https://lore.kernel.org/r/20241119163035.533822339@infradead.org
---
 arch/x86/include/asm/mmu_context.h |  3 ++
 arch/x86/kernel/alternative.c      | 64 --------------------------------------
 arch/x86/mm/tlb.c                  | 64 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 2398058b6e83..b103e1709a67 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -272,4 +272,7 @@ unsigned long __get_current_cr3_fast(void);
 
 #include <asm-generic/mmu_context.h>
 
+extern struct mm_struct *use_temporary_mm(struct mm_struct *temp_mm);
+extern void unuse_temporary_mm(struct mm_struct *mm, struct mm_struct *prev_mm);
+
 #endif /* _ASM_X86_MMU_CONTEXT_H */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index cfffcb80f564..25abadaf8751 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2111,73 +2111,9 @@ void __init_or_module text_poke_early(void *addr, const void *opcode,
 	}
 }
 
-/*
- * Using a temporary mm allows to set temporary mappings that are not accessible
- * by other CPUs. Such mappings are needed to perform sensitive memory writes
- * that override the kernel memory protections (e.g., W^X), without exposing the
- * temporary page-table mappings that are required for these write operations to
- * other CPUs. Using a temporary mm also allows to avoid TLB shootdowns when the
- * mapping is torn down.
- *
- * Context: The temporary mm needs to be used exclusively by a single core. To
- *          harden security IRQs must be disabled while the temporary mm is
- *          loaded, thereby preventing interrupt handler bugs from overriding
- *          the kernel memory protection.
- */
-static inline struct mm_struct *use_temporary_mm(struct mm_struct *temp_mm)
-{
-	struct mm_struct *prev_mm;
-
-	lockdep_assert_irqs_disabled();
-
-	/*
-	 * Make sure not to be in TLB lazy mode, as otherwise we'll end up
-	 * with a stale address space WITHOUT being in lazy mode after
-	 * restoring the previous mm.
-	 */
-	if (this_cpu_read(cpu_tlbstate_shared.is_lazy))
-		leave_mm();
-
-	prev_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
-	switch_mm_irqs_off(NULL, temp_mm, current);
-
-	/*
-	 * If breakpoints are enabled, disable them while the temporary mm is
-	 * used. Userspace might set up watchpoints on addresses that are used
-	 * in the temporary mm, which would lead to wrong signals being sent or
-	 * crashes.
-	 *
-	 * Note that breakpoints are not disabled selectively, which also causes
-	 * kernel breakpoints (e.g., perf's) to be disabled. This might be
-	 * undesirable, but still seems reasonable as the code that runs in the
-	 * temporary mm should be short.
-	 */
-	if (hw_breakpoint_active())
-		hw_breakpoint_disable();
-
-	return prev_mm;
-}
-
 __ro_after_init struct mm_struct *text_poke_mm;
 __ro_after_init unsigned long text_poke_mm_addr;
 
-static inline void unuse_temporary_mm(struct mm_struct *mm, struct mm_struct *prev_mm)
-{
-	lockdep_assert_irqs_disabled();
-
-	switch_mm_irqs_off(NULL, prev_mm, current);
-
-	/* Clear the cpumask, to indicate no TLB flushing is needed anywhere */
-	cpumask_clear_cpu(raw_smp_processor_id(), mm_cpumask(mm));
-
-	/*
-	 * Restore the breakpoints if they were disabled before the temporary mm
-	 * was loaded.
-	 */
-	if (hw_breakpoint_active())
-		hw_breakpoint_restore();
-}
-
 static void text_poke_memcpy(void *dst, const void *src, size_t len)
 {
 	memcpy(dst, src, len);
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 0925768d00cb..06a1ad39be74 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -972,6 +972,70 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 	this_cpu_write(cpu_tlbstate_shared.is_lazy, true);
 }
 
+/*
+ * Using a temporary mm allows to set temporary mappings that are not accessible
+ * by other CPUs. Such mappings are needed to perform sensitive memory writes
+ * that override the kernel memory protections (e.g., W^X), without exposing the
+ * temporary page-table mappings that are required for these write operations to
+ * other CPUs. Using a temporary mm also allows to avoid TLB shootdowns when the
+ * mapping is torn down.
+ *
+ * Context: The temporary mm needs to be used exclusively by a single core. To
+ *          harden security IRQs must be disabled while the temporary mm is
+ *          loaded, thereby preventing interrupt handler bugs from overriding
+ *          the kernel memory protection.
+ */
+struct mm_struct *use_temporary_mm(struct mm_struct *temp_mm)
+{
+	struct mm_struct *prev_mm;
+
+	lockdep_assert_irqs_disabled();
+
+	/*
+	 * Make sure not to be in TLB lazy mode, as otherwise we'll end up
+	 * with a stale address space WITHOUT being in lazy mode after
+	 * restoring the previous mm.
+	 */
+	if (this_cpu_read(cpu_tlbstate_shared.is_lazy))
+		leave_mm();
+
+	prev_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
+	switch_mm_irqs_off(NULL, temp_mm, current);
+
+	/*
+	 * If breakpoints are enabled, disable them while the temporary mm is
+	 * used. Userspace might set up watchpoints on addresses that are used
+	 * in the temporary mm, which would lead to wrong signals being sent or
+	 * crashes.
+	 *
+	 * Note that breakpoints are not disabled selectively, which also causes
+	 * kernel breakpoints (e.g., perf's) to be disabled. This might be
+	 * undesirable, but still seems reasonable as the code that runs in the
+	 * temporary mm should be short.
+	 */
+	if (hw_breakpoint_active())
+		hw_breakpoint_disable();
+
+	return prev_mm;
+}
+
+void unuse_temporary_mm(struct mm_struct *mm, struct mm_struct *prev_mm)
+{
+	lockdep_assert_irqs_disabled();
+
+	switch_mm_irqs_off(NULL, prev_mm, current);
+
+	/* Clear the cpumask, to indicate no TLB flushing is needed anywhere */
+	cpumask_clear_cpu(raw_smp_processor_id(), mm_cpumask(mm));
+
+	/*
+	 * Restore the breakpoints if they were disabled before the temporary mm
+	 * was loaded.
+	 */
+	if (hw_breakpoint_active())
+		hw_breakpoint_restore();
+}
+
 /*
  * Call this when reinitializing a CPU.  It fixes the following potential
  * problems:

  reply	other threads:[~2025-04-01 19:06 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-28 13:26 [PATCH -v2 00/49] Simplify, reorganize and clean up the x86 text-patching code (alternative.c) Ingo Molnar
2025-03-28 13:26 ` [PATCH 01/49] x86/alternatives: Rename 'struct bp_patching_desc' to 'struct int3_patching_desc' Ingo Molnar
2025-03-28 13:26 ` [PATCH 02/49] x86/alternatives: Rename 'bp_refs' to 'int3_refs' Ingo Molnar
2025-03-28 13:26 ` [PATCH 03/49] x86/alternatives: Rename 'text_poke_bp_batch()' to 'smp_text_poke_batch_process()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 04/49] x86/alternatives: Rename 'text_poke_bp()' to 'smp_text_poke_single()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 05/49] x86/alternatives: Rename 'poke_int3_handler()' to 'smp_text_poke_int3_trap_handler()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 06/49] x86/alternatives: Rename 'poking_mm' to 'text_poke_mm' Ingo Molnar
2025-03-28 13:26 ` [PATCH 07/49] x86/alternatives: Rename 'poking_addr' to 'text_poke_mm_addr' Ingo Molnar
2025-03-28 13:26 ` [PATCH 08/49] x86/alternatives: Rename 'bp_desc' to 'int3_desc' Ingo Molnar
2025-03-28 13:26 ` [PATCH 09/49] x86/alternatives: Remove duplicate 'text_poke_early()' prototype Ingo Molnar
2025-03-28 13:26 ` [PATCH 10/49] x86/alternatives: Update comments in int3_emulate_push() Ingo Molnar
2025-03-28 13:26 ` [PATCH 11/49] x86/alternatives: Remove the confusing, inaccurate & unnecessary 'temp_mm_state_t' abstraction Ingo Molnar
2025-04-01 14:36   ` Peter Zijlstra
2025-04-01 19:06     ` Ingo Molnar [this message]
2025-04-02  4:07       ` Ingo Molnar
2025-04-02  7:54         ` Peter Zijlstra
2025-03-28 13:26 ` [PATCH 12/49] x86/alternatives: Rename 'text_poke_flush()' to 'smp_text_poke_batch_flush()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 13/49] x86/alternatives: Rename 'text_poke_finish()' to 'smp_text_poke_batch_finish()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 14/49] x86/alternatives: Rename 'text_poke_queue()' to 'smp_text_poke_batch_add()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 15/49] x86/alternatives: Rename 'text_poke_loc_init()' to 'text_poke_int3_loc_init()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 16/49] x86/alternatives: Rename 'struct text_poke_loc' to 'struct smp_text_poke_loc' Ingo Molnar
2025-03-28 13:26 ` [PATCH 17/49] x86/alternatives: Rename 'struct int3_patching_desc' to 'struct text_poke_int3_vec' Ingo Molnar
2025-03-28 13:26 ` [PATCH 18/49] x86/alternatives: Rename 'int3_desc' to 'int3_vec' Ingo Molnar
2025-03-28 13:26 ` [PATCH 19/49] x86/alternatives: Add text_mutex) assert to smp_text_poke_batch_flush() Ingo Molnar
2025-03-28 13:26 ` [PATCH 20/49] x86/alternatives: Assert that smp_text_poke_int3_trap_handler() can only ever handle 'tp_vec[]' based requests Ingo Molnar
2025-03-28 13:26 ` [PATCH 21/49] x86/alternatives: Use non-inverted logic instead of 'tp_order_fail()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 22/49] x86/alternatives: Remove the 'addr == NULL means forced-flush' hack from smp_text_poke_batch_finish()/smp_text_poke_batch_flush()/text_poke_addr_ordered() Ingo Molnar
2025-03-28 13:26 ` [PATCH 23/49] x86/alternatives: Simplify smp_text_poke_single() by using tp_vec and existing APIs Ingo Molnar
2025-04-01 14:40   ` Peter Zijlstra
2025-04-01 18:49     ` Ingo Molnar
2025-03-28 13:26 ` [PATCH 24/49] x86/alternatives: Assert input parameters in smp_text_poke_batch_process() Ingo Molnar
2025-03-28 13:26 ` [PATCH 25/49] x86/alternatives: Introduce 'struct smp_text_poke_array' and move tp_vec and tp_vec_nr to it Ingo Molnar
2025-03-28 13:26 ` [PATCH 26/49] x86/alternatives: Remove the tp_vec indirection Ingo Molnar
2025-03-28 13:26 ` [PATCH 27/49] x86/alternatives: Rename 'try_get_desc()' to 'try_get_text_poke_array()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 28/49] x86/alternatives: Rename 'put_desc()' to 'put_text_poke_array()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 29/49] x86/alternatives: Simplify try_get_text_poke_array() Ingo Molnar
2025-03-28 13:26 ` [PATCH 30/49] x86/alternatives: Simplify smp_text_poke_int3_trap_handler() Ingo Molnar
2025-03-28 13:26 ` [PATCH 31/49] x86/alternatives: Simplify smp_text_poke_batch_process() Ingo Molnar
2025-03-28 13:26 ` [PATCH 32/49] x86/alternatives: Rename 'int3_refs' to 'text_poke_array_refs' Ingo Molnar
2025-03-28 13:26 ` [PATCH 33/49] x86/alternatives: Move the text_poke_array manipulation into text_poke_int3_loc_init() and rename it to __smp_text_poke_batch_add() Ingo Molnar
2025-03-28 13:26 ` [PATCH 34/49] x86/alternatives: Remove the mixed-patching restriction on smp_text_poke_single() Ingo Molnar
2025-03-28 13:26 ` [PATCH 35/49] x86/alternatives: Document 'smp_text_poke_single()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 36/49] x86/alternatives: Add documentation for smp_text_poke_batch_add() Ingo Molnar
2025-03-28 13:26 ` [PATCH 37/49] x86/alternatives: Move text_poke_array completion from smp_text_poke_batch_finish() and smp_text_poke_batch_flush() to smp_text_poke_batch_process() Ingo Molnar
2025-04-03 13:08   ` Nikolay Borisov
2025-04-03 13:38     ` Ingo Molnar
2025-04-03 13:41       ` Nikolay Borisov
2025-04-03 14:13         ` Ingo Molnar
2025-04-03 14:39           ` Nikolay Borisov
2025-04-03 15:29             ` Ingo Molnar
2025-04-03 15:34               ` Nikolay Borisov
2025-04-04  7:48                 ` Ingo Molnar
2025-03-28 13:26 ` [PATCH 38/49] x86/alternatives: Rename 'text_poke_sync()' to 'smp_text_poke_sync_each_cpu()' Ingo Molnar
2025-03-28 13:26 ` [PATCH 39/49] x86/alternatives: Simplify text_poke_addr_ordered() Ingo Molnar
2025-03-28 13:26 ` [PATCH 40/49] x86/alternatives: Constify text_poke_addr() Ingo Molnar
2025-03-28 13:26 ` [PATCH 41/49] x86/alternatives: Simplify and clean up patch_cmp() Ingo Molnar
2025-03-28 13:26 ` [PATCH 42/49] x86/alternatives: Standardize on 'tpl' local variable names for 'struct smp_text_poke_loc *' Ingo Molnar
2025-03-28 13:26 ` [PATCH 43/49] x86/alternatives: Rename 'TP_ARRAY_NR_ENTRIES_MAX' to 'TEXT_POKE_ARRAY_MAX' Ingo Molnar
2025-03-28 13:26 ` [PATCH 44/49] x86/alternatives: Rename 'POKE_MAX_OPCODE_SIZE' to 'TEXT_POKE_MAX_OPCODE_SIZE' Ingo Molnar
2025-03-28 13:27 ` [PATCH 45/49] x86/alternatives: Simplify the #include section Ingo Molnar
2025-03-28 13:27 ` [PATCH 46/49] x86/alternatives: Move declarations of vmlinux.lds.S defined section symbols to <asm/alternative.h> Ingo Molnar
2025-03-28 13:27 ` [PATCH 47/49] x86/alternatives: Remove 'smp_text_poke_batch_flush()' Ingo Molnar
2025-03-28 13:27 ` [PATCH 48/49] x86/alternatives: Update the comments in smp_text_poke_batch_process() Ingo Molnar
2025-03-28 13:27 ` [PATCH 49/49] x86/alternatives: Rename 'apply_relocation()' to 'text_poke_apply_relocation()' Ingo Molnar
2025-04-01 14:31 ` [PATCH -v2 00/49] Simplify, reorganize and clean up the x86 text-patching code (alternative.c) Peter Zijlstra
2025-04-09 20:51   ` Ingo Molnar
2025-04-10 12:57     ` Peter Zijlstra
2025-04-01 14:31 ` Peter Zijlstra
2025-04-02  3:47   ` Ingo Molnar

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=Z-w5INj77OkbFDQe@gmail.com \
    --to=mingo@kernel.org \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /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