From: "Rui Qi" <qirui.001@bytedance.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>
Cc: <mark.rutland@arm.com>, <ardb@kernel.org>, <song@kernel.org>,
<dylanbhatch@google.com>, <linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>,
"Rui Qi" <qirui.001@bytedance.com>, <stable@vger.kernel.org>
Subject: [PATCH 3/3] arm64: module: Use text-poke for late PLT/veneer emission
Date: Sat, 10 Oct 2026 16:50:55 +0800 [thread overview]
Message-ID: <20261010085055.2200241-2-qirui.001@bytedance.com> (raw)
In-Reply-To: <20261010085055.2200241-1-qirui.001@bytedance.com>
module_emit_plt_entry() and module_emit_veneer_for_adrp() write PLT
entries into the .plt section by direct assignment. Once a module is
fully formed its .plt is read-only/executable, so a late (livepatch)
relocation that falls back to PLT emission -- an out-of-range
R_AARCH64_CALL26/JUMP26, or an ADRP under CONFIG_ARM64_ERRATUM_843419
-- triggers a synchronous Data Abort and panics.
This is the same ROX premise that commit 91b89a634487
("arm64/module: Use text-poke API for late relocations.") handled for
the relocation writes through WRITE_PLACE(); the PLT/veneer emitters
were left using direct assignment.
The late path is reachable without remapping:
klp_write_section_relocs() applies .klp.rela.* sections through
apply_relocate_add() with the patch module already MODULE_STATE_LIVE,
so .plt is ROX.
Route the emitters through the text-poke API, mirroring WRITE_PLACE().
Fixes: 91b89a634487d5614e51ee773a889ed57f5551ca ("arm64/module: Use text-poke API for late relocations.")
Cc: stable@vger.kernel.org
Signed-off-by: Rui Qi <qirui.001@bytedance.com>
---
arch/arm64/kernel/module-plts.c | 35 ++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index 7afd370da9f4..fa89ed014bd1 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -9,6 +9,29 @@
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/sort.h>
+#include <linux/text-patching.h>
+
+/*
+ * The .plt section is marked ROX once the module is fully formed, so
+ * late (livepatch) relocations that emit PLT entries cannot use direct
+ * assignment. Mirror WRITE_PLACE() and route the write through the
+ * text-poke API when the module is already loaded.
+ *
+ * Return: 0 on success, -EINVAL if the text-poke write failed.
+ */
+static int plt_entry_write(struct plt_entry *plt,
+ struct plt_entry *entry, struct module *mod)
+{
+ if (mod->state == MODULE_STATE_UNFORMED) {
+ *plt = *entry;
+ return 0;
+ }
+
+ if (!aarch64_insn_copy(plt, entry, sizeof(*plt)))
+ return -EINVAL;
+
+ return 0;
+}
static struct plt_entry __get_adrp_add_pair(u64 dst, u64 pc,
enum aarch64_insn_register reg)
@@ -76,11 +99,14 @@ u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
int i = pltsec->plt_num_entries;
int j = i - 1;
u64 val = sym->st_value + rela->r_addend;
+ struct plt_entry entry;
if (is_forbidden_offset_for_adrp(&plt[i].adrp))
i++;
- plt[i] = get_plt_entry(val, &plt[i]);
+ entry = get_plt_entry(val, &plt[i]);
+ if (plt_entry_write(&plt[i], &entry, mod))
+ return 0;
/*
* Check if the entry we just created is a duplicate. Given that the
@@ -107,6 +133,7 @@ u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs,
int i = pltsec->plt_num_entries++;
u32 br;
int rd;
+ struct plt_entry entry;
if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries))
return 0;
@@ -121,8 +148,10 @@ u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs,
br = aarch64_insn_gen_branch_imm((u64)&plt[i].br, (u64)loc + 4,
AARCH64_INSN_BRANCH_NOLINK);
- plt[i] = __get_adrp_add_pair(val, (u64)&plt[i], rd);
- plt[i].br = cpu_to_le32(br);
+ entry = __get_adrp_add_pair(val, (u64)&plt[i], rd);
+ entry.br = cpu_to_le32(br);
+ if (plt_entry_write(&plt[i], &entry, mod))
+ return 0;
return (u64)&plt[i];
}
--
2.20.1
next prev parent reply other threads:[~2026-10-10 8:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-10 8:47 [PATCH 0/3] arm64: Fix text-poke byte-order and late PLT/veneer ROX handling Rui Qi
2026-10-10 8:47 ` [PATCH 1/3] arm64/module: Fix big-endian breakage in late data relocations Rui Qi
2026-10-10 8:50 ` [PATCH 2/3] arm64: patching: Fix instruction byte order in aarch64_insn_set() Rui Qi
2026-10-10 8:50 ` Rui Qi [this message]
2026-11-03 17:19 ` [PATCH 3/3] arm64: module: Use text-poke for late PLT/veneer emission Catalin Marinas
2026-11-11 6:50 ` Rui Qi
2026-10-15 16:57 ` [PATCH 2/3] arm64: patching: Fix instruction byte order in aarch64_insn_set() Catalin Marinas
2026-10-16 6:18 ` Rui Qi
2026-11-11 6:52 ` Rui Qi
2026-11-11 9:29 ` David Laight
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=20261010085055.2200241-2-qirui.001@bytedance.com \
--to=qirui.001@bytedance.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=dylanbhatch@google.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=song@kernel.org \
--cc=stable@vger.kernel.org \
--cc=will@kernel.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
all inboxes | Powered by JetHome®