[PATCH v1 1/1] riscv: fix runtime constant support for nommu kernels

Charles Mirabile cmirabil at redhat.com
Fri May 30 20:07:25 PDT 2025


From: Charlie Jenkins <charlie at rivosinc.com>

To be clear, I am suggesting that the following patch to just rip out all
of the if else stuff would also fix this bug, but maybe the perf gains of
potentially inserting nops is worth it.

---
 arch/riscv/include/asm/runtime-const.h | 33 ++++++--------------------
 1 file changed, 7 insertions(+), 26 deletions(-)

diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
index 451fd76b8811..da47253a89a9 100644
--- a/arch/riscv/include/asm/runtime-const.h
+++ b/arch/riscv/include/asm/runtime-const.h
@@ -179,41 +179,22 @@ static inline void __runtime_fixup_caches(void *where, unsigned int insns)
 static inline void __runtime_fixup_32(__le16 *lui_parcel, __le16 *addi_parcel, unsigned int val)
 {
 	unsigned int lower_immediate, upper_immediate;
-	u32 lui_insn, addi_insn, addi_insn_mask;
+	u32 lui_insn, addi_insn;
 	__le32 lui_res, addi_res;
 
-	/* Mask out upper 12 bit of addi */
-	addi_insn_mask = 0x000fffff;
-
 	lui_insn = (u32)le16_to_cpu(lui_parcel[0]) | (u32)le16_to_cpu(lui_parcel[1]) << 16;
 	addi_insn = (u32)le16_to_cpu(addi_parcel[0]) | (u32)le16_to_cpu(addi_parcel[1]) << 16;
 
 	lower_immediate = sign_extend32(val, 11);
 	upper_immediate = (val - lower_immediate);
 
-	if (upper_immediate & 0xfffff000) {
-		/* replace upper 20 bits of lui with upper immediate */
-		lui_insn &= 0x00000fff;
-		lui_insn |= upper_immediate & 0xfffff000;
-	} else {
-		/* replace lui with nop if immediate is small enough to fit in addi */
-		lui_insn = RISCV_INSN_NOP4;
-		/*
-		 * lui is being skipped, so do a load instead of an add. A load
-		 * is performed by adding with the x0 register. Setting rs to
-		 * zero with the following mask will accomplish this goal.
-		 */
-		addi_insn_mask &= 0x07fff;
-	}
+	/* replace upper 20 bits of lui with upper immediate */
+	lui_insn &= 0x00000fff;
+	lui_insn |= upper_immediate & 0xfffff000;
 
-	if (lower_immediate & 0x00000fff) {
-		/* replace upper 12 bits of addi with lower 12 bits of val */
-		addi_insn &= addi_insn_mask;
-		addi_insn |= (lower_immediate & 0x00000fff) << 20;
-	} else {
-		/* replace addi with nop if lower_immediate is empty */
-		addi_insn = RISCV_INSN_NOP4;
-	}
+	/* replace upper 12 bits of addi with lower 12 bits of val */
+	addi_insn &= 0x000fffff;
+	addi_insn |= (lower_immediate & 0x00000fff) << 20;
 
 	addi_res = cpu_to_le32(addi_insn);
 	lui_res = cpu_to_le32(lui_insn);
-- 
2.49.0




More information about the linux-riscv mailing list