2022-07-12 11:11:07

by Steffen Eiden

[permalink] [raw]
Subject: [PATCH 0/3] s390/cpufeature: rework to allow different types of cpufeatures

Currently the s390 implementaion of cpufeature is limited to elf_hwcap
bits. Using these to automatically load modules also exposes this
cpufeature to userspace which, sometimes is not intended.

Therefore, rework the s390-cpufeature implementation to allow for
various cpu feature indications, which is not only limited to hwcap bits.

Add a new type to allow facilities to be a cpufeature without using
hwcap bits that expose this feature to userspace.

Load uvdevice when facility 158 is present.

Heiko Carstens (1):
s390/cpufeature: allow for facility bits

Steffen Eiden (2):
s390/cpufeature: rework to allow more than only hwcap bits
s390/uvdevice: autoload module based on CPU facility

arch/s390/crypto/aes_s390.c | 2 +-
arch/s390/crypto/chacha-glue.c | 2 +-
arch/s390/crypto/crc32-vx.c | 2 +-
arch/s390/crypto/des_s390.c | 2 +-
arch/s390/crypto/ghash_s390.c | 2 +-
arch/s390/crypto/prng.c | 2 +-
arch/s390/crypto/sha1_s390.c | 2 +-
arch/s390/crypto/sha256_s390.c | 2 +-
arch/s390/crypto/sha3_256_s390.c | 2 +-
arch/s390/crypto/sha3_512_s390.c | 2 +-
arch/s390/crypto/sha512_s390.c | 2 +-
arch/s390/include/asm/cpufeature.h | 44 +++++++++++++-------
arch/s390/kernel/Makefile | 2 +-
arch/s390/kernel/cpufeature.c | 66 ++++++++++++++++++++++++++++++
arch/s390/kernel/processor.c | 10 -----
drivers/char/hw_random/s390-trng.c | 2 +-
drivers/s390/char/uvdevice.c | 5 +--
drivers/s390/crypto/pkey_api.c | 2 +-
18 files changed, 111 insertions(+), 42 deletions(-)
create mode 100644 arch/s390/kernel/cpufeature.c

--
2.35.3


2022-07-12 11:12:13

by Steffen Eiden

[permalink] [raw]
Subject: [PATCH 3/3] s390/uvdevice: autoload module based on CPU facility

Make sure the uvdevice driver will be automatically loaded when
facility 158 is available.

Signed-off-by: Steffen Eiden <[email protected]>
---
arch/s390/include/asm/cpufeature.h | 1 +
arch/s390/kernel/cpufeature.c | 1 +
drivers/s390/char/uvdevice.c | 5 ++---
3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h
index aa8081dad411..4b17f876ab54 100644
--- a/arch/s390/include/asm/cpufeature.h
+++ b/arch/s390/include/asm/cpufeature.h
@@ -33,6 +33,7 @@ enum {
S390_CPU_FEATURE_NNPA,
S390_CPU_FEATURE_PCI_MIO,
S390_CPU_FEATURE_SIE,
+ S390_CPU_FEATURE_UV,
MAX_CPU_FEATURES
};

diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
index e70b29804db4..0b854d37edcb 100644
--- a/arch/s390/kernel/cpufeature.c
+++ b/arch/s390/kernel/cpufeature.c
@@ -42,6 +42,7 @@ static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
[S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
[S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
[S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
+ [S390_CPU_FEATURE_UV] = {.type = TYPE_FACILITY, .num = 158},
};

/*
diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c
index 66505d7166a6..1d40457c7b10 100644
--- a/drivers/s390/char/uvdevice.c
+++ b/drivers/s390/char/uvdevice.c
@@ -27,6 +27,7 @@
#include <linux/stddef.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/cpufeature.h>

#include <asm/uvdevice.h>
#include <asm/uv.h>
@@ -244,12 +245,10 @@ static void __exit uvio_dev_exit(void)

static int __init uvio_dev_init(void)
{
- if (!test_facility(158))
- return -ENXIO;
return misc_register(&uvio_dev_miscdev);
}

-module_init(uvio_dev_init);
+module_cpu_feature_match(S390_CPU_FEATURE_UV, uvio_dev_init);
module_exit(uvio_dev_exit);

MODULE_AUTHOR("IBM Corporation");
--
2.35.3

2022-07-12 11:13:25

by Steffen Eiden

[permalink] [raw]
Subject: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

Rework cpufeature implementation to allow for various cpu feature
indications, which is not only limited to hwcap bits. This is achieved
by adding a sequential list of cpu feature numbers, where each of them
is mapped to an entry which indicates what this number is about.

Each entry contains a type member, which indicates what feature
name space to look into (e.g. hwcap, or cpu facility). If wanted this
allows also to automatically load modules only in e.g. z/VM
configurations.

Signed-off-by: Steffen Eiden <[email protected]>
Signed-off-by: Heiko Carstens <[email protected]>
---
arch/s390/crypto/aes_s390.c | 2 +-
arch/s390/crypto/chacha-glue.c | 2 +-
arch/s390/crypto/crc32-vx.c | 2 +-
arch/s390/crypto/des_s390.c | 2 +-
arch/s390/crypto/ghash_s390.c | 2 +-
arch/s390/crypto/prng.c | 2 +-
arch/s390/crypto/sha1_s390.c | 2 +-
arch/s390/crypto/sha256_s390.c | 2 +-
arch/s390/crypto/sha3_256_s390.c | 2 +-
arch/s390/crypto/sha3_512_s390.c | 2 +-
arch/s390/crypto/sha512_s390.c | 2 +-
arch/s390/include/asm/cpufeature.h | 43 +++++++++++++--------
arch/s390/kernel/Makefile | 2 +-
arch/s390/kernel/cpufeature.c | 62 ++++++++++++++++++++++++++++++
arch/s390/kernel/processor.c | 10 -----
drivers/char/hw_random/s390-trng.c | 2 +-
drivers/s390/crypto/pkey_api.c | 2 +-
17 files changed, 104 insertions(+), 39 deletions(-)
create mode 100644 arch/s390/kernel/cpufeature.c

diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 1023e9d43d44..526c3f40f6a2 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -1049,7 +1049,7 @@ static int __init aes_s390_init(void)
return ret;
}

-module_cpu_feature_match(MSA, aes_s390_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, aes_s390_init);
module_exit(aes_s390_fini);

MODULE_ALIAS_CRYPTO("aes-all");
diff --git a/arch/s390/crypto/chacha-glue.c b/arch/s390/crypto/chacha-glue.c
index 2ec51f339cec..7752bd314558 100644
--- a/arch/s390/crypto/chacha-glue.c
+++ b/arch/s390/crypto/chacha-glue.c
@@ -121,7 +121,7 @@ static void __exit chacha_mod_fini(void)
crypto_unregister_skciphers(chacha_algs, ARRAY_SIZE(chacha_algs));
}

-module_cpu_feature_match(VXRS, chacha_mod_init);
+module_cpu_feature_match(S390_CPU_FEATURE_VXRS, chacha_mod_init);
module_exit(chacha_mod_fini);

MODULE_DESCRIPTION("ChaCha20 stream cipher");
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
index fafecad20752..017143e9cef7 100644
--- a/arch/s390/crypto/crc32-vx.c
+++ b/arch/s390/crypto/crc32-vx.c
@@ -298,7 +298,7 @@ static void __exit crc_vx_mod_exit(void)
crypto_unregister_shashes(crc32_vx_algs, ARRAY_SIZE(crc32_vx_algs));
}

-module_cpu_feature_match(VXRS, crc_vx_mod_init);
+module_cpu_feature_match(S390_CPU_FEATURE_VXRS, crc_vx_mod_init);
module_exit(crc_vx_mod_exit);

MODULE_AUTHOR("Hendrik Brueckner <[email protected]>");
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index e013088b5115..8e75b83a5ddc 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -492,7 +492,7 @@ static int __init des_s390_init(void)
return ret;
}

-module_cpu_feature_match(MSA, des_s390_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, des_s390_init);
module_exit(des_s390_exit);

MODULE_ALIAS_CRYPTO("des");
diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c
index 6b07a2f1ce8a..0800a2a5799f 100644
--- a/arch/s390/crypto/ghash_s390.c
+++ b/arch/s390/crypto/ghash_s390.c
@@ -145,7 +145,7 @@ static void __exit ghash_mod_exit(void)
crypto_unregister_shash(&ghash_alg);
}

-module_cpu_feature_match(MSA, ghash_mod_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, ghash_mod_init);
module_exit(ghash_mod_exit);

MODULE_ALIAS_CRYPTO("ghash");
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index ae382bafc772..a077087bc6cc 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -907,5 +907,5 @@ static void __exit prng_exit(void)
}
}

-module_cpu_feature_match(MSA, prng_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, prng_init);
module_exit(prng_exit);
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index a3fabf310a38..bc3a22704e09 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -95,7 +95,7 @@ static void __exit sha1_s390_fini(void)
crypto_unregister_shash(&alg);
}

-module_cpu_feature_match(MSA, sha1_s390_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha1_s390_init);
module_exit(sha1_s390_fini);

MODULE_ALIAS_CRYPTO("sha1");
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index 24983f175676..6f1ccdf93d3e 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -134,7 +134,7 @@ static void __exit sha256_s390_fini(void)
crypto_unregister_shash(&sha256_alg);
}

-module_cpu_feature_match(MSA, sha256_s390_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha256_s390_init);
module_exit(sha256_s390_fini);

MODULE_ALIAS_CRYPTO("sha256");
diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s390.c
index 30ac49b635bf..e1350e033a32 100644
--- a/arch/s390/crypto/sha3_256_s390.c
+++ b/arch/s390/crypto/sha3_256_s390.c
@@ -137,7 +137,7 @@ static void __exit sha3_256_s390_fini(void)
crypto_unregister_shash(&sha3_256_alg);
}

-module_cpu_feature_match(MSA, sha3_256_s390_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha3_256_s390_init);
module_exit(sha3_256_s390_fini);

MODULE_ALIAS_CRYPTO("sha3-256");
diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s390.c
index e70d50f7620f..06c142ed9bb1 100644
--- a/arch/s390/crypto/sha3_512_s390.c
+++ b/arch/s390/crypto/sha3_512_s390.c
@@ -147,7 +147,7 @@ static void __exit fini(void)
crypto_unregister_shash(&sha3_384_alg);
}

-module_cpu_feature_match(MSA, init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, init);
module_exit(fini);

MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c
index 43ce4956df73..04f11c407763 100644
--- a/arch/s390/crypto/sha512_s390.c
+++ b/arch/s390/crypto/sha512_s390.c
@@ -142,7 +142,7 @@ static void __exit fini(void)
crypto_unregister_shash(&sha384_alg);
}

-module_cpu_feature_match(MSA, init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, init);
module_exit(fini);

MODULE_LICENSE("GPL");
diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h
index 14cfd48d598e..aa8081dad411 100644
--- a/arch/s390/include/asm/cpufeature.h
+++ b/arch/s390/include/asm/cpufeature.h
@@ -2,28 +2,41 @@
/*
* Module interface for CPU features
*
- * Copyright IBM Corp. 2015
+ * Copyright IBM Corp. 2015, 2022
* Author(s): Hendrik Brueckner <[email protected]>
*/

#ifndef __ASM_S390_CPUFEATURE_H
#define __ASM_S390_CPUFEATURE_H

-#include <asm/elf.h>
+enum {
+ S390_CPU_FEATURE_ESAN3,
+ S390_CPU_FEATURE_ZARCH,
+ S390_CPU_FEATURE_STFLE,
+ S390_CPU_FEATURE_MSA,
+ S390_CPU_FEATURE_LDISP,
+ S390_CPU_FEATURE_EIMM,
+ S390_CPU_FEATURE_DFP,
+ S390_CPU_FEATURE_HPAGE,
+ S390_CPU_FEATURE_ETF3EH,
+ S390_CPU_FEATURE_HIGH_GPRS,
+ S390_CPU_FEATURE_TE,
+ S390_CPU_FEATURE_VXRS,
+ S390_CPU_FEATURE_VXRS_BCD,
+ S390_CPU_FEATURE_VXRS_EXT,
+ S390_CPU_FEATURE_GS,
+ S390_CPU_FEATURE_VXRS_EXT2,
+ S390_CPU_FEATURE_VXRS_PDE,
+ S390_CPU_FEATURE_SORT,
+ S390_CPU_FEATURE_DFLT,
+ S390_CPU_FEATURE_VXRS_PDE2,
+ S390_CPU_FEATURE_NNPA,
+ S390_CPU_FEATURE_PCI_MIO,
+ S390_CPU_FEATURE_SIE,
+ MAX_CPU_FEATURES
+};

-/* Hardware features on Linux on z Systems are indicated by facility bits that
- * are mapped to the so-called machine flags. Particular machine flags are
- * then used to define ELF hardware capabilities; most notably hardware flags
- * that are essential for user space / glibc.
- *
- * Restrict the set of exposed CPU features to ELF hardware capabilities for
- * now. Additional machine flags can be indicated by values larger than
- * MAX_ELF_HWCAP_FEATURES.
- */
-#define MAX_ELF_HWCAP_FEATURES (8 * sizeof(elf_hwcap))
-#define MAX_CPU_FEATURES MAX_ELF_HWCAP_FEATURES
-
-#define cpu_feature(feat) ilog2(HWCAP_ ## feat)
+#define cpu_feature(feature) (feature)

int cpu_have_feature(unsigned int nr);

diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 27d6b3c7aa06..3cbfa9fddd9a 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -35,7 +35,7 @@ CFLAGS_unwind_bc.o += -fno-optimize-sibling-calls

obj-y := traps.o time.o process.o earlypgm.o early.o setup.o idle.o vtime.o
obj-y += processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
-obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o
+obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o cpufeature.o
obj-y += sysinfo.o lgr.o os_info.o machine_kexec.o
obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o
obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o
diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
new file mode 100644
index 000000000000..ea4bbfd855db
--- /dev/null
+++ b/arch/s390/kernel/cpufeature.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright IBM Corp. 2022
+ * Author(s): Steffen Eiden <[email protected]>
+ * Heiko Carstens <[email protected]>
+ */
+#include <linux/cpufeature.h>
+#include <linux/bug.h>
+#include <asm/elf.h>
+
+enum {
+ TYPE_HWCAP,
+};
+
+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_ESAN3] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ESAN3},
+ [S390_CPU_FEATURE_ZARCH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ZARCH},
+ [S390_CPU_FEATURE_STFLE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_STFLE},
+ [S390_CPU_FEATURE_MSA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA},
+ [S390_CPU_FEATURE_LDISP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_LDISP},
+ [S390_CPU_FEATURE_EIMM] = {.type = TYPE_HWCAP, .num = HWCAP_NR_EIMM},
+ [S390_CPU_FEATURE_DFP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFP},
+ [S390_CPU_FEATURE_HPAGE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HPAGE},
+ [S390_CPU_FEATURE_ETF3EH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ETF3EH},
+ [S390_CPU_FEATURE_HIGH_GPRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HIGH_GPRS},
+ [S390_CPU_FEATURE_TE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_TE},
+ [S390_CPU_FEATURE_VXRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS},
+ [S390_CPU_FEATURE_VXRS_BCD] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_BCD},
+ [S390_CPU_FEATURE_VXRS_EXT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT},
+ [S390_CPU_FEATURE_GS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_GS},
+ [S390_CPU_FEATURE_VXRS_EXT2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT2},
+ [S390_CPU_FEATURE_VXRS_PDE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE},
+ [S390_CPU_FEATURE_SORT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SORT},
+ [S390_CPU_FEATURE_DFLT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFLT},
+ [S390_CPU_FEATURE_VXRS_PDE2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE2},
+ [S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
+ [S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
+ [S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
+};
+
+/*
+ * cpu_have_feature - Test CPU features on module initialization
+ */
+int cpu_have_feature(unsigned int num)
+{
+ struct s390_cpu_feature *feature;
+
+ feature = &s390_cpu_features[num];
+ switch (feature->type) {
+ case TYPE_HWCAP:
+ return !!(elf_hwcap & (1UL << feature->num));
+ default:
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+}
+EXPORT_SYMBOL(cpu_have_feature);
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index aa0e0e7fc773..a194611ba88c 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -8,7 +8,6 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/stop_machine.h>
-#include <linux/cpufeature.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/random.h>
@@ -96,15 +95,6 @@ void cpu_init(void)
enter_lazy_tlb(&init_mm, current);
}

-/*
- * cpu_have_feature - Test CPU features on module initialization
- */
-int cpu_have_feature(unsigned int num)
-{
- return elf_hwcap & (1UL << num);
-}
-EXPORT_SYMBOL(cpu_have_feature);
-
static void show_facilities(struct seq_file *m)
{
unsigned int bit;
diff --git a/drivers/char/hw_random/s390-trng.c b/drivers/char/hw_random/s390-trng.c
index 2beaa35c0d74..12fbac0ed8ca 100644
--- a/drivers/char/hw_random/s390-trng.c
+++ b/drivers/char/hw_random/s390-trng.c
@@ -261,5 +261,5 @@ static void __exit trng_exit(void)
trng_debug_exit();
}

-module_cpu_feature_match(MSA, trng_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, trng_init);
module_exit(trng_exit);
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 7329caa7d467..5a05d1cdfec2 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -2115,5 +2115,5 @@ static void __exit pkey_exit(void)
pkey_debug_exit();
}

-module_cpu_feature_match(MSA, pkey_init);
+module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_init);
module_exit(pkey_exit);
--
2.35.3

