xref: /linux/tools/testing/selftests/kvm/include/s390/facility.h (revision 7d8d6ad659c02ed5d2387777194c22e8e81dbb2b)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright IBM Corp. 2024
4  *
5  * Authors:
6  *  Hariharan Mari <hari55@linux.ibm.com>
7  *
8  * Get the facility bits with the STFLE instruction
9  */
10 
11 #ifndef SELFTEST_KVM_FACILITY_H
12 #define SELFTEST_KVM_FACILITY_H
13 
14 #include <linux/atomic.h>
15 #include <linux/bitops.h>
16 
17 /* alt_stfle_fac_list[16] + stfle_fac_list[16] */
18 #define NB_STFL_DOUBLEWORDS 32
19 
20 extern u64 stfl_doublewords[NB_STFL_DOUBLEWORDS];
21 extern bool stfle_flag;
22 
23 static inline bool clear_bit_inv(unsigned long nr, unsigned long *ptr)
24 {
25 	return clear_bit(nr ^ (BITS_PER_LONG - 1), ptr);
26 }
27 
28 static inline bool test_bit_inv(unsigned long nr, const unsigned long *ptr)
29 {
30 	return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
31 }
32 
33 static inline void stfle(u64 *fac, unsigned int nb_doublewords)
34 {
35 	register unsigned long r0 asm("0") = nb_doublewords - 1;
36 
37 	asm volatile("	.insn	s,0xb2b00000,0(%1)\n"
38 			: "+d" (r0)
39 			: "a" (fac)
40 			: "memory", "cc");
41 }
42 
43 static inline void setup_facilities(void)
44 {
45 	stfle(stfl_doublewords, NB_STFL_DOUBLEWORDS);
46 	stfle_flag = true;
47 }
48 
49 static inline bool test_facility(int nr)
50 {
51 	if (!stfle_flag)
52 		setup_facilities();
53 	return test_bit_inv(nr, stfl_doublewords);
54 }
55 
56 #endif
57