Commit | Line | Data |
---|---|---|
9fa1db4c | 1 | // SPDX-License-Identifier: GPL-2.0 |
b3e0c5f7 HC |
2 | |
3 | #include <linux/uaccess.h> | |
47837a5c | 4 | #include <asm/nospec-branch.h> |
5ade5be4 | 5 | #include <asm/abs_lowcore.h> |
686140a1 VG |
6 | #include <asm/alternative.h> |
7 | #include <asm/facility.h> | |
8 | ||
b3e0c5f7 | 9 | void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx) |
686140a1 | 10 | { |
686140a1 | 11 | u8 *instr, *replacement; |
b3e0c5f7 HC |
12 | struct alt_instr *a; |
13 | bool replace; | |
686140a1 VG |
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++) { | |
b3e0c5f7 HC |
20 | if (!(a->ctx & ctx)) |
21 | continue; | |
22 | switch (a->type) { | |
23 | case ALT_TYPE_FACILITY: | |
beb8cee0 | 24 | replace = test_facility(a->data); |
b3e0c5f7 | 25 | break; |
47837a5c HC |
26 | case ALT_TYPE_SPEC: |
27 | replace = nobp_enabled(); | |
28 | break; | |
5ade5be4 SS |
29 | case ALT_TYPE_LOWCORE: |
30 | replace = have_relocated_lowcore(); | |
31 | break; | |
b3e0c5f7 HC |
32 | default: |
33 | replace = false; | |
34 | } | |
35 | if (!replace) | |
36 | continue; | |
686140a1 VG |
37 | instr = (u8 *)&a->instr_offset + a->instr_offset; |
38 | replacement = (u8 *)&a->repl_offset + a->repl_offset; | |
e6ed91fd | 39 | s390_kernel_write(instr, replacement, a->instrlen); |
686140a1 VG |
40 | } |
41 | } |