2022-07-12 11:23:21

by Steffen Eiden

[permalink] [raw]
Subject: [PATCH 2/3] s390/cpufeature: allow for facility bits

From: Heiko Carstens <[email protected]>

Allow for facility bits to be used in cpu features.

Signed-off-by: Heiko Carstens <[email protected]>
---
arch/s390/kernel/cpufeature.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
index ea4bbfd855db..e70b29804db4 100644
--- a/arch/s390/kernel/cpufeature.c
+++ b/arch/s390/kernel/cpufeature.c
@@ -10,6 +10,7 @@

enum {
TYPE_HWCAP,
+ TYPE_FACILITY,
};

struct s390_cpu_feature {
@@ -54,6 +55,8 @@ int cpu_have_feature(unsigned int num)
switch (feature->type) {
case TYPE_HWCAP:
return !!(elf_hwcap & (1UL << feature->num));
+ case TYPE_FACILITY:
+ return test_facility(feature->num);
default:
WARN_ON_ONCE(1);
return 0;
--
2.35.3

2022-07-12 12:19:05

by Steffen Eiden

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits



On 7/12/22 12:52, Steffen Eiden wrote:
> Rework cpufeature implementation to allow for various cpu feature
> indications, which is not only limited to hwcap bits. This is achieved
> by adding a sequential list of cpu feature numbers, where each of them
> is mapped to an entry which indicates what this number is about.
>
> Each entry contains a type member, which indicates what feature
> name space to look into (e.g. hwcap, or cpu facility). If wanted this
> allows also to automatically load modules only in e.g. z/VM
> configurations.
>
> Signed-off-by: Steffen Eiden <[email protected]>
> Signed-off-by: Heiko Carstens <[email protected]>

Sorry for the confusion. I modified a rfc from Heiko he sent to me.
My amended modifications also changed the author to myself of that
patch automatically.

Steffen

2022-07-12 17:11:29

by Claudio Imbrenda

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

On Tue, 12 Jul 2022 12:52:18 +0200
Steffen Eiden <[email protected]> wrote:

> Rework cpufeature implementation to allow for various cpu feature
> indications, which is not only limited to hwcap bits. This is achieved
> by adding a sequential list of cpu feature numbers, where each of them
> is mapped to an entry which indicates what this number is about.
>
> Each entry contains a type member, which indicates what feature
> name space to look into (e.g. hwcap, or cpu facility). If wanted this
> allows also to automatically load modules only in e.g. z/VM
> configurations.
>
> Signed-off-by: Steffen Eiden <[email protected]>
> Signed-off-by: Heiko Carstens <[email protected]>

[...]

> +
> +/*
> + * cpu_have_feature - Test CPU features on module initialization
> + */
> +int cpu_have_feature(unsigned int num)
> +{
> + struct s390_cpu_feature *feature;
> +
> + feature = &s390_cpu_features[num];

I would put some check to make sure you are going past the end of the
array.

Maybe something like

if (num >= MAX_CPU_FEATURES) {
WARN(1, "Invalid feature %d", num);
return 0;
}

> + switch (feature->type) {
> + case TYPE_HWCAP:
> + return !!(elf_hwcap & (1UL << feature->num));
> + default:
> + WARN_ON_ONCE(1);
> + return 0;
> + }
> +}
> +EXPORT_SYMBOL(cpu_have_feature);
> diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
> index aa0e0e7fc773..a194611ba88c 100644
> --- a/arch/s390/kernel/processor.c
> +++ b/arch/s390/kernel/processor.c
> @@ -8,7 +8,6 @@
> #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
>
> #include <linux/stop_machine.h>
> -#include <linux/cpufeature.h>
> #include <linux/bitops.h>
> #include <linux/kernel.h>
> #include <linux/random.h>
> @@ -96,15 +95,6 @@ void cpu_init(void)
> enter_lazy_tlb(&init_mm, current);
> }
>
> -/*
> - * cpu_have_feature - Test CPU features on module initialization
> - */
> -int cpu_have_feature(unsigned int num)
> -{
> - return elf_hwcap & (1UL << num);
> -}
> -EXPORT_SYMBOL(cpu_have_feature);
> -
> static void show_facilities(struct seq_file *m)
> {
> unsigned int bit;
> diff --git a/drivers/char/hw_random/s390-trng.c b/drivers/char/hw_random/s390-trng.c
> index 2beaa35c0d74..12fbac0ed8ca 100644
> --- a/drivers/char/hw_random/s390-trng.c
> +++ b/drivers/char/hw_random/s390-trng.c
> @@ -261,5 +261,5 @@ static void __exit trng_exit(void)
> trng_debug_exit();
> }
>
> -module_cpu_feature_match(MSA, trng_init);
> +module_cpu_feature_match(S390_CPU_FEATURE_MSA, trng_init);
> module_exit(trng_exit);
> diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
> index 7329caa7d467..5a05d1cdfec2 100644
> --- a/drivers/s390/crypto/pkey_api.c
> +++ b/drivers/s390/crypto/pkey_api.c
> @@ -2115,5 +2115,5 @@ static void __exit pkey_exit(void)
> pkey_debug_exit();
> }
>
> -module_cpu_feature_match(MSA, pkey_init);
> +module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_init);
> module_exit(pkey_exit);

