| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright IBM Corp. 2022 |
| */ |
| |
| #include <linux/cpufeature.h> |
| #include <linux/bug.h> |
| #include <asm/elf.h> |
| |
| enum { |
| TYPE_HWCAP, |
| TYPE_FACILITY, |
| }; |
| |
| struct s390_cpu_feature { |
| unsigned int type : 4; |
| unsigned int num : 28; |
| }; |
| |
| static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = { |
| [S390_CPU_FEATURE_MSA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA}, |
| [S390_CPU_FEATURE_VXRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS}, |
| [S390_CPU_FEATURE_UV] = {.type = TYPE_FACILITY, .num = 158}, |
| }; |
| |
| /* |
| * cpu_have_feature - Test CPU features on module initialization |
| */ |
| int cpu_have_feature(unsigned int num) |
| { |
| struct s390_cpu_feature *feature; |
| |
| if (WARN_ON_ONCE(num >= MAX_CPU_FEATURES)) |
| return 0; |
| feature = &s390_cpu_features[num]; |
| switch (feature->type) { |
| case TYPE_HWCAP: |
| return !!(elf_hwcap & BIT(feature->num)); |
| case TYPE_FACILITY: |
| return test_facility(feature->num); |
| default: |
| WARN_ON_ONCE(1); |
| return 0; |
| } |
| } |
| EXPORT_SYMBOL(cpu_have_feature); |