[RFC PATCH 36/56] x86/alternative: Do not recompute len on re-patch

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

Multiple alternatives may be defined at the same va, and the logic will
compute the maximum size of any alternative and update all of them with
the new max size. This only needs to be done once, and must be skipped
on re-patch because the memory containing the alternative information is
read-only at that point.

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

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index a02dc6bfb696..17b93763d1be 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -298,7 +298,7 @@ u8 *its_static_thunk(int reg)
static inline void its_fini_core(void) {}
#endif /* CONFIG_MITIGATION_ITS */

-static bool __maybe_unused repatch_in_progress;
+static bool repatch_in_progress;

#ifdef CONFIG_DYNAMIC_MITIGATIONS
static struct alt_site *alt_sites;
@@ -697,8 +697,12 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
* add more padding. To ensure consistent patching find the max
* padding for all alt_instr entries for this site (nested
* alternatives result in consecutive entries).
+ *
+ * Ignore this on repatching because this has already been done
+ * and because the alt_instr may be in read-only memory.
*/
- for (b = a+1; b < end && instr_va(b) == instr_va(a); b++) {
+ for (b = a+1; b < end && instr_va(b) == instr_va(a) &&
+ !repatch_in_progress; b++) {
u8 len = max(a->instrlen, b->instrlen);
a->instrlen = b->instrlen = len;
}
--
2.34.1