2022-07-12 17:11:44

by Claudio Imbrenda

[permalink] [raw]
Subject: Re: [PATCH 3/3] s390/uvdevice: autoload module based on CPU facility

On Tue, 12 Jul 2022 12:52:20 +0200
Steffen Eiden <[email protected]> wrote:

> Make sure the uvdevice driver will be automatically loaded when
> facility 158 is available.
>
> Signed-off-by: Steffen Eiden <[email protected]>
> ---
> arch/s390/include/asm/cpufeature.h | 1 +
> arch/s390/kernel/cpufeature.c | 1 +
> drivers/s390/char/uvdevice.c | 5 ++---
> 3 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h
> index aa8081dad411..4b17f876ab54 100644
> --- a/arch/s390/include/asm/cpufeature.h
> +++ b/arch/s390/include/asm/cpufeature.h
> @@ -33,6 +33,7 @@ enum {
> S390_CPU_FEATURE_NNPA,
> S390_CPU_FEATURE_PCI_MIO,
> S390_CPU_FEATURE_SIE,
> + S390_CPU_FEATURE_UV,
> MAX_CPU_FEATURES
> };
>
> diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
> index e70b29804db4..0b854d37edcb 100644
> --- a/arch/s390/kernel/cpufeature.c
> +++ b/arch/s390/kernel/cpufeature.c
> @@ -42,6 +42,7 @@ static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
> [S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
> [S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
> [S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
> + [S390_CPU_FEATURE_UV] = {.type = TYPE_FACILITY, .num = 158},
> };
>
> /*
> diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c
> index 66505d7166a6..1d40457c7b10 100644
> --- a/drivers/s390/char/uvdevice.c
> +++ b/drivers/s390/char/uvdevice.c
> @@ -27,6 +27,7 @@
> #include <linux/stddef.h>
> #include <linux/vmalloc.h>
> #include <linux/slab.h>
> +#include <linux/cpufeature.h>
>
> #include <asm/uvdevice.h>
> #include <asm/uv.h>
> @@ -244,12 +245,10 @@ static void __exit uvio_dev_exit(void)
>
> static int __init uvio_dev_init(void)
> {
> - if (!test_facility(158))
> - return -ENXIO;
> return misc_register(&uvio_dev_miscdev);
> }
>
> -module_init(uvio_dev_init);
> +module_cpu_feature_match(S390_CPU_FEATURE_UV, uvio_dev_init);

does this still prevent manual loading when the feature is not present?

> module_exit(uvio_dev_exit);
>
> MODULE_AUTHOR("IBM Corporation");

2022-07-12 17:28:44

by Claudio Imbrenda

[permalink] [raw]
Subject: Re: [PATCH 2/3] s390/cpufeature: allow for facility bits

On Tue, 12 Jul 2022 12:52:19 +0200
Steffen Eiden <[email protected]> wrote:

> From: Heiko Carstens <[email protected]>
>
> Allow for facility bits to be used in cpu features.
>
> Signed-off-by: Heiko Carstens <[email protected]>

Reviewed-by: Claudio Imbrenda <[email protected]>

> ---
> arch/s390/kernel/cpufeature.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
> index ea4bbfd855db..e70b29804db4 100644
> --- a/arch/s390/kernel/cpufeature.c
> +++ b/arch/s390/kernel/cpufeature.c
> @@ -10,6 +10,7 @@
>
> enum {
> TYPE_HWCAP,
> + TYPE_FACILITY,
> };
>
> struct s390_cpu_feature {
> @@ -54,6 +55,8 @@ int cpu_have_feature(unsigned int num)
> switch (feature->type) {
> case TYPE_HWCAP:
> return !!(elf_hwcap & (1UL << feature->num));
> + case TYPE_FACILITY:
> + return test_facility(feature->num);
> default:
> WARN_ON_ONCE(1);
> return 0;

2022-07-12 19:46:15

by Heiko Carstens

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

On Tue, Jul 12, 2022 at 06:46:19PM +0200, Claudio Imbrenda wrote:
> > +int cpu_have_feature(unsigned int num)
> > +{
> > + struct s390_cpu_feature *feature;
> > +
> > + feature = &s390_cpu_features[num];
>
> I would put some check to make sure you are going past the end of the
> array.
>
> Maybe something like
>
> if (num >= MAX_CPU_FEATURES) {
> WARN(1, "Invalid feature %d", num);
> return 0;

That makes sense. I would go for a simple

if (WARN_ON_ONCE(num >= MAX_CPU_FEATURES))
return 0;

2022-07-12 20:54:34

by Heiko Carstens

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

On Tue, Jul 12, 2022 at 12:52:18PM +0200, Steffen Eiden wrote:
> Rework cpufeature implementation to allow for various cpu feature
> indications, which is not only limited to hwcap bits. This is achieved
> by adding a sequential list of cpu feature numbers, where each of them
> is mapped to an entry which indicates what this number is about.
>
> Each entry contains a type member, which indicates what feature
> name space to look into (e.g. hwcap, or cpu facility). If wanted this
> allows also to automatically load modules only in e.g. z/VM
> configurations.
>
> Signed-off-by: Steffen Eiden <[email protected]>
> Signed-off-by: Heiko Carstens <[email protected]>
...
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright IBM Corp. 2022
> + * Author(s): Steffen Eiden <[email protected]>
> + * Heiko Carstens <[email protected]>

Please don't add my name + email address in source code. I just
recently removed that everywhere since email addresses may change, and
git history is more than enough for me. It's up to you if you want to
keep your name + email address here.

> +static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
> + [S390_CPU_FEATURE_ESAN3] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ESAN3},
> + [S390_CPU_FEATURE_ZARCH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ZARCH},
> + [S390_CPU_FEATURE_STFLE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_STFLE},
> + [S390_CPU_FEATURE_MSA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA},
> + [S390_CPU_FEATURE_LDISP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_LDISP},
> + [S390_CPU_FEATURE_EIMM] = {.type = TYPE_HWCAP, .num = HWCAP_NR_EIMM},
> + [S390_CPU_FEATURE_DFP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFP},
> + [S390_CPU_FEATURE_HPAGE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HPAGE},
> + [S390_CPU_FEATURE_ETF3EH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ETF3EH},
> + [S390_CPU_FEATURE_HIGH_GPRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HIGH_GPRS},
> + [S390_CPU_FEATURE_TE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_TE},
> + [S390_CPU_FEATURE_VXRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS},
> + [S390_CPU_FEATURE_VXRS_BCD] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_BCD},
> + [S390_CPU_FEATURE_VXRS_EXT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT},
> + [S390_CPU_FEATURE_GS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_GS},
> + [S390_CPU_FEATURE_VXRS_EXT2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT2},
> + [S390_CPU_FEATURE_VXRS_PDE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE},
> + [S390_CPU_FEATURE_SORT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SORT},
> + [S390_CPU_FEATURE_DFLT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFLT},
> + [S390_CPU_FEATURE_VXRS_PDE2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE2},
> + [S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
> + [S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
> + [S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
> +};

I only realized now that you added all HWCAP bits here. It was
intentional that I added only the two bits which are currently used
for several reasons:

- Keep the array as small as possible.
- No need to keep this array in sync with HWCAPs, if new ones are added.
- There is a for loop in print_cpu_modalias() which iterates over all
MAX_CPU_FEATURES entries; this should be as fast as possible. Adding
extra entries burns cycles for no added value.

Any future user which requires a not yet listed feature, can simply
add it when needed.

> +int cpu_have_feature(unsigned int num)
> +{
> + struct s390_cpu_feature *feature;
> +
> + feature = &s390_cpu_features[num];
> + switch (feature->type) {
> + case TYPE_HWCAP:
> + return !!(elf_hwcap & (1UL << feature->num));

Before somebody else mentions it, I could have done better. Nowadays
this should be:

return !!(elf_hwcap & BIT(feature->num));

2022-07-13 08:54:53

by Steffen Eiden

[permalink] [raw]
Subject: Re: [PATCH 3/3] s390/uvdevice: autoload module based on CPU facility



On 7/12/22 18:49, Claudio Imbrenda wrote:
> On Tue, 12 Jul 2022 12:52:20 +0200
> Steffen Eiden <[email protected]> wrote:
>
>> Make sure the uvdevice driver will be automatically loaded when
>> facility 158 is available.
>>
>> Signed-off-by: Steffen Eiden <[email protected]>
>> ---
>> arch/s390/include/asm/cpufeature.h | 1 +
>> arch/s390/kernel/cpufeature.c | 1 +
>> drivers/s390/char/uvdevice.c | 5 ++---
>> 3 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h
>> index aa8081dad411..4b17f876ab54 100644
>> --- a/arch/s390/include/asm/cpufeature.h
>> +++ b/arch/s390/include/asm/cpufeature.h
>> @@ -33,6 +33,7 @@ enum {
>> S390_CPU_FEATURE_NNPA,
>> S390_CPU_FEATURE_PCI_MIO,
>> S390_CPU_FEATURE_SIE,
>> + S390_CPU_FEATURE_UV,
>> MAX_CPU_FEATURES
>> };
>>
>> diff --git a/arch/s390/kernel/cpufeature.c b/arch/s390/kernel/cpufeature.c
>> index e70b29804db4..0b854d37edcb 100644
>> --- a/arch/s390/kernel/cpufeature.c
>> +++ b/arch/s390/kernel/cpufeature.c
>> @@ -42,6 +42,7 @@ static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
>> [S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
>> [S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
>> [S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
>> + [S390_CPU_FEATURE_UV] = {.type = TYPE_FACILITY, .num = 158},
>> };
>>
>> /*
>> diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c
>> index 66505d7166a6..1d40457c7b10 100644
>> --- a/drivers/s390/char/uvdevice.c
>> +++ b/drivers/s390/char/uvdevice.c
>> @@ -27,6 +27,7 @@
>> #include <linux/stddef.h>
>> #include <linux/vmalloc.h>
>> #include <linux/slab.h>
>> +#include <linux/cpufeature.h>
>>
>> #include <asm/uvdevice.h>
>> #include <asm/uv.h>
>> @@ -244,12 +245,10 @@ static void __exit uvio_dev_exit(void)
>>
>> static int __init uvio_dev_init(void)
>> {
>> - if (!test_facility(158))
>> - return -ENXIO;
>> return misc_register(&uvio_dev_miscdev);
>> }
>>
>> -module_init(uvio_dev_init);
>> +module_cpu_feature_match(S390_CPU_FEATURE_UV, uvio_dev_init);
>
> does this still prevent manual loading when the feature is not present?
yes.

Have a look at the macro definition at 'include/linux/cpufeature.h':

Use module_cpu_feature_match(feature, module_init_function) to

declare that

[snip]
b) the module must not be loaded if CPU feature 'feature' is not present

(not even by manual insmod).

The test 'facility(158)' just moved to cpu_have_feature() in
'/arch/s390/kernel/cpufeature.c'.
>
>> module_exit(uvio_dev_exit);
>>
>> MODULE_AUTHOR("IBM Corporation");
>

2022-07-13 09:07:36

by Steffen Eiden

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits



On 7/12/22 21:25, Heiko Carstens wrote:
> On Tue, Jul 12, 2022 at 12:52:18PM +0200, Steffen Eiden wrote:
>> Rework cpufeature implementation to allow for various cpu feature
>> indications, which is not only limited to hwcap bits. This is achieved
>> by adding a sequential list of cpu feature numbers, where each of them
>> is mapped to an entry which indicates what this number is about.
>>
>> Each entry contains a type member, which indicates what feature
>> name space to look into (e.g. hwcap, or cpu facility). If wanted this
>> allows also to automatically load modules only in e.g. z/VM
>> configurations.
>>
>> Signed-off-by: Steffen Eiden <[email protected]>
>> Signed-off-by: Heiko Carstens <[email protected]>
> ...
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright IBM Corp. 2022
>> + * Author(s): Steffen Eiden <[email protected]>
>> + * Heiko Carstens <[email protected]>
>
> Please don't add my name + email address in source code. I just
> recently removed that everywhere since email addresses may change, and
> git history is more than enough for me. It's up to you if you want to
> keep your name + email address here.

OK, makes sense.

>
>> +static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
>> + [S390_CPU_FEATURE_ESAN3] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ESAN3},
>> + [S390_CPU_FEATURE_ZARCH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ZARCH},
>> + [S390_CPU_FEATURE_STFLE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_STFLE},
>> + [S390_CPU_FEATURE_MSA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA},
>> + [S390_CPU_FEATURE_LDISP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_LDISP},
>> + [S390_CPU_FEATURE_EIMM] = {.type = TYPE_HWCAP, .num = HWCAP_NR_EIMM},
>> + [S390_CPU_FEATURE_DFP] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFP},
>> + [S390_CPU_FEATURE_HPAGE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HPAGE},
>> + [S390_CPU_FEATURE_ETF3EH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ETF3EH},
>> + [S390_CPU_FEATURE_HIGH_GPRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_HIGH_GPRS},
>> + [S390_CPU_FEATURE_TE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_TE},
>> + [S390_CPU_FEATURE_VXRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS},
>> + [S390_CPU_FEATURE_VXRS_BCD] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_BCD},
>> + [S390_CPU_FEATURE_VXRS_EXT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT},
>> + [S390_CPU_FEATURE_GS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_GS},
>> + [S390_CPU_FEATURE_VXRS_EXT2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_EXT2},
>> + [S390_CPU_FEATURE_VXRS_PDE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE},
>> + [S390_CPU_FEATURE_SORT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SORT},
>> + [S390_CPU_FEATURE_DFLT] = {.type = TYPE_HWCAP, .num = HWCAP_NR_DFLT},
>> + [S390_CPU_FEATURE_VXRS_PDE2] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS_PDE2},
>> + [S390_CPU_FEATURE_NNPA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_NNPA},
>> + [S390_CPU_FEATURE_PCI_MIO] = {.type = TYPE_HWCAP, .num = HWCAP_NR_PCI_MIO},
>> + [S390_CPU_FEATURE_SIE] = {.type = TYPE_HWCAP, .num = HWCAP_NR_SIE},
>> +};
>
> I only realized now that you added all HWCAP bits here. It was
> intentional that I added only the two bits which are currently used
> for several reasons:
>
> - Keep the array as small as possible.
> - No need to keep this array in sync with HWCAPs, if new ones are added.
> - There is a for loop in print_cpu_modalias() which iterates over all
> MAX_CPU_FEATURES entries; this should be as fast as possible. Adding
> extra entries burns cycles for no added value.
The loop in print_cpu_modalias() was the reason why I added all
current HWCAPs. The current implementation runs through all HWCAPs
using cpu_have_feature() and I feared that reducing to just MSA and
VXRS has effects in the reporting of CPU-features to userspace.

I double checked the output of 'grep features /proc/cpuinfo' and it
stays the same, for 5.19-rc6, 5.19-rc6+this series, 5.19-rc6+this series
with just the two S390_CPU_FEATUREs. I might have misunderstood what
happens in that loop in print_cpu_modalias().

Now that I think again over this piece of code my additions do not make
sense at all for me.

I will reduce that array again to the two explicitly needed entries.


>
> Any future user which requires a not yet listed feature, can simply
> add it when needed.
>
>> +int cpu_have_feature(unsigned int num)
>> +{
>> + struct s390_cpu_feature *feature;
>> +
>> + feature = &s390_cpu_features[num];
>> + switch (feature->type) {
>> + case TYPE_HWCAP:
>> + return !!(elf_hwcap & (1UL << feature->num));
>
> Before somebody else mentions it, I could have done better. Nowadays
> this should be:
>
> return !!(elf_hwcap & BIT(feature->num));
I'll change it.

2022-07-13 09:46:58

by Claudio Imbrenda

[permalink] [raw]
Subject: Re: [PATCH 3/3] s390/uvdevice: autoload module based on CPU facility

On Wed, 13 Jul 2022 10:39:47 +0200
Steffen Eiden <[email protected]> wrote:

> On 7/12/22 18:49, Claudio Imbrenda wrote:
> > On Tue, 12 Jul 2022 12:52:20 +0200
> > Steffen Eiden <[email protected]> wrote:
> >
> >> Make sure the uvdevice driver will be automatically loaded when
> >> facility 158 is available.
> >>
> >> Signed-off-by: Steffen Eiden <[email protected]>

Reviewed-by: Claudio Imbrenda <[email protected]>

> >> -module_init(uvio_dev_init);
> >> +module_cpu_feature_match(S390_CPU_FEATURE_UV, uvio_dev_init);
> >
> > does this still prevent manual loading when the feature is not present?
> yes.
>
> Have a look at the macro definition at 'include/linux/cpufeature.h':
>
> Use module_cpu_feature_match(feature, module_init_function) to
>
> declare that
>
> [snip]
> b) the module must not be loaded if CPU feature 'feature' is not present
>
> (not even by manual insmod).

that is what I needed to see :)

>
> The test 'facility(158)' just moved to cpu_have_feature() in
> '/arch/s390/kernel/cpufeature.c'.
> >
> >> module_exit(uvio_dev_exit);
> >>
> >> MODULE_AUTHOR("IBM Corporation");
> >

2022-07-14 11:43:22

by Heiko Carstens

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

> > > +static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
> > > + [S390_CPU_FEATURE_ESAN3] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ESAN3},
> > > + [S390_CPU_FEATURE_ZARCH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ZARCH},
...
> > I only realized now that you added all HWCAP bits here. It was
> > intentional that I added only the two bits which are currently used
> > for several reasons:
> >
> > - Keep the array as small as possible.
> > - No need to keep this array in sync with HWCAPs, if new ones are added.
> > - There is a for loop in print_cpu_modalias() which iterates over all
> > MAX_CPU_FEATURES entries; this should be as fast as possible. Adding
> > extra entries burns cycles for no added value.
> The loop in print_cpu_modalias() was the reason why I added all
> current HWCAPs. The current implementation runs through all HWCAPs
> using cpu_have_feature() and I feared that reducing to just MSA and
> VXRS has effects in the reporting of CPU-features to userspace.
>
> I double checked the output of 'grep features /proc/cpuinfo' and it
> stays the same, for 5.19-rc6, 5.19-rc6+this series, 5.19-rc6+this series
> with just the two S390_CPU_FEATUREs. I might have misunderstood what happens
> in that loop in print_cpu_modalias().

It is used on cpu hotplug to generate a MODALIAS environment
variable. You can check that by running "udevadm monitor -p"
and then switching a cpu off/on.

This environment variable is then used by systemd/udev to load
feature matching modules via kmod.

2022-07-15 08:44:29

by Hendrik Brueckner

[permalink] [raw]
Subject: Re: [PATCH 1/3] s390/cpufeature: rework to allow more than only hwcap bits

On Thu, Jul 14, 2022 at 12:52:25PM +0200, Heiko Carstens wrote:
> > > > +static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
> > > > + [S390_CPU_FEATURE_ESAN3] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ESAN3},
> > > > + [S390_CPU_FEATURE_ZARCH] = {.type = TYPE_HWCAP, .num = HWCAP_NR_ZARCH},
> ...
> > > I only realized now that you added all HWCAP bits here. It was
> > > intentional that I added only the two bits which are currently used
> > > for several reasons:
> > >
> > > - Keep the array as small as possible.
> > > - No need to keep this array in sync with HWCAPs, if new ones are added.
> > > - There is a for loop in print_cpu_modalias() which iterates over all
> > > MAX_CPU_FEATURES entries; this should be as fast as possible. Adding
> > > extra entries burns cycles for no added value.
> > The loop in print_cpu_modalias() was the reason why I added all
> > current HWCAPs. The current implementation runs through all HWCAPs
> > using cpu_have_feature() and I feared that reducing to just MSA and
> > VXRS has effects in the reporting of CPU-features to userspace.
> >
> > I double checked the output of 'grep features /proc/cpuinfo' and it
> > stays the same, for 5.19-rc6, 5.19-rc6+this series, 5.19-rc6+this series
> > with just the two S390_CPU_FEATUREs. I might have misunderstood what happens
> > in that loop in print_cpu_modalias().
>
> It is used on cpu hotplug to generate a MODALIAS environment
> variable. You can check that by running "udevadm monitor -p"
> and then switching a cpu off/on.
>
> This environment variable is then used by systemd/udev to load
> feature matching modules via kmod.

See also some notes on the cpu feature in KRN1305 spec (introduced w/ VX
support).