1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/uaccess.h> 4 #include <asm/nospec-branch.h> 5 #include <asm/abs_lowcore.h> 6 #include <asm/alternative.h> 7 #include <asm/facility.h> 8 9 void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx) 10 { 11 u8 *instr, *replacement; 12 struct alt_instr *a; 13 bool replace; 14 15 /* 16 * The scan order should be from start to end. A later scanned 17 * alternative code can overwrite previously scanned alternative code. 18 */ 19 for (a = start; a < end; a++) { 20 if (!(a->ctx & ctx)) 21 continue; 22 switch (a->type) { 23 case ALT_TYPE_FACILITY: 24 replace = test_facility(a->data); 25 break; 26 case ALT_TYPE_SPEC: 27 replace = nobp_enabled(); 28 break; 29 case ALT_TYPE_LOWCORE: 30 replace = have_relocated_lowcore(); 31 break; 32 default: 33 replace = false; 34 } 35 if (!replace) 36 continue; 37 instr = (u8 *)&a->instr_offset + a->instr_offset; 38 replacement = (u8 *)&a->repl_offset + a->repl_offset; 39 s390_kernel_write(instr, replacement, a->instrlen); 40 } 41 } 42