/* patch the call place again */
patch_text_nosync(ptr, &jal_insn, sizeof(u32));
}
void riscv_alternative_fix_offsets(void *alt_ptr, unsignedint len, int patch_offset)
{ int num_insn = len / sizeof(u32); int i;
for (i = 0; i < num_insn; i++) {
u32 insn = riscv_instruction_at(alt_ptr + i * sizeof(u32));
/* * May be the start of an auipc + jalr pair * Needs to check that at least one more instruction * is in the list.
*/ if (riscv_insn_is_auipc(insn) && i < num_insn - 1) {
u32 insn2 = riscv_instruction_at(alt_ptr + (i + 1) * sizeof(u32));
if (!riscv_insn_is_jalr(insn2)) continue;
/* if instruction pair is a call, it will use the ra register */ if (RV_EXTRACT_RD_REG(insn) != 1) continue;
riscv_alternative_fix_auipc_jalr(alt_ptr + i * sizeof(u32),
insn, insn2, patch_offset);
i++;
}
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);
}
}
}
/* * This is called very early in the boot process (directly after we run * a feature detect on the boot CPU). No need to worry about other CPUs * here.
*/ staticvoid __init_or_module _apply_alternatives(struct alt_entry *begin, struct alt_entry *end, unsignedint stage)
{ struct cpu_manufacturer_info_t cpu_mfr_info;
/* * apply_early_boot_alternatives() is called from setup_vm() with MMU-off. * * Following requirements should be honoured for it to work correctly: * 1) It should use PC-relative addressing for accessing kernel symbols. * To achieve this we always use GCC cmodel=medany. * 2) The compiler instrumentation for FTRACE will not work for setup_vm() * so disable compiler instrumentation when FTRACE is enabled. * * Currently, the above requirements are honoured by using custom CFLAGS * for alternative.o in kernel/Makefile.
*/ void __init apply_early_boot_alternatives(void)
{ #ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
_apply_alternatives((struct alt_entry *)__alt_start,
(struct alt_entry *)__alt_end,
RISCV_ALTERNATIVES_EARLY_BOOT); #endif
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.