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