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 __ASSEMBLER__
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
__set_machine_feature(unsigned int nr,unsigned long * mfeatures)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
set_machine_feature(unsigned int nr)39 static inline void set_machine_feature(unsigned int nr)
40 {
41 __set_machine_feature(nr, machine_features);
42 }
43
__clear_machine_feature(unsigned int nr,unsigned long * mfeatures)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
clear_machine_feature(unsigned int nr)51 static inline void clear_machine_feature(unsigned int nr)
52 {
53 __clear_machine_feature(nr, machine_features);
54 }
55
__test_machine_feature(unsigned int nr,unsigned long * mfeatures)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
test_machine_feature(unsigned int nr)63 static bool test_machine_feature(unsigned int nr)
64 {
65 return __test_machine_feature(nr, machine_features);
66 }
67
__test_machine_feature_constant(unsigned int nr)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 /* __ASSEMBLER__ */
104 #endif /* __ASM_S390_MACHINE_H */
105