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