xref: /linux/arch/s390/kernel/cpufeature.c (revision bca5cfbb694d66a1c482d0c347eee80f6afbc870)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright IBM Corp. 2022
4  */
5 
6 #include <linux/cpufeature.h>
7 #include <linux/bug.h>
8 #include <asm/machine.h>
9 #include <asm/elf.h>
10 
11 enum {
12 	TYPE_HWCAP,
13 	TYPE_FACILITY,
14 	TYPE_MACHINE,
15 };
16 
17 struct s390_cpu_feature {
18 	unsigned int type	: 4;
19 	unsigned int num	: 28;
20 };
21 
22 static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
23 	[S390_CPU_FEATURE_MSA]	= {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA},
24 	[S390_CPU_FEATURE_VXRS]	= {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS},
25 	[S390_CPU_FEATURE_UV]	= {.type = TYPE_FACILITY, .num = 158},
26 	[S390_CPU_FEATURE_D288]	= {.type = TYPE_MACHINE, .num = MFEATURE_DIAG288},
27 };
28 
29 /*
30  * cpu_have_feature - Test CPU features on module initialization
31  */
32 int cpu_have_feature(unsigned int num)
33 {
34 	struct s390_cpu_feature *feature;
35 
36 	if (WARN_ON_ONCE(num >= MAX_CPU_FEATURES))
37 		return 0;
38 	feature = &s390_cpu_features[num];
39 	switch (feature->type) {
40 	case TYPE_HWCAP:
41 		return !!(elf_hwcap & BIT(feature->num));
42 	case TYPE_FACILITY:
43 		return test_facility(feature->num);
44 	case TYPE_MACHINE:
45 		return test_machine_feature(feature->num);
46 	default:
47 		WARN_ON_ONCE(1);
48 		return 0;
49 	}
50 }
51 EXPORT_SYMBOL(cpu_have_feature);
52