~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/loongarch/include/asm/alternative.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _ASM_ALTERNATIVE_H
  3 #define _ASM_ALTERNATIVE_H
  4 
  5 #ifndef __ASSEMBLY__
  6 
  7 #include <linux/types.h>
  8 #include <linux/stddef.h>
  9 #include <linux/stringify.h>
 10 #include <asm/asm.h>
 11 
 12 struct alt_instr {
 13         s32 instr_offset;       /* offset to original instruction */
 14         s32 replace_offset;     /* offset to replacement instruction */
 15         u16 feature;            /* feature bit set for replacement */
 16         u8  instrlen;           /* length of original instruction */
 17         u8  replacementlen;     /* length of new instruction */
 18 } __packed;
 19 
 20 /*
 21  * Debug flag that can be tested to see whether alternative
 22  * instructions were patched in already:
 23  */
 24 extern int alternatives_patched;
 25 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
 26 
 27 extern void alternative_instructions(void);
 28 extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
 29 
 30 #define b_replacement(num)      "664"#num
 31 #define e_replacement(num)      "665"#num
 32 
 33 #define alt_end_marker          "663"
 34 #define alt_slen                "662b-661b"
 35 #define alt_total_slen          alt_end_marker"b-661b"
 36 #define alt_rlen(num)           e_replacement(num)"f-"b_replacement(num)"f"
 37 
 38 #define __OLDINSTR(oldinstr, num)                                       \
 39         "661:\n\t" oldinstr "\n662:\n"                                  \
 40         ".fill -(((" alt_rlen(num) ")-(" alt_slen ")) > 0) * "          \
 41                 "((" alt_rlen(num) ")-(" alt_slen ")) / 4, 4, 0x03400000\n"
 42 
 43 #define OLDINSTR(oldinstr, num)                                         \
 44         __OLDINSTR(oldinstr, num)                                       \
 45         alt_end_marker ":\n"
 46 
 47 #define alt_max_short(a, b)     "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"
 48 
 49 /*
 50  * Pad the second replacement alternative with additional NOPs if it is
 51  * additionally longer than the first replacement alternative.
 52  */
 53 #define OLDINSTR_2(oldinstr, num1, num2) \
 54         "661:\n\t" oldinstr "\n662:\n"                                                          \
 55         ".fill -((" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")) > 0) * "  \
 56                 "(" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")) / 4, "    \
 57                 "4, 0x03400000\n"       \
 58         alt_end_marker ":\n"
 59 
 60 #define ALTINSTR_ENTRY(feature, num)                                          \
 61         " .long 661b - .\n"                             /* label           */ \
 62         " .long " b_replacement(num)"f - .\n"           /* new instruction */ \
 63         " .short " __stringify(feature) "\n"            /* feature bit     */ \
 64         " .byte " alt_total_slen "\n"                   /* source len      */ \
 65         " .byte " alt_rlen(num) "\n"                    /* replacement len */
 66 
 67 #define ALTINSTR_REPLACEMENT(newinstr, feature, num)    /* replacement */     \
 68         b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n\t"
 69 
 70 /* alternative assembly primitive: */
 71 #define ALTERNATIVE(oldinstr, newinstr, feature)                        \
 72         OLDINSTR(oldinstr, 1)                                           \
 73         ".pushsection .altinstructions,\"a\"\n"                         \
 74         ALTINSTR_ENTRY(feature, 1)                                      \
 75         ".popsection\n"                                                 \
 76         ".subsection 1\n" \
 77         ALTINSTR_REPLACEMENT(newinstr, feature, 1)                      \
 78         ".previous\n"
 79 
 80 #define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\
 81         OLDINSTR_2(oldinstr, 1, 2)                                      \
 82         ".pushsection .altinstructions,\"a\"\n"                         \
 83         ALTINSTR_ENTRY(feature1, 1)                                     \
 84         ALTINSTR_ENTRY(feature2, 2)                                     \
 85         ".popsection\n"                                                 \
 86         ".subsection 1\n" \
 87         ALTINSTR_REPLACEMENT(newinstr1, feature1, 1)                    \
 88         ALTINSTR_REPLACEMENT(newinstr2, feature2, 2)                    \
 89         ".previous\n"
 90 
 91 /*
 92  * Alternative instructions for different CPU types or capabilities.
 93  *
 94  * This allows to use optimized instructions even on generic binary
 95  * kernels.
 96  *
 97  * length of oldinstr must be longer or equal the length of newinstr
 98  * It can be padded with nops as needed.
 99  *
100  * For non barrier like inlines please define new variants
101  * without volatile and memory clobber.
102  */
103 #define alternative(oldinstr, newinstr, feature)                        \
104         (asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory"))
105 
106 #define alternative_2(oldinstr, newinstr1, feature1, newinstr2, feature2) \
107         (asm volatile(ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2) ::: "memory"))
108 
109 #endif /* __ASSEMBLY__ */
110 
111 #endif /* _ASM_ALTERNATIVE_H */
112 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php