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