From: Charlie Jenkins <[email protected]>

Migrate the kexec relocation code to use the generated instruction
headers instead of the hand-written instruction composition functions.

Signed-off-by: Charlie Jenkins <[email protected]>

---

This was again tested by brute forcing all possible inputs to the value
fed into the immediates.
---
 arch/riscv/kernel/machine_kexec_file.c | 55 ++++++++++++----------------------
 1 file changed, 19 insertions(+), 36 deletions(-)

diff --git a/arch/riscv/kernel/machine_kexec_file.c 
b/arch/riscv/kernel/machine_kexec_file.c
index dd9d92a96517..1d58aafea232 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -116,32 +116,6 @@ static char *setup_kdump_cmdline(struct kimage *image, 
char *cmdline,
        (((x) + (RISCV_IMM_REACH >> 1)) & ~(RISCV_IMM_REACH - 1))
 #define RISCV_CONST_LOW_PART(x) ((x) - RISCV_CONST_HIGH_PART(x))
 
-#define ENCODE_ITYPE_IMM(x) \
-       (RV_X(x, 0, 12) << 20)
-#define ENCODE_BTYPE_IMM(x) \
-       ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | \
-       (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31))
-#define ENCODE_UTYPE_IMM(x) \
-       (RV_X(x, 12, 20) << 12)
-#define ENCODE_JTYPE_IMM(x) \
-       ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | \
-       (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31))
-#define ENCODE_CBTYPE_IMM(x) \
-       ((RV_X(x, 1, 2) << 3) | (RV_X(x, 3, 2) << 10) | (RV_X(x, 5, 1) << 2) | \
-       (RV_X(x, 6, 2) << 5) | (RV_X(x, 8, 1) << 12))
-#define ENCODE_CJTYPE_IMM(x) \
-       ((RV_X(x, 1, 3) << 3) | (RV_X(x, 4, 1) << 11) | (RV_X(x, 5, 1) << 2) | \
-       (RV_X(x, 6, 1) << 7) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 8, 2) << 9) | \
-       (RV_X(x, 10, 1) << 8) | (RV_X(x, 11, 1) << 12))
-#define ENCODE_UJTYPE_IMM(x) \
-       (ENCODE_UTYPE_IMM(RISCV_CONST_HIGH_PART(x)) | \
-       (ENCODE_ITYPE_IMM(RISCV_CONST_LOW_PART(x)) << 32))
-#define ENCODE_UITYPE_IMM(x) \
-       (ENCODE_UTYPE_IMM(x) | (ENCODE_ITYPE_IMM(x) << 32))
-
-#define CLEAN_IMM(type, x) \
-       ((~ENCODE_##type##_IMM((uint64_t)(-1))) & (x))
-
 int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
                                     Elf_Shdr *section,
                                     const Elf_Shdr *relsec,
@@ -197,12 +171,14 @@ int arch_kexec_apply_relocations_add(struct 
purgatory_info *pi,
 
                switch (r_type) {
                case R_RISCV_BRANCH:
-                       *(u32 *)loc = CLEAN_IMM(BTYPE, *(u32 *)loc) |
-                                ENCODE_BTYPE_IMM(val - addr);
+                       /*
+                        * For simplicity, use beq as represenative of all
+                        * branches (they all have the same imm encoding)
+                        */
+                       riscv_insn_beq_insert_imm((u32 *)loc, val - addr);
                        break;
                case R_RISCV_JAL:
-                       *(u32 *)loc = CLEAN_IMM(JTYPE, *(u32 *)loc) |
-                                ENCODE_JTYPE_IMM(val - addr);
+                       riscv_insn_jal_insert_imm((u32 *)loc, val  - addr);
                        break;
                /*
                 * With no R_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_I
@@ -213,16 +189,23 @@ int arch_kexec_apply_relocations_add(struct 
purgatory_info *pi,
                case R_RISCV_PCREL_HI20:
                case R_RISCV_CALL_PLT:
                case R_RISCV_CALL:
-                       *(u64 *)loc = CLEAN_IMM(UITYPE, *(u64 *)loc) |
-                                ENCODE_UJTYPE_IMM(val - addr);
+                       riscv_insn_auipc_insert_imm((u32 *)loc, 
RISCV_CONST_HIGH_PART(val - addr));
+                       riscv_insn_jalr_insert_imm((u32 *)loc + 1,
+                                                  RISCV_CONST_LOW_PART(val - 
addr));
                        break;
                case R_RISCV_RVC_BRANCH:
-                       *(u32 *)loc = CLEAN_IMM(CBTYPE, *(u32 *)loc) |
-                                ENCODE_CBTYPE_IMM(val - addr);
+                       /*
+                        * For simplicity, use c.beqz as represenative of all
+                        * compressed branches (they all have the same imm 
encoding)
+                        */
+                       riscv_insn_c_beqz_insert_imm((u16 *)loc, val - addr);
                        break;
                case R_RISCV_RVC_JUMP:
-                       *(u32 *)loc = CLEAN_IMM(CJTYPE, *(u32 *)loc) |
-                                ENCODE_CJTYPE_IMM(val - addr);
+                       /*
+                        * For simplicity, use c.j as represenative of all
+                        * compressed jumps (they all have the same imm 
encoding)
+                        */
+                       riscv_insn_c_j_insert_imm((u16 *)loc, val - addr);
                        break;
                case R_RISCV_ADD16:
                        *(u16 *)loc += val;

-- 
2.52.0



Reply via email to