RISC-V: fix jal addresses in patched alternatives

A patch from »Zbb string optimizations and call support in alternatives« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko.stuebner@...> Date: Mon, 19 Dec 2022 22:27:55 +0100

Commit-Message

Alternatives live in a different section, so addresses used by jal instructions will point to wrong locations after the patch got applied. Similar to arm64, adjust the location to consider that offset. Signed-off-by: Heiko Stuebner <heiko.stuebner@...>

Patch-Comment

arch/riscv/kernel/alternative.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)

Statistics

  • 27 lines added
  • 0 lines removed

Changes

----------------------- arch/riscv/kernel/alternative.c ------------------------
index 6212ea0eed72..985c284fe9f4 100644
@@ -79,6 +79,21 @@ static void riscv_alternative_fix_auipc_jalr(void *ptr, u32 auipc_insn,
patch_text_nosync(ptr, call, sizeof(u32) * 2);
}
+static void riscv_alternative_fix_jal(void *ptr, u32 jal_insn, int patch_offset)
+{
+ s32 imm;
+
+ /* get and adjust new target address */
+ imm = riscv_insn_extract_jtype_imm(jal_insn);
+ imm -= patch_offset;
+
+ /* update instructions */
+ riscv_insn_insert_jtype_imm(&jal_insn, imm);
+
+ /* patch the call place again */
+ patch_text_nosync(ptr, &jal_insn, sizeof(u32));
+}
+
void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len,
int patch_offset)
{
@@ -106,6 +121,18 @@ void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len,
riscv_alternative_fix_auipc_jalr(alt_ptr + i * sizeof(u32),
insn, insn2, patch_offset);
}
+
+ if (riscv_insn_is_jal(insn)) {
+ s32 imm = riscv_insn_extract_jtype_imm(insn);
+
+ /* don't modify jumps inside the alternative block */
+ if ((alt_ptr + i * sizeof(u32) + imm) >= alt_ptr &&
+ (alt_ptr + i * sizeof(u32) + imm) < (alt_ptr + len))
+ continue;
+
+ riscv_alternative_fix_jal(alt_ptr + i * sizeof(u32),
+ insn, patch_offset);
+ }
}
}
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...