^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef _ASM_X86_ALTERNATIVE_ASM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define _ASM_X86_ALTERNATIVE_ASM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #ifdef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) .macro LOCK_PREFIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) 672: lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) .pushsection .smp_locks,"a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) .balign 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) .long 672b - .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) .macro LOCK_PREFIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * objtool annotation to ignore the alternatives and only consider the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * instruction(s).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .macro ANNOTATE_IGNORE_ALTERNATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .Lannotate_\@:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .pushsection .discard.ignore_alts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .long .Lannotate_\@ - .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Issue one struct alt_instr descriptor entry (need to put it into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * the section .altinstructions, see below). This entry contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * enough information for the alternatives patching code to patch an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * instruction. See apply_alternatives().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .macro altinstruction_entry orig alt feature orig_len alt_len pad_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .long \orig - .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .long \alt - .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .word \feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .byte \orig_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .byte \alt_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .byte \pad_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Define an alternative between two instructions. If @feature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * present, early code in apply_alternatives() replaces @oldinstr with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @newinstr. ".skip" directive takes care of proper instruction padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * in case @newinstr is longer than @oldinstr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .macro ALTERNATIVE oldinstr, newinstr, feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 140:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) \oldinstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 141:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .skip -(((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)),0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 142:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .pushsection .altinstructions,"a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) altinstruction_entry 140b,143f,\feature,142b-140b,144f-143f,142b-141b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .pushsection .altinstr_replacement,"ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 143:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) \newinstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 144:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define old_len 141b-140b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define new_len1 144f-143f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define new_len2 145f-144f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * gas compatible max based on the idea from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * The additional "-" is needed because gas uses a "true" value of -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Same as ALTERNATIVE macro above but for two alternatives. If CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @feature2, it replaces @oldinstr with @feature2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 140:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) \oldinstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 141:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .skip -((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) (alt_max_short(new_len1, new_len2) - (old_len)),0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 142:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .pushsection .altinstructions,"a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f,142b-141b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f,142b-141b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .pushsection .altinstr_replacement,"ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 143:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) \newinstr1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 144:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) \newinstr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 145:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #endif /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif /* _ASM_X86_ALTERNATIVE_ASM_H */