arch/riscv/kernel/alternative.c
Source file repositories/reference/linux-study-clean/arch/riscv/kernel/alternative.c
File Facts
- System
- Linux kernel
- Corpus path
arch/riscv/kernel/alternative.c- Extension
.c- Size
- 6286 bytes
- Lines
- 242
- Domain
- Architecture Layer
- Bucket
- arch/riscv
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/module.hlinux/cpu.hlinux/uaccess.hasm/alternative.hasm/module.hasm/sections.hasm/vdso.hasm/vendorid_list.hasm/sbi.hasm/csr.hasm/insn.hasm/text-patching.h
Detected Declarations
struct cpu_manufacturer_info_tfunction riscv_fill_cpu_mfr_infofunction riscv_instruction_atfunction riscv_alternative_fix_auipc_jalrfunction riscv_alternative_fix_jalfunction riscv_alternative_fix_offsetsfunction processfunction apply_vdso_alternativesfunction apply_boot_alternativesfunction apply_early_boot_alternativesfunction apply_module_alternatives
Annotated Snippet
struct cpu_manufacturer_info_t {
unsigned long vendor_id;
unsigned long arch_id;
unsigned long imp_id;
void (*patch_func)(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
};
static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info)
{
#ifdef CONFIG_RISCV_M_MODE
cpu_mfr_info->vendor_id = csr_read(CSR_MVENDORID);
cpu_mfr_info->arch_id = csr_read(CSR_MARCHID);
cpu_mfr_info->imp_id = csr_read(CSR_MIMPID);
#else
cpu_mfr_info->vendor_id = sbi_get_mvendorid();
cpu_mfr_info->arch_id = sbi_get_marchid();
cpu_mfr_info->imp_id = sbi_get_mimpid();
#endif
switch (cpu_mfr_info->vendor_id) {
#ifdef CONFIG_ERRATA_ANDES
case ANDES_VENDOR_ID:
cpu_mfr_info->patch_func = andes_errata_patch_func;
break;
#endif
#ifdef CONFIG_ERRATA_MIPS
case MIPS_VENDOR_ID:
cpu_mfr_info->patch_func = mips_errata_patch_func;
break;
#endif
#ifdef CONFIG_ERRATA_SIFIVE
case SIFIVE_VENDOR_ID:
cpu_mfr_info->patch_func = sifive_errata_patch_func;
break;
#endif
#ifdef CONFIG_ERRATA_THEAD
case THEAD_VENDOR_ID:
cpu_mfr_info->patch_func = thead_errata_patch_func;
break;
#endif
default:
cpu_mfr_info->patch_func = NULL;
}
}
static u32 riscv_instruction_at(void *p)
{
u16 *parcel = p;
return (u32)parcel[0] | (u32)parcel[1] << 16;
}
static void riscv_alternative_fix_auipc_jalr(void *ptr, u32 auipc_insn,
u32 jalr_insn, int patch_offset)
{
u32 call[2] = { auipc_insn, jalr_insn };
s32 imm;
/* get and adjust new target address */
imm = riscv_insn_extract_utype_itype_imm(auipc_insn, jalr_insn);
imm -= patch_offset;
/* update instructions */
riscv_insn_insert_utype_itype_imm(&call[0], &call[1], imm);
/* patch the call place again */
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 instruction */
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)
{
int num_insn = len / sizeof(u32);
Annotation
- Immediate include surface: `linux/init.h`, `linux/module.h`, `linux/cpu.h`, `linux/uaccess.h`, `asm/alternative.h`, `asm/module.h`, `asm/sections.h`, `asm/vdso.h`.
- Detected declarations: `struct cpu_manufacturer_info_t`, `function riscv_fill_cpu_mfr_info`, `function riscv_instruction_at`, `function riscv_alternative_fix_auipc_jalr`, `function riscv_alternative_fix_jal`, `function riscv_alternative_fix_offsets`, `function process`, `function apply_vdso_alternatives`, `function apply_boot_alternatives`, `function apply_early_boot_alternatives`.
- Atlas domain: Architecture Layer / arch/riscv.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.