1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright IBM Corp. 2024 4 */ 5 6 #ifndef __ASM_S390_MACHINE_H 7 #define __ASM_S390_MACHINE_H 8 9 #include <linux/const.h> 10 11 #define MFEATURE_LOWCORE 0 12 #define MFEATURE_PCI_MIO 1 13 #define MFEATURE_SCC 2 14 #define MFEATURE_TLB_GUEST 3 15 #define MFEATURE_TX 4 16 #define MFEATURE_ESOP 5 17 #define MFEATURE_DIAG9C 6 18 #define MFEATURE_VM 7 19 #define MFEATURE_KVM 8 20 #define MFEATURE_LPAR 9 21 #define MFEATURE_DIAG288 10 22 23 #ifndef __ASSEMBLY__ 24 25 #include <linux/bitops.h> 26 #include <asm/alternative.h> 27 28 extern unsigned long machine_features[1]; 29 30 #define MAX_MFEATURE_BIT (sizeof(machine_features) * BITS_PER_BYTE) 31 32 static inline void __set_machine_feature(unsigned int nr, unsigned long *mfeatures) 33 { 34 if (nr >= MAX_MFEATURE_BIT) 35 return; 36 __set_bit(nr, mfeatures); 37 } 38 39 static inline void set_machine_feature(unsigned int nr) 40 { 41 __set_machine_feature(nr, machine_features); 42 } 43 44 static inline void __clear_machine_feature(unsigned int nr, unsigned long *mfeatures) 45 { 46 if (nr >= MAX_MFEATURE_BIT) 47 return; 48 __clear_bit(nr, mfeatures); 49 } 50 51 static inline void clear_machine_feature(unsigned int nr) 52 { 53 __clear_machine_feature(nr, machine_features); 54 } 55 56 static bool __test_machine_feature(unsigned int nr, unsigned long *mfeatures) 57 { 58 if (nr >= MAX_MFEATURE_BIT) 59 return false; 60 return test_bit(nr, mfeatures); 61 } 62 63 static bool test_machine_feature(unsigned int nr) 64 { 65 return __test_machine_feature(nr, machine_features); 66 } 67 68 static __always_inline bool __test_machine_feature_constant(unsigned int nr) 69 { 70 asm goto( 71 ALTERNATIVE("brcl 15,%l[l_no]", "brcl 0,0", ALT_FEATURE(%[nr])) 72 : 73 : [nr] "i" (nr) 74 : 75 : l_no); 76 return true; 77 l_no: 78 return false; 79 } 80 81 #define DEFINE_MACHINE_HAS_FEATURE(name, feature) \ 82 static __always_inline bool machine_has_##name(void) \ 83 { \ 84 if (!__is_defined(__DECOMPRESSOR) && __builtin_constant_p(feature)) \ 85 return __test_machine_feature_constant(feature); \ 86 return test_machine_feature(feature); \ 87 } 88 89 DEFINE_MACHINE_HAS_FEATURE(relocated_lowcore, MFEATURE_LOWCORE) 90 DEFINE_MACHINE_HAS_FEATURE(scc, MFEATURE_SCC) 91 DEFINE_MACHINE_HAS_FEATURE(tlb_guest, MFEATURE_TLB_GUEST) 92 DEFINE_MACHINE_HAS_FEATURE(tx, MFEATURE_TX) 93 DEFINE_MACHINE_HAS_FEATURE(esop, MFEATURE_ESOP) 94 DEFINE_MACHINE_HAS_FEATURE(diag9c, MFEATURE_DIAG9C) 95 DEFINE_MACHINE_HAS_FEATURE(vm, MFEATURE_VM) 96 DEFINE_MACHINE_HAS_FEATURE(kvm, MFEATURE_KVM) 97 DEFINE_MACHINE_HAS_FEATURE(lpar, MFEATURE_LPAR) 98 99 #define machine_is_vm machine_has_vm 100 #define machine_is_kvm machine_has_kvm 101 #define machine_is_lpar machine_has_lpar 102 103 #endif /* __ASSEMBLY__ */ 104 #endif /* __ASM_S390_MACHINE_H */ 105