1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun #ifndef __ASM_POWERPC_FEATURE_FIXUPS_H 3*4882a593Smuzhiyun #define __ASM_POWERPC_FEATURE_FIXUPS_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <asm/asm-const.h> 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun /* 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun /* 11*4882a593Smuzhiyun * Feature section common macros 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * Note that the entries now contain offsets between the table entry 14*4882a593Smuzhiyun * and the code rather than absolute code pointers in order to be 15*4882a593Smuzhiyun * useable with the vdso shared library. There is also an assumption 16*4882a593Smuzhiyun * that values will be negative, that is, the fixup table has to be 17*4882a593Smuzhiyun * located after the code it fixes up. 18*4882a593Smuzhiyun */ 19*4882a593Smuzhiyun #if defined(CONFIG_PPC64) && !defined(__powerpc64__) 20*4882a593Smuzhiyun /* 64 bits kernel, 32 bits code (ie. vdso32) */ 21*4882a593Smuzhiyun #define FTR_ENTRY_LONG .8byte 22*4882a593Smuzhiyun #define FTR_ENTRY_OFFSET .long 0xffffffff; .long 23*4882a593Smuzhiyun #elif defined(CONFIG_PPC64) 24*4882a593Smuzhiyun #define FTR_ENTRY_LONG .8byte 25*4882a593Smuzhiyun #define FTR_ENTRY_OFFSET .8byte 26*4882a593Smuzhiyun #else 27*4882a593Smuzhiyun #define FTR_ENTRY_LONG .long 28*4882a593Smuzhiyun #define FTR_ENTRY_OFFSET .long 29*4882a593Smuzhiyun #endif 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #define START_FTR_SECTION(label) label##1: 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define FTR_SECTION_ELSE_NESTED(label) \ 34*4882a593Smuzhiyun label##2: \ 35*4882a593Smuzhiyun .pushsection __ftr_alt_##label,"a"; \ 36*4882a593Smuzhiyun .align 2; \ 37*4882a593Smuzhiyun label##3: 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ 40*4882a593Smuzhiyun label##4: \ 41*4882a593Smuzhiyun .popsection; \ 42*4882a593Smuzhiyun .pushsection sect,"a"; \ 43*4882a593Smuzhiyun .align 3; \ 44*4882a593Smuzhiyun label##5: \ 45*4882a593Smuzhiyun FTR_ENTRY_LONG msk; \ 46*4882a593Smuzhiyun FTR_ENTRY_LONG val; \ 47*4882a593Smuzhiyun FTR_ENTRY_OFFSET label##1b-label##5b; \ 48*4882a593Smuzhiyun FTR_ENTRY_OFFSET label##2b-label##5b; \ 49*4882a593Smuzhiyun FTR_ENTRY_OFFSET label##3b-label##5b; \ 50*4882a593Smuzhiyun FTR_ENTRY_OFFSET label##4b-label##5b; \ 51*4882a593Smuzhiyun .ifgt (label##4b- label##3b)-(label##2b- label##1b); \ 52*4882a593Smuzhiyun .error "Feature section else case larger than body"; \ 53*4882a593Smuzhiyun .endif; \ 54*4882a593Smuzhiyun .popsection; 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun /* CPU feature dependent sections */ 58*4882a593Smuzhiyun #define BEGIN_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 59*4882a593Smuzhiyun #define BEGIN_FTR_SECTION START_FTR_SECTION(97) 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun #define END_FTR_SECTION_NESTED(msk, val, label) \ 62*4882a593Smuzhiyun FTR_SECTION_ELSE_NESTED(label) \ 63*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define END_FTR_SECTION(msk, val) \ 66*4882a593Smuzhiyun END_FTR_SECTION_NESTED(msk, val, 97) 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun #define END_FTR_SECTION_NESTED_IFSET(msk, label) \ 69*4882a593Smuzhiyun END_FTR_SECTION_NESTED((msk), (msk), label) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun #define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) 72*4882a593Smuzhiyun #define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /* CPU feature sections with alternatives, use BEGIN_FTR_SECTION to start */ 75*4882a593Smuzhiyun #define FTR_SECTION_ELSE FTR_SECTION_ELSE_NESTED(97) 76*4882a593Smuzhiyun #define ALT_FTR_SECTION_END_NESTED(msk, val, label) \ 77*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) 78*4882a593Smuzhiyun #define ALT_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 79*4882a593Smuzhiyun ALT_FTR_SECTION_END_NESTED(msk, msk, label) 80*4882a593Smuzhiyun #define ALT_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 81*4882a593Smuzhiyun ALT_FTR_SECTION_END_NESTED(msk, 0, label) 82*4882a593Smuzhiyun #define ALT_FTR_SECTION_END(msk, val) \ 83*4882a593Smuzhiyun ALT_FTR_SECTION_END_NESTED(msk, val, 97) 84*4882a593Smuzhiyun #define ALT_FTR_SECTION_END_IFSET(msk) \ 85*4882a593Smuzhiyun ALT_FTR_SECTION_END_NESTED_IFSET(msk, 97) 86*4882a593Smuzhiyun #define ALT_FTR_SECTION_END_IFCLR(msk) \ 87*4882a593Smuzhiyun ALT_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* MMU feature dependent sections */ 90*4882a593Smuzhiyun #define BEGIN_MMU_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 91*4882a593Smuzhiyun #define BEGIN_MMU_FTR_SECTION START_FTR_SECTION(97) 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun #define END_MMU_FTR_SECTION_NESTED(msk, val, label) \ 94*4882a593Smuzhiyun FTR_SECTION_ELSE_NESTED(label) \ 95*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun #define END_MMU_FTR_SECTION(msk, val) \ 98*4882a593Smuzhiyun END_MMU_FTR_SECTION_NESTED(msk, val, 97) 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun #define END_MMU_FTR_SECTION_NESTED_IFSET(msk, label) \ 101*4882a593Smuzhiyun END_MMU_FTR_SECTION_NESTED((msk), (msk), label) 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun #define END_MMU_FTR_SECTION_IFSET(msk) END_MMU_FTR_SECTION((msk), (msk)) 104*4882a593Smuzhiyun #define END_MMU_FTR_SECTION_IFCLR(msk) END_MMU_FTR_SECTION((msk), 0) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* MMU feature sections with alternatives, use BEGIN_FTR_SECTION to start */ 107*4882a593Smuzhiyun #define MMU_FTR_SECTION_ELSE_NESTED(label) FTR_SECTION_ELSE_NESTED(label) 108*4882a593Smuzhiyun #define MMU_FTR_SECTION_ELSE MMU_FTR_SECTION_ELSE_NESTED(97) 109*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END_NESTED(msk, val, label) \ 110*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup) 111*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 112*4882a593Smuzhiyun ALT_MMU_FTR_SECTION_END_NESTED(msk, msk, label) 113*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 114*4882a593Smuzhiyun ALT_MMU_FTR_SECTION_END_NESTED(msk, 0, label) 115*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END(msk, val) \ 116*4882a593Smuzhiyun ALT_MMU_FTR_SECTION_END_NESTED(msk, val, 97) 117*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END_IFSET(msk) \ 118*4882a593Smuzhiyun ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, 97) 119*4882a593Smuzhiyun #define ALT_MMU_FTR_SECTION_END_IFCLR(msk) \ 120*4882a593Smuzhiyun ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun /* Firmware feature dependent sections */ 123*4882a593Smuzhiyun #define BEGIN_FW_FTR_SECTION_NESTED(label) START_FTR_SECTION(label) 124*4882a593Smuzhiyun #define BEGIN_FW_FTR_SECTION START_FTR_SECTION(97) 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun #define END_FW_FTR_SECTION_NESTED(msk, val, label) \ 127*4882a593Smuzhiyun FTR_SECTION_ELSE_NESTED(label) \ 128*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup) 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun #define END_FW_FTR_SECTION(msk, val) \ 131*4882a593Smuzhiyun END_FW_FTR_SECTION_NESTED(msk, val, 97) 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #define END_FW_FTR_SECTION_IFSET(msk) END_FW_FTR_SECTION((msk), (msk)) 134*4882a593Smuzhiyun #define END_FW_FTR_SECTION_IFCLR(msk) END_FW_FTR_SECTION((msk), 0) 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* Firmware feature sections with alternatives */ 137*4882a593Smuzhiyun #define FW_FTR_SECTION_ELSE_NESTED(label) FTR_SECTION_ELSE_NESTED(label) 138*4882a593Smuzhiyun #define FW_FTR_SECTION_ELSE FTR_SECTION_ELSE_NESTED(97) 139*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END_NESTED(msk, val, label) \ 140*4882a593Smuzhiyun MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup) 141*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, label) \ 142*4882a593Smuzhiyun ALT_FW_FTR_SECTION_END_NESTED(msk, msk, label) 143*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, label) \ 144*4882a593Smuzhiyun ALT_FW_FTR_SECTION_END_NESTED(msk, 0, label) 145*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END(msk, val) \ 146*4882a593Smuzhiyun ALT_FW_FTR_SECTION_END_NESTED(msk, val, 97) 147*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END_IFSET(msk) \ 148*4882a593Smuzhiyun ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, 97) 149*4882a593Smuzhiyun #define ALT_FW_FTR_SECTION_END_IFCLR(msk) \ 150*4882a593Smuzhiyun ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, 97) 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define ASM_FTR_IF(section_if, section_else, msk, val) \ 155*4882a593Smuzhiyun stringify_in_c(BEGIN_FTR_SECTION) \ 156*4882a593Smuzhiyun section_if "; " \ 157*4882a593Smuzhiyun stringify_in_c(FTR_SECTION_ELSE) \ 158*4882a593Smuzhiyun section_else "; " \ 159*4882a593Smuzhiyun stringify_in_c(ALT_FTR_SECTION_END((msk), (val))) 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun #define ASM_FTR_IFSET(section_if, section_else, msk) \ 162*4882a593Smuzhiyun ASM_FTR_IF(section_if, section_else, (msk), (msk)) 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun #define ASM_FTR_IFCLR(section_if, section_else, msk) \ 165*4882a593Smuzhiyun ASM_FTR_IF(section_if, section_else, (msk), 0) 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun #define ASM_MMU_FTR_IF(section_if, section_else, msk, val) \ 168*4882a593Smuzhiyun stringify_in_c(BEGIN_MMU_FTR_SECTION) \ 169*4882a593Smuzhiyun section_if "; " \ 170*4882a593Smuzhiyun stringify_in_c(MMU_FTR_SECTION_ELSE) \ 171*4882a593Smuzhiyun section_else "; " \ 172*4882a593Smuzhiyun stringify_in_c(ALT_MMU_FTR_SECTION_END((msk), (val))) 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun #define ASM_MMU_FTR_IFSET(section_if, section_else, msk) \ 175*4882a593Smuzhiyun ASM_MMU_FTR_IF(section_if, section_else, (msk), (msk)) 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun #define ASM_MMU_FTR_IFCLR(section_if, section_else, msk) \ 178*4882a593Smuzhiyun ASM_MMU_FTR_IF(section_if, section_else, (msk), 0) 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */ 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun /* LWSYNC feature sections */ 183*4882a593Smuzhiyun #define START_LWSYNC_SECTION(label) label##1: 184*4882a593Smuzhiyun #define MAKE_LWSYNC_SECTION_ENTRY(label, sect) \ 185*4882a593Smuzhiyun label##2: \ 186*4882a593Smuzhiyun .pushsection sect,"a"; \ 187*4882a593Smuzhiyun .align 2; \ 188*4882a593Smuzhiyun label##3: \ 189*4882a593Smuzhiyun FTR_ENTRY_OFFSET label##1b-label##3b; \ 190*4882a593Smuzhiyun .popsection; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun #define STF_ENTRY_BARRIER_FIXUP_SECTION \ 193*4882a593Smuzhiyun 953: \ 194*4882a593Smuzhiyun .pushsection __stf_entry_barrier_fixup,"a"; \ 195*4882a593Smuzhiyun .align 2; \ 196*4882a593Smuzhiyun 954: \ 197*4882a593Smuzhiyun FTR_ENTRY_OFFSET 953b-954b; \ 198*4882a593Smuzhiyun .popsection; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun #define STF_EXIT_BARRIER_FIXUP_SECTION \ 201*4882a593Smuzhiyun 955: \ 202*4882a593Smuzhiyun .pushsection __stf_exit_barrier_fixup,"a"; \ 203*4882a593Smuzhiyun .align 2; \ 204*4882a593Smuzhiyun 956: \ 205*4882a593Smuzhiyun FTR_ENTRY_OFFSET 955b-956b; \ 206*4882a593Smuzhiyun .popsection; 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun #define UACCESS_FLUSH_FIXUP_SECTION \ 209*4882a593Smuzhiyun 959: \ 210*4882a593Smuzhiyun .pushsection __uaccess_flush_fixup,"a"; \ 211*4882a593Smuzhiyun .align 2; \ 212*4882a593Smuzhiyun 960: \ 213*4882a593Smuzhiyun FTR_ENTRY_OFFSET 959b-960b; \ 214*4882a593Smuzhiyun .popsection; 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun #define ENTRY_FLUSH_FIXUP_SECTION \ 217*4882a593Smuzhiyun 957: \ 218*4882a593Smuzhiyun .pushsection __entry_flush_fixup,"a"; \ 219*4882a593Smuzhiyun .align 2; \ 220*4882a593Smuzhiyun 958: \ 221*4882a593Smuzhiyun FTR_ENTRY_OFFSET 957b-958b; \ 222*4882a593Smuzhiyun .popsection; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun #define SCV_ENTRY_FLUSH_FIXUP_SECTION \ 225*4882a593Smuzhiyun 957: \ 226*4882a593Smuzhiyun .pushsection __scv_entry_flush_fixup,"a"; \ 227*4882a593Smuzhiyun .align 2; \ 228*4882a593Smuzhiyun 958: \ 229*4882a593Smuzhiyun FTR_ENTRY_OFFSET 957b-958b; \ 230*4882a593Smuzhiyun .popsection; 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun #define RFI_FLUSH_FIXUP_SECTION \ 233*4882a593Smuzhiyun 951: \ 234*4882a593Smuzhiyun .pushsection __rfi_flush_fixup,"a"; \ 235*4882a593Smuzhiyun .align 2; \ 236*4882a593Smuzhiyun 952: \ 237*4882a593Smuzhiyun FTR_ENTRY_OFFSET 951b-952b; \ 238*4882a593Smuzhiyun .popsection; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun #define NOSPEC_BARRIER_FIXUP_SECTION \ 241*4882a593Smuzhiyun 953: \ 242*4882a593Smuzhiyun .pushsection __barrier_nospec_fixup,"a"; \ 243*4882a593Smuzhiyun .align 2; \ 244*4882a593Smuzhiyun 954: \ 245*4882a593Smuzhiyun FTR_ENTRY_OFFSET 953b-954b; \ 246*4882a593Smuzhiyun .popsection; 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun #define START_BTB_FLUSH_SECTION \ 249*4882a593Smuzhiyun 955: \ 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun #define END_BTB_FLUSH_SECTION \ 252*4882a593Smuzhiyun 956: \ 253*4882a593Smuzhiyun .pushsection __btb_flush_fixup,"a"; \ 254*4882a593Smuzhiyun .align 2; \ 255*4882a593Smuzhiyun 957: \ 256*4882a593Smuzhiyun FTR_ENTRY_OFFSET 955b-957b; \ 257*4882a593Smuzhiyun FTR_ENTRY_OFFSET 956b-957b; \ 258*4882a593Smuzhiyun .popsection; 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 261*4882a593Smuzhiyun #include <linux/types.h> 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun extern long stf_barrier_fallback; 264*4882a593Smuzhiyun extern long entry_flush_fallback; 265*4882a593Smuzhiyun extern long scv_entry_flush_fallback; 266*4882a593Smuzhiyun extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; 267*4882a593Smuzhiyun extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; 268*4882a593Smuzhiyun extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; 269*4882a593Smuzhiyun extern long __start___entry_flush_fixup, __stop___entry_flush_fixup; 270*4882a593Smuzhiyun extern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup; 271*4882a593Smuzhiyun extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; 272*4882a593Smuzhiyun extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; 273*4882a593Smuzhiyun extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun void apply_feature_fixups(void); 276*4882a593Smuzhiyun void setup_feature_keys(void); 277*4882a593Smuzhiyun #endif 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun #endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */ 280