riscv: xip: support runtime trap patching

RISCV_ERRATA_ALTERNATIVE patches text at runtime which is currently
not possible when the kernel is executed from the flash in XIP mode.
Since runtime patching concerns only traps at the moment, let's just
have all the traps reside in RAM anyway if RISCV_ERRATA_ALTERNATIVE
is set. Thus, these functions will be patch-able even when the .text
section is in flash.

Signed-off-by: Vitaly Wool <vitaly.wool@konsulko.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>

authored by Vitaly Wool and committed by Palmer Dabbelt 5e63215c 160ce364

+23 -5
+9 -4
arch/riscv/kernel/traps.c
··· 86 86 } 87 87 } 88 88 89 + #if defined (CONFIG_XIP_KERNEL) && defined (CONFIG_RISCV_ERRATA_ALTERNATIVE) 90 + #define __trap_section __section(".xip.traps") 91 + #else 92 + #define __trap_section 93 + #endif 89 94 #define DO_ERROR_INFO(name, signo, code, str) \ 90 - asmlinkage __visible void name(struct pt_regs *regs) \ 95 + asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ 91 96 { \ 92 97 do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \ 93 98 } ··· 116 111 int handle_misaligned_load(struct pt_regs *regs); 117 112 int handle_misaligned_store(struct pt_regs *regs); 118 113 119 - asmlinkage void do_trap_load_misaligned(struct pt_regs *regs) 114 + asmlinkage void __trap_section do_trap_load_misaligned(struct pt_regs *regs) 120 115 { 121 116 if (!handle_misaligned_load(regs)) 122 117 return; ··· 124 119 "Oops - load address misaligned"); 125 120 } 126 121 127 - asmlinkage void do_trap_store_misaligned(struct pt_regs *regs) 122 + asmlinkage void __trap_section do_trap_store_misaligned(struct pt_regs *regs) 128 123 { 129 124 if (!handle_misaligned_store(regs)) 130 125 return; ··· 151 146 return GET_INSN_LENGTH(insn); 152 147 } 153 148 154 - asmlinkage __visible void do_trap_break(struct pt_regs *regs) 149 + asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) 155 150 { 156 151 #ifdef CONFIG_KPROBES 157 152 if (kprobe_single_step_handler(regs))
+14 -1
arch/riscv/kernel/vmlinux-xip.lds.S
··· 99 99 } 100 100 PERCPU_SECTION(L1_CACHE_BYTES) 101 101 102 - . = ALIGN(PAGE_SIZE); 102 + . = ALIGN(8); 103 + .alternative : { 104 + __alt_start = .; 105 + *(.alternative) 106 + __alt_end = .; 107 + } 103 108 __init_end = .; 104 109 110 + . = ALIGN(16); 111 + .xip.traps : { 112 + __xip_traps_start = .; 113 + *(.xip.traps) 114 + __xip_traps_end = .; 115 + } 116 + 117 + . = ALIGN(PAGE_SIZE); 105 118 .sdata : { 106 119 __global_pointer$ = . + 0x800; 107 120 *(.sdata*)