Skip to contentSkip to conversation

RISC-V: archrandom support

PATCH In review Samuel Ortiz 5 participants 15 messages Jul 12, 2023 – Oct 12, 2023

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v4 cover RISC-V: archrandom support

This patchset adds support for the archrandom API to the RISC-V architecture.

The ratified crypto scalar extensions provide entropy bits via the seed CSR, as exposed by the Zkr extension.

The first patch of this patchset allows for detecting support of the Zbc and all scalar crypto extensions. The second patch documents the corresponding dt-bindings.

The third patch exposes the Zbc and scalar crypto extensions through the hwprobe syscall.

The last patch relies on the first ones to check for the Zkr support, and implements get_random_seed_longs by looping through a seed CSR read-write to return one long worth of entropy.

---
v4:

- Documented the USEED and SSEED requirements when Zkr is enabled

v3:

- Increased the CSR SEED retry loop max iterations to 100
- Documented the added extensions in the related dt-bindings file

v2:

- Fixed the ISA map setting for zkbx
- Alphanumerically sorted the ISA map setting
- Added my SOB on Hongren's patch
- Fixed patch #1 commit message
- Removed printk prefix from the archrandom implementation
- Fixed needed_seeds computation (and make it const)
- Replaced riscv_isa_extension_available() with riscv_has_extension_likely()
- Made the get_random_seed_longs implementation more readable

---

Hongren (Zenithal) Zheng (1):
RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Samuel Ortiz (3):
dt-bindings: riscv: Document the 1.0 scalar cryptography extensions
RISC-V: hwprobe: Expose Zbc and the scalar crypto extensions
RISC-V: Implement archrandom when Zkr is available

 .../devicetree/bindings/riscv/extensions.yaml | 87 +++++++++++++++++++
 Documentation/riscv/hwprobe.rst               | 35 ++++++++
 arch/riscv/include/asm/archrandom.h           | 70 +++++++++++++++
 arch/riscv/include/asm/csr.h                  |  9 ++
 arch/riscv/include/asm/hwcap.h                | 11 +++
 arch/riscv/include/uapi/asm/hwprobe.h         | 11 +++
 arch/riscv/kernel/cpu.c                       | 11 +++
 arch/riscv/kernel/cpufeature.c                | 30 +++++++
 arch/riscv/kernel/sys_riscv.c                 | 36 +++++---
 9 files changed, 286 insertions(+), 14 deletions(-)
 create mode 100644 arch/riscv/include/asm/archrandom.h

base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5

Signature · 1 line
2.41.0
#1 lore raw

PATCH v4 1/4 RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

---
 arch/riscv/include/asm/hwcap.h | 11 +++++++++++
 arch/riscv/kernel/cpu.c        | 11 +++++++++++
 arch/riscv/kernel/cpufeature.c | 30 ++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+)
arch/riscv/include/asm/hwcap.h +11 -0
index f041bfa7f6a0..b80ca6e77088 100644
@@ -53,6 +53,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC		43
+#define RISCV_ISA_EXT_ZBKB		44
+#define RISCV_ISA_EXT_ZBKC		45
+#define RISCV_ISA_EXT_ZBKX		46
+#define RISCV_ISA_EXT_ZKND		47
+#define RISCV_ISA_EXT_ZKNE		48
+#define RISCV_ISA_EXT_ZKNH		49
+#define RISCV_ISA_EXT_ZKR		50
+#define RISCV_ISA_EXT_ZKSED		51
+#define RISCV_ISA_EXT_ZKSH		52
+#define RISCV_ISA_EXT_ZKT		53
 
 #define RISCV_ISA_EXT_MAX		64
 #define RISCV_ISA_EXT_NAME_LEN_MAX	32
arch/riscv/kernel/cpu.c +11 -0
index a2fc952318e9..10524322a4c0 100644
@@ -215,7 +215,18 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
 	__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
 	__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
 	__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
+	__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
+	__RISCV_ISA_EXT_DATA(zbkb, RISCV_ISA_EXT_ZBKB),
+	__RISCV_ISA_EXT_DATA(zbkc, RISCV_ISA_EXT_ZBKC),
+	__RISCV_ISA_EXT_DATA(zbkx, RISCV_ISA_EXT_ZBKX),
 	__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
+	__RISCV_ISA_EXT_DATA(zknd, RISCV_ISA_EXT_ZKND),
+	__RISCV_ISA_EXT_DATA(zkne, RISCV_ISA_EXT_ZKNE),
+	__RISCV_ISA_EXT_DATA(zknh, RISCV_ISA_EXT_ZKNH),
+	__RISCV_ISA_EXT_DATA(zkr, RISCV_ISA_EXT_ZKR),
+	__RISCV_ISA_EXT_DATA(zksed, RISCV_ISA_EXT_ZKSED),
+	__RISCV_ISA_EXT_DATA(zksh, RISCV_ISA_EXT_ZKSH),
+	__RISCV_ISA_EXT_DATA(zkt, RISCV_ISA_EXT_ZKT),
 	__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
 	__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
arch/riscv/kernel/cpufeature.c +30 -0
index bdcf460ea53d..9a872a2007a5 100644
@@ -309,10 +309,40 @@ void __init riscv_fill_hwcap(void)
 				SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
 				SET_ISA_EXT_MAP("zba", RISCV_ISA_EXT_ZBA);
 				SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
+				SET_ISA_EXT_MAP("zbc", RISCV_ISA_EXT_ZBC);
+				SET_ISA_EXT_MAP("zbkb", RISCV_ISA_EXT_ZBKB);
+				SET_ISA_EXT_MAP("zbkc", RISCV_ISA_EXT_ZBKC);
+				SET_ISA_EXT_MAP("zbkx", RISCV_ISA_EXT_ZBKX);
 				SET_ISA_EXT_MAP("zbs", RISCV_ISA_EXT_ZBS);
 				SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
 				SET_ISA_EXT_MAP("zicboz", RISCV_ISA_EXT_ZICBOZ);
 				SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZBKB);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZBKC);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZBKX);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZKND);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZKNE);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZKNH);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZKR);
+				SET_ISA_EXT_MAP("zk", RISCV_ISA_EXT_ZKT);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZBKB);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZBKC);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZBKX);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZKND);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZKNE);
+				SET_ISA_EXT_MAP("zkn", RISCV_ISA_EXT_ZKNH);
+				SET_ISA_EXT_MAP("zknd", RISCV_ISA_EXT_ZKND);
+				SET_ISA_EXT_MAP("zkne", RISCV_ISA_EXT_ZKNE);
+				SET_ISA_EXT_MAP("zknh", RISCV_ISA_EXT_ZKNH);
+				SET_ISA_EXT_MAP("zks", RISCV_ISA_EXT_ZBKB);
+				SET_ISA_EXT_MAP("zks", RISCV_ISA_EXT_ZBKC);
+				SET_ISA_EXT_MAP("zks", RISCV_ISA_EXT_ZBKX);
+				SET_ISA_EXT_MAP("zks", RISCV_ISA_EXT_ZKSED);
+				SET_ISA_EXT_MAP("zks", RISCV_ISA_EXT_ZKSH);
+				SET_ISA_EXT_MAP("zksed", RISCV_ISA_EXT_ZKSED);
+				SET_ISA_EXT_MAP("zksh", RISCV_ISA_EXT_ZKSH);
+				SET_ISA_EXT_MAP("zkr", RISCV_ISA_EXT_ZKR);
+				SET_ISA_EXT_MAP("zkt", RISCV_ISA_EXT_ZKT);
 			}
 #undef SET_ISA_EXT_MAP
 		}
Signature · 1 line
2.41.0
#2 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Hey Samuel, Evan,

Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

(I took authorship since only the #defines & part of the commit message came from the original commit)

-- >8 --
From 2351c46fd1c9f6de312463875a4887f03d365b76 Mon Sep 17 00:00:00 2001
From: Conor Dooley <[email protected]>
Date: Wed, 12 Jul 2023 11:25:36 +0100
Subject: [PATCH] RISC-V: add detection of scalar crypto extensions

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT shold enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.
For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit searching for supersets of the extension in question, both while parsing the ISA string and the new dedicated extension properties.

---
 arch/riscv/include/asm/hwcap.h | 13 +++++
 arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
 2 files changed, 94 insertions(+), 14 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..46d54f31e162 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC		43
+#define RISCV_ISA_EXT_ZBKB		44
+#define RISCV_ISA_EXT_ZBKC		45
+#define RISCV_ISA_EXT_ZBKX		46
+#define RISCV_ISA_EXT_ZKND		47
+#define RISCV_ISA_EXT_ZKNE		48
+#define RISCV_ISA_EXT_ZKNH		49
+#define RISCV_ISA_EXT_ZKR		50
+#define RISCV_ISA_EXT_ZKSED		51
+#define RISCV_ISA_EXT_ZKSH		52
+#define RISCV_ISA_EXT_ZKT		53
 
 #define RISCV_ISA_EXT_MAX		64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
 	const unsigned int id;
 	const char *name;
 	const char *property;
+	const unsigned int superset_count;
+	const char **subset_of;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +81 -14

138 lines not on this page · raw message

Signature · 1 line
2.40.1

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

#3 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Quoted 29 lines · Conor Dooley

Hey Samuel, Evan,

Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Quoted 4 lines

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

I would rather use the "property" member, renaming it to "properties", but I didn't get the macro right in the bit of time I had this morning. I'll try to think of a cleaner way...

Thanks,
Conor.

Quoted 215 lines

(I took authorship since only the #defines & part of the commit message came from the original commit)

-- >8 --
From 2351c46fd1c9f6de312463875a4887f03d365b76 Mon Sep 17 00:00:00 2001
From: Conor Dooley <[email protected]>
Date: Wed, 12 Jul 2023 11:25:36 +0100
Subject: [PATCH] RISC-V: add detection of scalar crypto extensions

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT shold enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.
For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit searching for supersets of the extension in question, both while parsing the ISA string and the new dedicated extension properties.

---
 arch/riscv/include/asm/hwcap.h | 13 +++++
 arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
 2 files changed, 94 insertions(+), 14 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..46d54f31e162 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC		43
+#define RISCV_ISA_EXT_ZBKB		44
+#define RISCV_ISA_EXT_ZBKC		45
+#define RISCV_ISA_EXT_ZBKX		46
+#define RISCV_ISA_EXT_ZKND		47
+#define RISCV_ISA_EXT_ZKNE		48
+#define RISCV_ISA_EXT_ZKNH		49
+#define RISCV_ISA_EXT_ZKR		50
+#define RISCV_ISA_EXT_ZKSED		51
+#define RISCV_ISA_EXT_ZKSH		52
+#define RISCV_ISA_EXT_ZKT		53
 
 #define RISCV_ISA_EXT_MAX		64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
 	const unsigned int id;
 	const char *name;
 	const char *property;
+	const unsigned int superset_count;
+	const char **subset_of;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +81 -14
index 5945dfc5f806..e862958d5495 100644
@@ -103,8 +103,22 @@ static bool riscv_isa_extension_check(int id)
 	.name = #_name,				\
 	.property = #_name,			\
 	.id = _id,				\
+	.superset_count = 0,			\
+	.subset_of = NULL,			\
 }
 
+#define __RISCV_ISA_EXT_DATA_SUBSET(_name, _id, _subset_of) {	\
+	.name = #_name,						\
+	.property = #_name,					\
+	.id = _id,						\
+	.superset_count = ARRAY_SIZE(_subset_of),		\
+	.subset_of = _subset_of,				\
+}
+
+static const char * const riscv_subset_of_zbk[] = { "zk", "zkn", "zks" };
+static const char * const riscv_subset_of_zkn[] = { "zk", "zkn" };
+static const char * const riscv_subset_of_zk[]  = { "zk" };
+static const char * const riscv_subset_of_zks[] = { "zks" };
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -167,7 +181,18 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
 	__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
 	__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
+	__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkb, RISCV_ISA_EXT_ZBKB, riscv_subset_of_zbk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkc, RISCV_ISA_EXT_ZBKC, riscv_subset_of_zbk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkx, RISCV_ISA_EXT_ZBKX, riscv_subset_of_zbk),
 	__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
+	__RISCV_ISA_EXT_DATA_SUBSET(zknd, RISCV_ISA_EXT_ZKND, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkne, RISCV_ISA_EXT_ZKNE, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zknh, RISCV_ISA_EXT_ZKNH, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkr, RISCV_ISA_EXT_ZKR, riscv_subset_of_zk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zksed, RISCV_ISA_EXT_ZKSED, riscv_subset_of_zks),
+	__RISCV_ISA_EXT_DATA_SUBSET(zksh, RISCV_ISA_EXT_ZKSH, riscv_subset_of_zks),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkt, RISCV_ISA_EXT_ZKT, riscv_subset_of_zk),
 	__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
 	__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
@@ -179,6 +204,31 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 
 const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
 
+static inline int __init riscv_try_match_extension(const char *name, const unsigned int bit,
+						   const char *ext, const char *ext_end,
+						   struct riscv_isainfo *isainfo)
+{
+	if ((ext_end - ext == strlen(name)) && !strncasecmp(ext, name, strlen(name)) &&
+	    riscv_isa_extension_check(bit)) {
+		set_bit(bit, isainfo->isa);
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static inline void __init riscv_try_match_supersets(struct riscv_isa_ext_data ext_data,
+						    const char *ext, const char *ext_end,
+						    struct riscv_isainfo *isainfo)
+{
+	for (int i = 0; i < ext_data.superset_count; i++) {
+		const char *superset = ext_data.subset_of[i];
+		const int bit = ext_data.id;
+
+		riscv_try_match_extension(superset, bit, ext, ext_end, isainfo);
+	}
+}
+
 static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct riscv_isainfo *isainfo,
 					  unsigned long *isa2hwcap, const char *isa)
 {
@@ -310,16 +360,9 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 		if (*isa == '_')
 			++isa;
 
-#define SET_ISA_EXT_MAP(name, bit)						\
-		do {								\
-			if ((ext_end - ext == sizeof(name) - 1) &&		\
-			     !strncasecmp(ext, name, sizeof(name) - 1) &&	\
-			     riscv_isa_extension_check(bit))			\
-				set_bit(bit, isainfo->isa);			\
-		} while (false)							\
-
 		if (unlikely(ext_err))
 			continue;
+
 		if (!ext_long) {
 			int nr = tolower(*ext) - 'a';
 
@@ -327,12 +370,21 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 				*this_hwcap |= isa2hwcap[nr];
 				set_bit(nr, isainfo->isa);
 			}
-		} else {
+
 			for (int i = 0; i < riscv_isa_ext_count; i++)
-				SET_ISA_EXT_MAP(riscv_isa_ext[i].name,
-						riscv_isa_ext[i].id);
+				riscv_try_match_supersets(riscv_isa_ext[i], ext, ext_end, isainfo);
+		} else {
+			for (int i = 0; i < riscv_isa_ext_count; i++) {
+				const char *name = riscv_isa_ext[i].name;
+				const int bit = riscv_isa_ext[i].id;
+				int ret;
+
+				ret = riscv_try_match_extension(name, bit, ext, ext_end, isainfo);
+				if (ret && riscv_isa_ext[i].superset_count)
+					riscv_try_match_supersets(riscv_isa_ext[i], ext,
+								  ext_end, isainfo);
+			}
 		}
-#undef SET_ISA_EXT_MAP
 	}
 }
 
@@ -434,8 +486,23 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 			continue;
 
 		for (int i = 0; i < riscv_isa_ext_count; i++) {
-			if (of_property_match_string(cpu_node, "riscv,isa-extensions",
-						     riscv_isa_ext[i].property) < 0)
+			struct riscv_isa_ext_data ext = riscv_isa_ext[i];
+			int ret;
+
+			ret = of_property_match_string(cpu_node, "riscv,isa-extensions",
+						       ext.property);
+
+			if (ret < 0 && ext.superset_count) {
+				for (int j = 0; j < ext.superset_count; j++) {
+					ret = of_property_match_string(cpu_node,
+								       "riscv,isa-extensions",
+								       ext.subset_of[j]);
+					if (ret >= 0)
+						break;
+				}
+			}
+
+			if (ret < 0)
 				continue;
 
 			if (!riscv_isa_extension_check(riscv_isa_ext[i].id))
Signature · 1 line
2.40.1
#4 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Me again, spotted an issue after sending.

Quoted 89 lines · Conor Dooley
Quoted 27 lines · Conor Dooley
Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Quoted 4 lines

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

I would rather use the "property" member, renaming it to "properties", but I didn't get the macro right in the bit of time I had this morning. I'll try to think of a cleaner way...

Quoted 52 lines

(I took authorship since only the #defines & part of the commit message came from the original commit)

-- >8 --
From 2351c46fd1c9f6de312463875a4887f03d365b76 Mon Sep 17 00:00:00 2001
From: Conor Dooley <[email protected]>
Date: Wed, 12 Jul 2023 11:25:36 +0100
Subject: [PATCH] RISC-V: add detection of scalar crypto extensions

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT shold enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.
For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit searching for supersets of the extension in question, both while parsing the ISA string and the new dedicated extension properties.

---
 arch/riscv/include/asm/hwcap.h | 13 +++++
 arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
 2 files changed, 94 insertions(+), 14 deletions(-)
arch/riscv/include/asm/hwcap.h +11 -0
index b7b58258f6c7..46d54f31e162 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC		43
+#define RISCV_ISA_EXT_ZBKB		44
+#define RISCV_ISA_EXT_ZBKC		45
+#define RISCV_ISA_EXT_ZBKX		46
+#define RISCV_ISA_EXT_ZKND		47
+#define RISCV_ISA_EXT_ZKNE		48
+#define RISCV_ISA_EXT_ZKNH		49
+#define RISCV_ISA_EXT_ZKR		50
+#define RISCV_ISA_EXT_ZKSED		51
+#define RISCV_ISA_EXT_ZKSH		52
+#define RISCV_ISA_EXT_ZKT		53
 
Quoted 8 lines

arch/riscv/include/asm/hwcap.h struct riscv_isa_ext_data { · line 92

Quoted 8 lines
arch/riscv/include/asm/hwcap.h +2 -0
 #define RISCV_ISA_EXT_MAX		64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
 	const unsigned int id;
 	const char *name;
 	const char *property;
+	const unsigned int superset_count;
+	const char **subset_of;

I forgot to stage the addition of a const qualifier here, it should be const char * const *subset_of, otherwise it fails to build.

Cheers,
Conor.

Quoted 150 lines
Quoted 150 lines
arch/riscv/include/asm/hwcap.h +0 -0
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +81 -14
index 5945dfc5f806..e862958d5495 100644
@@ -103,8 +103,22 @@ static bool riscv_isa_extension_check(int id)
 	.name = #_name,				\
 	.property = #_name,			\
 	.id = _id,				\
+	.superset_count = 0,			\
+	.subset_of = NULL,			\
 }
 
+#define __RISCV_ISA_EXT_DATA_SUBSET(_name, _id, _subset_of) {	\
+	.name = #_name,						\
+	.property = #_name,					\
+	.id = _id,						\
+	.superset_count = ARRAY_SIZE(_subset_of),		\
+	.subset_of = _subset_of,				\
+}
+
+static const char * const riscv_subset_of_zbk[] = { "zk", "zkn", "zks" };
+static const char * const riscv_subset_of_zkn[] = { "zk", "zkn" };
+static const char * const riscv_subset_of_zk[]  = { "zk" };
+static const char * const riscv_subset_of_zks[] = { "zks" };
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -167,7 +181,18 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
 	__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
 	__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
+	__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkb, RISCV_ISA_EXT_ZBKB, riscv_subset_of_zbk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkc, RISCV_ISA_EXT_ZBKC, riscv_subset_of_zbk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zbkx, RISCV_ISA_EXT_ZBKX, riscv_subset_of_zbk),
 	__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
+	__RISCV_ISA_EXT_DATA_SUBSET(zknd, RISCV_ISA_EXT_ZKND, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkne, RISCV_ISA_EXT_ZKNE, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zknh, RISCV_ISA_EXT_ZKNH, riscv_subset_of_zkn),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkr, RISCV_ISA_EXT_ZKR, riscv_subset_of_zk),
+	__RISCV_ISA_EXT_DATA_SUBSET(zksed, RISCV_ISA_EXT_ZKSED, riscv_subset_of_zks),
+	__RISCV_ISA_EXT_DATA_SUBSET(zksh, RISCV_ISA_EXT_ZKSH, riscv_subset_of_zks),
+	__RISCV_ISA_EXT_DATA_SUBSET(zkt, RISCV_ISA_EXT_ZKT, riscv_subset_of_zk),
 	__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
 	__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
@@ -179,6 +204,31 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 
 const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
 
+static inline int __init riscv_try_match_extension(const char *name, const unsigned int bit,
+						   const char *ext, const char *ext_end,
+						   struct riscv_isainfo *isainfo)
+{
+	if ((ext_end - ext == strlen(name)) && !strncasecmp(ext, name, strlen(name)) &&
+	    riscv_isa_extension_check(bit)) {
+		set_bit(bit, isainfo->isa);
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static inline void __init riscv_try_match_supersets(struct riscv_isa_ext_data ext_data,
+						    const char *ext, const char *ext_end,
+						    struct riscv_isainfo *isainfo)
+{
+	for (int i = 0; i < ext_data.superset_count; i++) {
+		const char *superset = ext_data.subset_of[i];
+		const int bit = ext_data.id;
+
+		riscv_try_match_extension(superset, bit, ext, ext_end, isainfo);
+	}
+}
+
 static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct riscv_isainfo *isainfo,
 					  unsigned long *isa2hwcap, const char *isa)
 {
@@ -310,16 +360,9 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 		if (*isa == '_')
 			++isa;
 
-#define SET_ISA_EXT_MAP(name, bit)						\
-		do {								\
-			if ((ext_end - ext == sizeof(name) - 1) &&		\
-			     !strncasecmp(ext, name, sizeof(name) - 1) &&	\
-			     riscv_isa_extension_check(bit))			\
-				set_bit(bit, isainfo->isa);			\
-		} while (false)							\
-
 		if (unlikely(ext_err))
 			continue;
+
 		if (!ext_long) {
 			int nr = tolower(*ext) - 'a';
 
@@ -327,12 +370,21 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 				*this_hwcap |= isa2hwcap[nr];
 				set_bit(nr, isainfo->isa);
 			}
-		} else {
+
 			for (int i = 0; i < riscv_isa_ext_count; i++)
-				SET_ISA_EXT_MAP(riscv_isa_ext[i].name,
-						riscv_isa_ext[i].id);
+				riscv_try_match_supersets(riscv_isa_ext[i], ext, ext_end, isainfo);
+		} else {
+			for (int i = 0; i < riscv_isa_ext_count; i++) {
+				const char *name = riscv_isa_ext[i].name;
+				const int bit = riscv_isa_ext[i].id;
+				int ret;
+
+				ret = riscv_try_match_extension(name, bit, ext, ext_end, isainfo);
+				if (ret && riscv_isa_ext[i].superset_count)
+					riscv_try_match_supersets(riscv_isa_ext[i], ext,
+								  ext_end, isainfo);
+			}
 		}
-#undef SET_ISA_EXT_MAP
 	}
 }
 
@@ -434,8 +486,23 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 			continue;
 
 		for (int i = 0; i < riscv_isa_ext_count; i++) {
-			if (of_property_match_string(cpu_node, "riscv,isa-extensions",
-						     riscv_isa_ext[i].property) < 0)
+			struct riscv_isa_ext_data ext = riscv_isa_ext[i];
+			int ret;
+
+			ret = of_property_match_string(cpu_node, "riscv,isa-extensions",
+						       ext.property);
+
+			if (ret < 0 && ext.superset_count) {
+				for (int j = 0; j < ext.superset_count; j++) {
+					ret = of_property_match_string(cpu_node,
+								       "riscv,isa-extensions",
+								       ext.subset_of[j]);
+					if (ret >= 0)
+						break;
+				}
+			}
+
+			if (ret < 0)
 				continue;
 
Quoted 7 lines
Quoted 5 lines
arch/riscv/kernel/cpufeature.c +0 -0
 			if (!riscv_isa_extension_check(riscv_isa_ext[i].id))
Signature · 1 line
2.40.1

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

#5 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

In reply to Conor Dooley
Quoted 30 lines · Conor Dooley

Hey Samuel, Evan,

Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Quoted 5 lines

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

This looks alright to me. At the risk of getting into bikeshedding territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh}, rather than zbkb being a part of {zks, zkn, zk}, though both are of course correct. Here's an untested version of the other way. You can decide if you like it better or worse than what you've got, and I'm fine either way. Sorry gmail mangles it, if you want the patch for real I can get it to you:

From e201c34c05cd82812b5b3f47ccdd7d5909259f07 Mon Sep 17 00:00:00 2001
From: Evan Green <[email protected]>
Date: Wed, 12 Jul 2023 10:36:15 -0700
Subject: [PATCH] WIP: RISC-V: Allow support for bundled extensions, and add Zk*

---
 arch/riscv/include/asm/hwcap.h | 13 ++++++
 arch/riscv/kernel/cpufeature.c | 82 +++++++++++++++++++++++++++++-----
 2 files changed, 84 insertions(+), 11 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..7d2d10b42cf3 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR            40
 #define RISCV_ISA_EXT_ZIFENCEI         41
 #define RISCV_ISA_EXT_ZIHPM            42
+#define RISCV_ISA_EXT_ZBC              43
+#define RISCV_ISA_EXT_ZBKB             44
+#define RISCV_ISA_EXT_ZBKC             45
+#define RISCV_ISA_EXT_ZBKX             46
+#define RISCV_ISA_EXT_ZKND             47
+#define RISCV_ISA_EXT_ZKNE             48
+#define RISCV_ISA_EXT_ZKNH             49
+#define RISCV_ISA_EXT_ZKR              50
+#define RISCV_ISA_EXT_ZKSED            51
+#define RISCV_ISA_EXT_ZKSH             52
+#define RISCV_ISA_EXT_ZKT              53
 
 #define RISCV_ISA_EXT_MAX              64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
        const unsigned int id;
        const char *name;
        const char *property;
+       const unsigned int *bundled_exts;
+       const unsigned int bundle_size;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +47 -0

63 lines not on this page · raw message

char *name,
+ const char *name_end, struct riscv_isainfo *isainfo)
+{
+ if ((name_end - name == strlen(ext->name)) &&
+ !strncasecmp(name, ext->name, name_end - name)) {
+
+ /*

+                * If this is a bundle, enable all the ISA extensions that
+                * comprise the bundle.
+                */

+ if (ext->bundle_size) {
+ unsigned int i;
+ for (i = 0; i < ext->bundle_size; i++) {
+ if
(riscv_isa_extension_check(ext->bundled_exts[i]))
+ set_bit(ext->bundled_exts[i],
isainfo->isa);
+ }
+
+
+ } else if (riscv_isa_extension_check(ext->id)) {
+ set_bit(ext->id, isainfo->isa);
+ }
+ }
+}
+
static void __init riscv_parse_isa_string(unsigned long *this_hwcap,
struct riscv_isainfo *isainfo,
unsigned long *isa2hwcap,
const char *isa)
{
@@ -310,14 +380,6 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc

                if (*isa == '_')
                        ++isa;

-#define SET_ISA_EXT_MAP(name, bit)

         \
-               do {
         \
-                       if ((ext_end - ext == sizeof(name) - 1) &&
         \
-                            !strncasecmp(ext, name, sizeof(name) - 1)
&&       \
-                            riscv_isa_extension_check(bit))
         \
-                               set_bit(bit, isainfo->isa);
         \
-               } while (false)
         \
-
                if (unlikely(ext_err))
                        continue;
                if (!ext_long) {
@@ -329,10 +391,8 @@ static void __init
riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
                        }
                } else {
                        for (int i = 0; i < riscv_isa_ext_count; i++)
-                               SET_ISA_EXT_MAP(riscv_isa_ext[i].name,
-                                               riscv_isa_ext[i].id);
+                               match_isa_ext(&riscv_isa_ext[i], ext,
ext_end, isainfo);
                }
-#undef SET_ISA_EXT_MAP
        }

}

#6 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Quoted 1 line · Evan Green

This looks alright to me. At the risk of getting into bikeshedding

I very much do not think that that is bikeshedding FWIW.

Quoted 6 lines

territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh}, rather than zbkb being a part of {zks, zkn, zk}, though both are of course correct. Here's an untested version of the other way. You can decide if you like it better or worse than what you've got, and I'm fine either way.

I'm happy to do it this way too, just wanna see how it interacts with the new property stuff. I actually found it confusing to implement the arrays, it just seemed easier to integrate with the new property stuff this way.

Quoted 2 lines

Sorry
gmail mangles it, if you want the patch for real I can get it to you:

Please, reading the line-wrapped mangling hurts my head unfortunately. Tree or attachment WFM :)

Thanks,
Conor.

#7 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

In reply to Evan Green
Quoted 37 lines · Evan Green
Quoted 30 lines · Conor Dooley

Hey Samuel, Evan,

Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Quoted 5 lines

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

Quoted 4 lines

This looks alright to me. At the risk of getting into bikeshedding territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh},

This is also the way I think of it, so, FWIW, I prefer the approach below, where bundles are expanded.

Thanks,
drew

Quoted 183 lines

rather than zbkb being a part
of {zks, zkn, zk}, though both are of course correct. Here's an untested version of the other way. You can decide if you like it better or worse than what you've got, and I'm fine either way. Sorry gmail mangles it, if you want the patch for real I can get it to you:

From e201c34c05cd82812b5b3f47ccdd7d5909259f07 Mon Sep 17 00:00:00 2001
From: Evan Green <[email protected]>
Date: Wed, 12 Jul 2023 10:36:15 -0700
Subject: [PATCH] WIP: RISC-V: Allow support for bundled extensions, and add Zk*

---
 arch/riscv/include/asm/hwcap.h | 13 ++++++
 arch/riscv/kernel/cpufeature.c | 82 +++++++++++++++++++++++++++++-----
 2 files changed, 84 insertions(+), 11 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..7d2d10b42cf3 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR            40
 #define RISCV_ISA_EXT_ZIFENCEI         41
 #define RISCV_ISA_EXT_ZIHPM            42
+#define RISCV_ISA_EXT_ZBC              43
+#define RISCV_ISA_EXT_ZBKB             44
+#define RISCV_ISA_EXT_ZBKC             45
+#define RISCV_ISA_EXT_ZBKX             46
+#define RISCV_ISA_EXT_ZKND             47
+#define RISCV_ISA_EXT_ZKNE             48
+#define RISCV_ISA_EXT_ZKNH             49
+#define RISCV_ISA_EXT_ZKR              50
+#define RISCV_ISA_EXT_ZKSED            51
+#define RISCV_ISA_EXT_ZKSH             52
+#define RISCV_ISA_EXT_ZKT              53
 
 #define RISCV_ISA_EXT_MAX              64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
        const unsigned int id;
        const char *name;
        const char *property;
+       const unsigned int *bundled_exts;
+       const unsigned int bundle_size;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +70 -0
index 5945dfc5f806..2a1f958c1777 100644
@@ -105,6 +105,39 @@ static bool riscv_isa_extension_check(int id)
        .id = _id,                              \
 }
 
+#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) { \
+       .name = #_name,                         \
+       .property = #_name,                     \
+       .bundled_exts = _bundled_exts,          \
+       .bundle_size = ARRAY_SIZE(_bundled_exts)        \
+}
+
+static const unsigned int riscv_zk_bundled_exts[] = {
+       RISCV_ISA_EXT_ZBKB,
+       RISCV_ISA_EXT_ZBKC,
+       RISCV_ISA_EXT_ZBKX,
+       RISCV_ISA_EXT_ZKND,
+       RISCV_ISA_EXT_ZKNE,
+       RISCV_ISA_EXT_ZKR,
+       RISCV_ISA_EXT_ZKT,
+};
+
+static const unsigned int riscv_zkn_bundled_exts[] = {
+       RISCV_ISA_EXT_ZBKB,
+       RISCV_ISA_EXT_ZBKC,
+       RISCV_ISA_EXT_ZBKX,
+       RISCV_ISA_EXT_ZKND,
+       RISCV_ISA_EXT_ZKNE,
+       RISCV_ISA_EXT_ZKNH,
+};
+
+static const unsigned int riscv_zks_bundled_exts[] = {
+       RISCV_ISA_EXT_ZBKB,
+       RISCV_ISA_EXT_ZBKC,
+       RISCV_ISA_EXT_ZKSED,
+       RISCV_ISA_EXT_ZKSH
+};
+
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -167,7 +200,20 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
        __RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
        __RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
        __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
+       __RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
+       __RISCV_ISA_EXT_DATA(zbkb, RISCV_ISA_EXT_ZBKB),
+       __RISCV_ISA_EXT_DATA(zbkc, RISCV_ISA_EXT_ZBKC),
+       __RISCV_ISA_EXT_DATA(zbkx, RISCV_ISA_EXT_ZBKX),
        __RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
+       __RISCV_ISA_EXT_BUNDLE(zk, riscv_zk_bundled_exts),
+       __RISCV_ISA_EXT_BUNDLE(zkn, riscv_zkn_bundled_exts),
+       __RISCV_ISA_EXT_DATA(zknd, RISCV_ISA_EXT_ZKND),
+       __RISCV_ISA_EXT_DATA(zkne, RISCV_ISA_EXT_ZKNE),
+       __RISCV_ISA_EXT_DATA(zknh, RISCV_ISA_EXT_ZKNH),
+       __RISCV_ISA_EXT_DATA(zkr, RISCV_ISA_EXT_ZKR),
+       __RISCV_ISA_EXT_BUNDLE(zks, riscv_zks_bundled_exts),
+       __RISCV_ISA_EXT_DATA(zksed, RISCV_ISA_EXT_ZKSED),
+       __RISCV_ISA_EXT_DATA(zksh, RISCV_ISA_EXT_ZKSH),
        __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
        __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
        __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
@@ -179,6 +225,30 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 
 const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
 
+static void match_isa_ext(const struct riscv_isa_ext_data *ext, const
 char *name,
+                         const char *name_end, struct riscv_isainfo *isainfo)
+{
+       if ((name_end - name == strlen(ext->name)) &&
+            !strncasecmp(name, ext->name, name_end - name)) {
+
+               /*
+                * If this is a bundle, enable all the ISA extensions that
+                * comprise the bundle.
+                */
+               if (ext->bundle_size) {
+                       unsigned int i;
+                       for (i = 0; i < ext->bundle_size; i++) {
+                               if
 (riscv_isa_extension_check(ext->bundled_exts[i]))
+                                       set_bit(ext->bundled_exts[i],
 isainfo->isa);
+                       }
+
+
+               } else if (riscv_isa_extension_check(ext->id)) {
+                       set_bit(ext->id, isainfo->isa);
+               }
+       }
+}
+

static void __init riscv_parse_isa_string(unsigned long *this_hwcap,
struct riscv_isainfo *isainfo,
unsigned long *isa2hwcap,
const char *isa)
{

arch/riscv/kernel/cpufeature.c +0 -0
@@ -310,14 +380,6 @@ static void __init

riscv_parse_isa_string(unsigned long *this_hwcap, struct risc

                if (*isa == '_')
                        ++isa;
arch/riscv/kernel/cpufeature.c +0 -4
-#define SET_ISA_EXT_MAP(name, bit)
         \
-               do {
         \
-                       if ((ext_end - ext == sizeof(name) - 1) &&
         \
-                            !strncasecmp(ext, name, sizeof(name) - 1)

&& \

arch/riscv/kernel/cpufeature.c +0 -4
-                            riscv_isa_extension_check(bit))
         \
-                               set_bit(bit, isainfo->isa);
         \
-               } while (false)
         \
-
                if (unlikely(ext_err))
                        continue;
                if (!ext_long) {
@@ -329,10 +391,8 @@ static void __init

riscv_parse_isa_string(unsigned long *this_hwcap, struct risc

                        }
                } else {
                        for (int i = 0; i < riscv_isa_ext_count; i++)
arch/riscv/kernel/cpufeature.c +1 -2
-                               SET_ISA_EXT_MAP(riscv_isa_ext[i].name,
-                                               riscv_isa_ext[i].id);
+                               match_isa_ext(&riscv_isa_ext[i], ext,
ext_end, isainfo);
                }
-#undef SET_ISA_EXT_MAP
        }
Quoted 1 line

}

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

#8 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Quoted 35 lines · Andrew Jones
Quoted 34 lines · Evan Green
Quoted 32 lines · Conor Dooley
Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

Quoted 7 lines
Quoted 4 lines

This looks alright to me. At the risk of getting into bikeshedding territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh},

This is also the way I think of it, so, FWIW, I prefer the approach below, where bundles are expanded.

I took the patch Evan sent me off-list & have spun it into a "real" patch. I did some minor changes (c99 loop, __init marking) to match what the code was already doing and expanded it to work for the new property stuff.
I'm not sure that match_isa_ext() needs to be a function, given the single user - it might be better refactored to drop the outer if & return whether a match was found.
If done that would allow sharing the same function between isa string and dedicated property parsing. I left it intact for now. Might also be worth adding kerneldoc for that struct.

-- >8 --
From 8300b98e487e57d192bc9581c6a3639c40c52623 Mon Sep 17 00:00:00 2001
From: Evan Green <[email protected]>
Date: Wed, 12 Jul 2023 10:36:15 -0700
Subject: [PATCH] RISC-V: Add support Scalar Crypto using "bundled extensions"

The Scalar Crypto specification defines Zk as a shorthand for the Zkn, Zkr and Zkt extensions. The same follows for both Zkn, Zks and Zbk, which are all shorthands for various other extensions. The detailed breakdown can be found in their dt-binding entries.

Since Zkn also implies the Zbkb, Zbkc and Zbkx extensions, simply passing "zk" through a DT should enable all of Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit setting the relevant bits for "bundled" extensions, both while parsing the ISA string and the new dedicated extension properties

---
There's basically none of the original patch left, so I have dropped the co-developed-bys and signed-off-bys from before. It does need one from you now though Evan!

---
 arch/riscv/include/asm/hwcap.h | 13 +++++
 arch/riscv/kernel/cpufeature.c | 94 ++++++++++++++++++++++++++++------
 2 files changed, 92 insertions(+), 15 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..f74308633e45 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC              43
+#define RISCV_ISA_EXT_ZBKB             44
+#define RISCV_ISA_EXT_ZBKC             45
+#define RISCV_ISA_EXT_ZBKX             46
+#define RISCV_ISA_EXT_ZKND             47
+#define RISCV_ISA_EXT_ZKNE             48
+#define RISCV_ISA_EXT_ZKNH             49
+#define RISCV_ISA_EXT_ZKR              50
+#define RISCV_ISA_EXT_ZKSED            51
+#define RISCV_ISA_EXT_ZKSH             52
+#define RISCV_ISA_EXT_ZKT              53
 
 #define RISCV_ISA_EXT_MAX		64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
 	const unsigned int id;
 	const char *name;
 	const char *property;
+	const unsigned int *bundle_ids;
+	const unsigned int bundle_size;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +79 -15

140 lines not on this page · raw message

Signature · 1 line
2.40.1
#9 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Quoted 131 lines · Conor Dooley
Quoted 35 lines · Andrew Jones
Quoted 34 lines · Evan Green
Quoted 32 lines · Conor Dooley
Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

Quoted 7 lines
Quoted 4 lines

This looks alright to me. At the risk of getting into bikeshedding territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh},

This is also the way I think of it, so, FWIW, I prefer the approach below, where bundles are expanded.

I took the patch Evan sent me off-list & have spun it into a "real" patch. I did some minor changes (c99 loop, __init marking) to match what the code was already doing and expanded it to work for the new property stuff.
I'm not sure that match_isa_ext() needs to be a function, given the single user - it might be better refactored to drop the outer if & return whether a match was found.
If done that would allow sharing the same function between isa string and dedicated property parsing. I left it intact for now. Might also be worth adding kerneldoc for that struct.

-- >8 --
From 8300b98e487e57d192bc9581c6a3639c40c52623 Mon Sep 17 00:00:00 2001
From: Evan Green <[email protected]>
Date: Wed, 12 Jul 2023 10:36:15 -0700
Subject: [PATCH] RISC-V: Add support Scalar Crypto using "bundled extensions"

The Scalar Crypto specification defines Zk as a shorthand for the Zkn, Zkr and Zkt extensions. The same follows for both Zkn, Zks and Zbk, which are all shorthands for various other extensions. The detailed breakdown can be found in their dt-binding entries.

Since Zkn also implies the Zbkb, Zbkc and Zbkx extensions, simply passing "zk" through a DT should enable all of Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit setting the relevant bits for "bundled" extensions, both while parsing the ISA string and the new dedicated extension properties

---
There's basically none of the original patch left, so I have dropped the co-developed-bys and signed-off-bys from before. It does need one from you now though Evan!

---
 arch/riscv/include/asm/hwcap.h | 13 +++++
 arch/riscv/kernel/cpufeature.c | 94 ++++++++++++++++++++++++++++------
 2 files changed, 92 insertions(+), 15 deletions(-)
arch/riscv/include/asm/hwcap.h +13 -0
index b7b58258f6c7..f74308633e45 100644
@@ -58,6 +58,17 @@
 #define RISCV_ISA_EXT_ZICSR		40
 #define RISCV_ISA_EXT_ZIFENCEI		41
 #define RISCV_ISA_EXT_ZIHPM		42
+#define RISCV_ISA_EXT_ZBC              43
+#define RISCV_ISA_EXT_ZBKB             44
+#define RISCV_ISA_EXT_ZBKC             45
+#define RISCV_ISA_EXT_ZBKX             46
+#define RISCV_ISA_EXT_ZKND             47
+#define RISCV_ISA_EXT_ZKNE             48
+#define RISCV_ISA_EXT_ZKNH             49
+#define RISCV_ISA_EXT_ZKR              50
+#define RISCV_ISA_EXT_ZKSED            51
+#define RISCV_ISA_EXT_ZKSH             52
+#define RISCV_ISA_EXT_ZKT              53
 
 #define RISCV_ISA_EXT_MAX		64
 
@@ -77,6 +88,8 @@ struct riscv_isa_ext_data {
 	const unsigned int id;
 	const char *name;
 	const char *property;
+	const unsigned int *bundle_ids;
+	const unsigned int bundle_size;
 };
 
 extern const struct riscv_isa_ext_data riscv_isa_ext[];
arch/riscv/kernel/cpufeature.c +5 -0
index ccbe27b3060b..d999d73554f0 100644
@@ -105,6 +105,39 @@ static bool riscv_isa_extension_check(int id)
 	.id = _id,				\
 }
 
+#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) {	\
+	.name = #_name,					\
+	.property = #_name,				\
+	.bundle_ids = _bundled_exts,			\
+	.bundle_size = ARRAY_SIZE(_bundled_exts)	\

arch/riscv/kernel/cpufeature.c static bool riscv_isa_extension_check(int id) · line 122

Quoted 10 lines
arch/riscv/kernel/cpufeature.c +10 -0
+}
+
+static const unsigned int riscv_zk_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZBKX,
+	RISCV_ISA_EXT_ZKND,
+	RISCV_ISA_EXT_ZKNE,
+	RISCV_ISA_EXT_ZKR,
+	RISCV_ISA_EXT_ZKT,

I think RISCV_ISA_EXT_ZKNH also belongs in this bundle, since the spec says zk is the zkn bundle plus zkr and zkt.

Quoted 6 lines
arch/riscv/kernel/cpufeature.c +6 -0
+};
+
+static const unsigned int riscv_zkn_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZBKX,

arch/riscv/kernel/cpufeature.c static bool riscv_isa_extension_check(int id) · line 138

Quoted 10 lines
arch/riscv/kernel/cpufeature.c +10 -0
+	RISCV_ISA_EXT_ZKND,
+	RISCV_ISA_EXT_ZKNE,
+	RISCV_ISA_EXT_ZKNH,
+};
+
+static const unsigned int riscv_zks_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZKSED,
+	RISCV_ISA_EXT_ZKSH

And, per the spec, this one appears to be missing RISCV_ISA_EXT_ZBKX.

I found [1] which calls these shorthands "group names", so maybe we should use the term "group" instead of "bundle"? I'm tempted to try to directly code that graphic in [1] with something like...

#define Zks_group1 \
	RISCV_ISA_EXT_ZKSED, \
	RISCV_ISA_EXT_ZKSH
#define Zks_group2 \
	RISCV_ISA_EXT_ZBKB, \
	RISCV_ISA_EXT_ZBKC, \
	RISCV_ISA_EXT_ZBKX
#define Zks_group \
	Zks_group1, \
	Zks_group2
#define Zkn_group1 \
	RISCV_ISA_EXT_ZKND, \
	RISCV_ISA_EXT_ZKNE, \
	RISCV_ISA_EXT_ZKNH

#define Zkn_group2 \
Zks_group2

#define Zkn_group \
	Zkn_group1, \
	Zkn_group2

static const unsigned int riscv_zks_group[] = {
Zks_group,
};

static const unsigned int riscv_zkn_group[] = {
Zkn_group,
};

static const unsigned int riscv_zk_group[] = {
Zks_group,
Zkn_group,
RISCV_ISA_EXT_ZKR,
RISCV_ISA_EXT_ZKT,
};

...but now that I have, I'm not sure I like the looks of it...

[1] https://wiki.riscv.org/display/HOME/Scalar+Cryptography+Instruction+Set+Extension+Group+Names+Diagram

Thanks,
drew

Quoted 115 lines
arch/riscv/kernel/cpufeature.c +48 -15
+};
+
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -167,7 +200,20 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
 	__RISCV_ISA_EXT_DATA(zba, RISCV_ISA_EXT_ZBA),
 	__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
+	__RISCV_ISA_EXT_DATA(zbc, RISCV_ISA_EXT_ZBC),
+	__RISCV_ISA_EXT_DATA(zbkb, RISCV_ISA_EXT_ZBKB),
+	__RISCV_ISA_EXT_DATA(zbkc, RISCV_ISA_EXT_ZBKC),
+	__RISCV_ISA_EXT_DATA(zbkx, RISCV_ISA_EXT_ZBKX),
 	__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
+	__RISCV_ISA_EXT_BUNDLE(zk, riscv_zk_bundled_exts),
+	__RISCV_ISA_EXT_BUNDLE(zkn, riscv_zkn_bundled_exts),
+	__RISCV_ISA_EXT_DATA(zknd, RISCV_ISA_EXT_ZKND),
+	__RISCV_ISA_EXT_DATA(zkne, RISCV_ISA_EXT_ZKNE),
+	__RISCV_ISA_EXT_DATA(zknh, RISCV_ISA_EXT_ZKNH),
+	__RISCV_ISA_EXT_DATA(zkr, RISCV_ISA_EXT_ZKR),
+	__RISCV_ISA_EXT_BUNDLE(zks, riscv_zks_bundled_exts),
+	__RISCV_ISA_EXT_DATA(zksed, RISCV_ISA_EXT_ZKSED),
+	__RISCV_ISA_EXT_DATA(zksh, RISCV_ISA_EXT_ZKSH),
 	__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
 	__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
@@ -179,6 +225,26 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 
 const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
 
+static void inline __init match_isa_ext(const struct riscv_isa_ext_data *ext, const char *name,
+					const char *name_end, struct riscv_isainfo *isainfo)
+{
+	if ((name_end - name == strlen(ext->name)) &&
+	     !strncasecmp(name, ext->name, name_end - name)) {
+		/*
+		 * If this is a bundle, enable all the ISA extensions that
+		 * comprise the bundle.
+		 */
+		if (ext->bundle_size) {
+			for (int i = 0; i < ext->bundle_size; i++) {
+				if (riscv_isa_extension_check(ext->bundle_ids[i]))
+					set_bit(ext->bundle_ids[i], isainfo->isa);
+			}
+		} else if (riscv_isa_extension_check(ext->id)) {
+			set_bit(ext->id, isainfo->isa);
+		}
+	}
+}
+
 static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct riscv_isainfo *isainfo,
 					  unsigned long *isa2hwcap, const char *isa)
 {
@@ -310,14 +376,6 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 		if (*isa == '_')
 			++isa;
 
-#define SET_ISA_EXT_MAP(name, bit)						\
-		do {								\
-			if ((ext_end - ext == strlen(name)) &&			\
-			     !strncasecmp(ext, name, strlen(name)) &&		\
-			     riscv_isa_extension_check(bit))			\
-				set_bit(bit, isainfo->isa);			\
-		} while (false)							\
-
 		if (unlikely(ext_err))
 			continue;
 		if (!ext_long) {
@@ -329,10 +387,8 @@ static void __init riscv_parse_isa_string(unsigned long *this_hwcap, struct risc
 			}
 		} else {
 			for (int i = 0; i < riscv_isa_ext_count; i++)
-				SET_ISA_EXT_MAP(riscv_isa_ext[i].name,
-						riscv_isa_ext[i].id);
+				match_isa_ext(&riscv_isa_ext[i], ext, ext_end, isainfo);
 		}
-#undef SET_ISA_EXT_MAP
 	}
 }
 
@@ -436,18 +492,26 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 		}
 
 		for (int i = 0; i < riscv_isa_ext_count; i++) {
+			const struct riscv_isa_ext_data ext = riscv_isa_ext[i];
+
 			if (of_property_match_string(cpu_node, "riscv,isa-extensions",
-						     riscv_isa_ext[i].property) < 0)
+						     ext.property) < 0)
 				continue;
 
-			if (!riscv_isa_extension_check(riscv_isa_ext[i].id))
+			if (ext.bundle_size) {
+				for (int j = 0; j < ext.bundle_size; j++) {
+					if (riscv_isa_extension_check(ext.bundle_ids[i]))
+						set_bit(ext.bundle_ids[j], this_isa);
+				}
+			} else if (riscv_isa_extension_check(ext.id)) {
+				set_bit(ext.id, this_isa);
+			} else {
 				continue;
+			}
 
 			/* Only single letter extensions get set in hwcap */
 			if (strnlen(riscv_isa_ext[i].name, 2) == 1)
 				this_hwcap |= isa2hwcap[riscv_isa_ext[i].id];
-
-			set_bit(riscv_isa_ext[i].id, this_isa);
 		}
 
 		of_node_put(cpu_node);
Signature · 1 line
2.40.1

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

#10 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

Quoted 31 lines · Andrew Jones
Quoted 5 lines · Conor Dooley
arch/riscv/kernel/cpufeature.c +5 -0
+#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) {	\
+	.name = #_name,					\
+	.property = #_name,				\
+	.bundle_ids = _bundled_exts,			\
+	.bundle_size = ARRAY_SIZE(_bundled_exts)	\

arch/riscv/kernel/cpufeature.c static bool riscv_isa_extension_check(int id) · line 122

Quoted 10 lines
arch/riscv/kernel/cpufeature.c +10 -0
+}
+
+static const unsigned int riscv_zk_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZBKX,
+	RISCV_ISA_EXT_ZKND,
+	RISCV_ISA_EXT_ZKNE,
+	RISCV_ISA_EXT_ZKR,
+	RISCV_ISA_EXT_ZKT,

I think RISCV_ISA_EXT_ZKNH also belongs in this bundle, since the spec says zk is the zkn bundle plus zkr and zkt.

Quoted 10 lines
arch/riscv/kernel/cpufeature.c +10 -0
+};
+
+static const unsigned int riscv_zkn_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZBKX,
+	RISCV_ISA_EXT_ZKND,
+	RISCV_ISA_EXT_ZKNE,
+	RISCV_ISA_EXT_ZKNH,
+};
Quoted 8 lines

arch/riscv/kernel/cpufeature.c static bool riscv_isa_extension_check(int id) · line 138

Quoted 6 lines
arch/riscv/kernel/cpufeature.c +6 -0
+
+static const unsigned int riscv_zks_bundled_exts[] = {
+	RISCV_ISA_EXT_ZBKB,
+	RISCV_ISA_EXT_ZBKC,
+	RISCV_ISA_EXT_ZKSED,
+	RISCV_ISA_EXT_ZKSH

And, per the spec, this one appears to be missing RISCV_ISA_EXT_ZBKX.

Yeah, these do look wrong. I should've cross-checked it.

Quoted 2 lines

I found [1] which calls these shorthands "group names", so maybe we should use the term "group" instead of "bundle"?

WFM at least.

Quoted 36 lines

I'm tempted to try to directly
code that graphic in [1] with something like...

#define Zks_group1 \
	RISCV_ISA_EXT_ZKSED, \
	RISCV_ISA_EXT_ZKSH
#define Zks_group2 \
	RISCV_ISA_EXT_ZBKB, \
	RISCV_ISA_EXT_ZBKC, \
	RISCV_ISA_EXT_ZBKX
#define Zks_group \
	Zks_group1, \
	Zks_group2
#define Zkn_group1 \
	RISCV_ISA_EXT_ZKND, \
	RISCV_ISA_EXT_ZKNE, \
	RISCV_ISA_EXT_ZKNH

#define Zkn_group2 \
Zks_group2

#define Zkn_group \
	Zkn_group1, \
	Zkn_group2

static const unsigned int riscv_zks_group[] = {
Zks_group,
};

static const unsigned int riscv_zkn_group[] = {
Zkn_group,
};

Quoted 8 lines

static const unsigned int riscv_zk_group[] = {
Zks_group,
Zkn_group,
RISCV_ISA_EXT_ZKR,
RISCV_ISA_EXT_ZKT,
};

...but now that I have, I'm not sure I like the looks of it...

If you called them RISCV_ISA_EXT_GROUP_ZKN (or similar) it would look a lot less out of place IMO. I'd probably drop the "group2" dance & pick a better name for "Zks_group2", maybe just do something like RISCV_ISA_EXT_GROUP_SCALAR_CRYPTO_BITMANIP? Mouthful, but seemed better than trying to be clever with ZBK or something.

Quoted 1 line

[1] https://wiki.riscv.org/display/HOME/Scalar+Cryptography+Instruction+Set+Extension+Group+Names+Diagram

#11 lore raw

Re: [PATCH v4 1/4] RISC-V: Add Bitmanip/Scalar Crypto parsing from DT

In reply to Conor Dooley
Quoted 77 lines · Conor Dooley
Quoted 35 lines · Andrew Jones
Quoted 34 lines · Evan Green
Quoted 32 lines · Conor Dooley
Quoted 3 lines · Samuel Ortiz

From: "Hongren (Zenithal) Zheng" <[email protected]>

Parse Zb/Zk related string from DT and output them to cpuinfo.

One thing that has sprung to mind is that this is not limited to DT anymore, since the information could in theory come from ACPI too. Ditto the title I guess.

Quoted 11 lines

It is worth noting that the Scalar Crypto extension defines "zk" as a shorthand for the Zkn, Zkr and Zkt extensions. Since the Zkn one also implies the Zbkb, Zbkc and Zbkx extensions, simply passing the valid "zk" extension name through a DT will enable all of the Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt extensions.

Also, since there currently is no mechanism to merge all enabled extensions, the generated cpuinfo output could be relatively large. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk_zks" will generate the following cpuinfo output:
"rv64imafdc_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zksed_zksh_zkt".

On that note, I've created another version of what checking for supersets could look like, since it'll be needed either by my series or this one, depending on what gets merged first. I've yet to test the dedicated extensions part of it, but I wanted to get this out before I went looking at other fixes in the area.

Evan, since it was you that commented on this stuff last time around, could you take another look? I'm still not keen on the "subset_of" arrays, but they're an improvement on what I had last time around for sure.

Quoted 7 lines
Quoted 4 lines

This looks alright to me. At the risk of getting into bikeshedding territory, the only awkward bit of it is it composes the extensions in sort of the opposite way you'd expect. I tend to think of Zks as being comprised of {zbkb, zbkc, zksed, zksh},

This is also the way I think of it, so, FWIW, I prefer the approach below, where bundles are expanded.

I took the patch Evan sent me off-list & have spun it into a "real" patch. I did some minor changes (c99 loop, __init marking) to match what the code was already doing and expanded it to work for the new property stuff.
I'm not sure that match_isa_ext() needs to be a function, given the single user - it might be better refactored to drop the outer if & return whether a match was found.
If done that would allow sharing the same function between isa string and dedicated property parsing. I left it intact for now. Might also be worth adding kerneldoc for that struct.

-- >8 --
From 8300b98e487e57d192bc9581c6a3639c40c52623 Mon Sep 17 00:00:00 2001
From: Evan Green <[email protected]>
Date: Wed, 12 Jul 2023 10:36:15 -0700
Subject: [PATCH] RISC-V: Add support Scalar Crypto using "bundled extensions"

The Scalar Crypto specification defines Zk as a shorthand for the Zkn, Zkr and Zkt extensions. The same follows for both Zkn, Zks and Zbk, which are all shorthands for various other extensions. The detailed breakdown can be found in their dt-binding entries.

Since Zkn also implies the Zbkb, Zbkc and Zbkx extensions, simply passing "zk" through a DT should enable all of Zbkb, Zbkc, Zbkx, Zkn, Zkr and Zkt. For example, setting the "riscv,isa" DT property to "rv64imafdc_zk" should generate the following cpuinfo output:
"rv64imafdc_zicntr_zicsr_zifencei_zihpm_zbkb_zbkc_zbkx_zknd_zkne_zknh_zkr_zkt"

riscv_isa_ext_data grows a pair of new members, to permit setting the relevant bits for "bundled" extensions, both while parsing the ISA string and the new dedicated extension properties

Quoted 6 lines

---
There's basically none of the original patch left, so I have dropped the co-developed-bys and signed-off-bys from before. It does need one from you now though Evan!

Oops, I hadn't realized this was blocked on me!

#12 lore raw

PATCH v4 2/4 dt-bindings: riscv: Document the 1.0 scalar cryptography extensions

In reply to Samuel Ortiz

The RISC-V cryptography extensions define a set of instructions, CSR definitions, architectural interfaces and also extension shorthands for running scalar and vector based cryptography operations on RISC-V systems.

This documents all the dt-bindings for the scalar cryptography extensions, including the Zk, Zkn and Zks shorthands.

---
 .../devicetree/bindings/riscv/extensions.yaml | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
Documentation/devicetree/bindings/riscv/extensions.yaml +87 -0
index cc1f546fdbdc..3d3d0d2f71e7 100644
@@ -190,6 +190,24 @@ properties:
             instructions as ratified at commit 6d33919 ("Merge pull request #158
             from hirooih/clmul-fix-loop-end-condition") of riscv-bitmanip.
 
+        - const: zbkb
+          description: |
+            The standard Zbkb cryptography extension for bit-manipulation
+            instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zbkc
+          description: |
+            The standard Zbkc cryptography extension for carry-less multiply
+            instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zbkx
+          description: |
+            The standard Zbkx cryptography extension for crossbar permutation
+            instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
         - const: zicbom
           description:
             The standard Zicbom extension for base cache management operations as
@@ -240,6 +258,75 @@ properties:
             ratified in the 20191213 version of the unprivileged ISA
             specification.
 
+        - const: zk
+          description: |
+            The standard Zk cryptography extension is a shorthand for the
+            union of the Zkn, Zkr and Zkt cryptography extensions, as ratified
+            at commit 73de909 ("Zvk: Update AES instruction specs") of
+            riscv-crypto.
+
+        - const: zkn
+          description: |
+            The standard Zkn cryptography extension covers the NIST algorithm
+            suite that other cryptography extensions support. It is the union of
+            the Zbkb, Zbkc, Zbkx, Zknd, Zkne and Zknh extensions, as ratified at
+            commit 73de909 ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zknd
+          description: |
+            The standard Zknd cryptography extension for AES block cipher
+            decryption acceleration instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zkne
+          description: |
+            The standard Zkne cryptography extension for AES block cipher
+            encryption acceleration instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zknh
+          description: |
+            The standard Zknh cryptography extension for SHA2 hash algorithm
+            functions acceleration instructions as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zkr
+          description: |
+            The standard Zkr cryptography extension for the entropy source CSR
+            definitions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+            Systems with the Zkr extension enabled must set the MSECCFG SSEED
+            bit to 1 in order for the Linux kernel to access the SEED CSR.
+            As userspace access to the entropy source is usually carefully
+            controlled and exclusively managed by the Linux kernel, M-mode
+            should set USEED to 0.
+
+        - const: zks
+          description: |
+            The standard Zks cryptography extension covers the ShangMi algorithm
+            suite that other cryptography extensions support. It is the union of
+            the Zbkb, Zbkc, Zbkx, Zksed and Zksh extensions, as ratified at
+            commit 73de909 ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zksed
+          description: |
+            The standard Zksed cryptography extension for SM4 block cipher
+            acceleration instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zksh
+          description: |
+            The standard Zksh cryptography extension for SM3 hash algorithm
+            funstions acceleration instructions, as ratified at commit 73de909
+            ("Zvk: Update AES instruction specs") of riscv-crypto.
+
+        - const: zkt
+          description: |
+            The standard Zkt cryptography extension for data independent
+            execution latency attestation, for a safe subset of instructions,
+            as ratified at commit 73de909 ("Zvk: Update AES instruction specs")
+            of riscv-crypto.
+
         - const: ztso
           description:
             The standard Ztso extension for total store ordering, as ratified
Signature · 1 line
2.41.0
#13 lore raw

PATCH v4 3/4 RISC-V: hwprobe: Expose Zbc and the scalar crypto extensions

In reply to Samuel Ortiz

Zbc was missing from a previous Bit-Manipulation extension hwprobe patch.

Add all scalar crypto extensions bits, and define a macro for setting the hwprobe key/pair in a more readable way.

---
 Documentation/riscv/hwprobe.rst       | 35 ++++++++++++++++++++++++++
 arch/riscv/include/uapi/asm/hwprobe.h | 11 ++++++++
 arch/riscv/kernel/sys_riscv.c         | 36 ++++++++++++++++-----------
 3 files changed, 68 insertions(+), 14 deletions(-)
Documentation/riscv/hwprobe.rst +35 -0
index 19165ebd82ba..105b59e2e780 100644
@@ -72,11 +72,46 @@ The following keys are defined:
        extensions.
 
   * :c:macro:`RISCV_HWPROBE_EXT_ZBB`: The Zbb extension is supported, as defined
+      in version 1.0 of the Bit-Manipulation ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBC`: The Zbc extension is supported, as defined
        in version 1.0 of the Bit-Manipulation ISA extensions.
 
   * :c:macro:`RISCV_HWPROBE_EXT_ZBS`: The Zbs extension is supported, as defined
        in version 1.0 of the Bit-Manipulation ISA extensions.
 
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBKB`: The Zbkb extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBKC`: The Zbkc extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBKX`: The Zbkx extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKND`: The Zknd extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKNE`: The Zkne extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKNH`: The Zknh extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKR`: The Zkr extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions. Depending on the
+    M-mode `mseccfg` CSR configuration, userspace may not be allowed to directly
+    access the Zkr-defined `seed` CSR.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKSED`: The Zksed extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKSH`: The Zksh extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZKT`: The Zkt extension is supported, as defined
+    in version 1.0 of the Scalar Cryptography ISA extensions.
+
 * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: A bitmask that contains performance
   information about the selected set of processors.
 
arch/riscv/include/uapi/asm/hwprobe.h +11 -0
index 006bfb48343d..8357052061b3 100644
@@ -29,6 +29,17 @@ struct riscv_hwprobe {
 #define		RISCV_HWPROBE_EXT_ZBA		(1 << 3)
 #define		RISCV_HWPROBE_EXT_ZBB		(1 << 4)
 #define		RISCV_HWPROBE_EXT_ZBS		(1 << 5)
+#define		RISCV_HWPROBE_EXT_ZBC		(1 << 6)
+#define		RISCV_HWPROBE_EXT_ZBKB		(1 << 7)
+#define		RISCV_HWPROBE_EXT_ZBKC		(1 << 8)
+#define		RISCV_HWPROBE_EXT_ZBKX		(1 << 9)
+#define		RISCV_HWPROBE_EXT_ZKND		(1 << 10)
+#define		RISCV_HWPROBE_EXT_ZKNE		(1 << 11)
+#define		RISCV_HWPROBE_EXT_ZKNH		(1 << 12)
+#define		RISCV_HWPROBE_EXT_ZKR		(1 << 13)
+#define		RISCV_HWPROBE_EXT_ZKSED		(1 << 14)
+#define		RISCV_HWPROBE_EXT_ZKSH		(1 << 15)
+#define		RISCV_HWPROBE_EXT_ZKT		(1 << 16)
 #define RISCV_HWPROBE_KEY_CPUPERF_0	5
 #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
 #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
arch/riscv/kernel/sys_riscv.c +22 -14
index 26ef5526bfb4..df15926196b6 100644
@@ -145,20 +145,28 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 	for_each_cpu(cpu, cpus) {
 		struct riscv_isainfo *isainfo = &hart_isa[cpu];
 
-		if (riscv_isa_extension_available(isainfo->isa, ZBA))
-			pair->value |= RISCV_HWPROBE_EXT_ZBA;
-		else
-			missing |= RISCV_HWPROBE_EXT_ZBA;
-
-		if (riscv_isa_extension_available(isainfo->isa, ZBB))
-			pair->value |= RISCV_HWPROBE_EXT_ZBB;
-		else
-			missing |= RISCV_HWPROBE_EXT_ZBB;
-
-		if (riscv_isa_extension_available(isainfo->isa, ZBS))
-			pair->value |= RISCV_HWPROBE_EXT_ZBS;
-		else
-			missing |= RISCV_HWPROBE_EXT_ZBS;
+#define SET_HWPROBE_EXT_PAIR(ext)					\
+		do {							\
+			if (riscv_isa_extension_available(isainfo->isa, ext)) \
+				pair->value |= RISCV_HWPROBE_EXT_## ext; \
+			else						\
+				missing |= RISCV_HWPROBE_EXT_## ext;	\
+		} while (false)						\
+
+		SET_HWPROBE_EXT_PAIR(ZBA);
+		SET_HWPROBE_EXT_PAIR(ZBB);
+		SET_HWPROBE_EXT_PAIR(ZBC);
+		SET_HWPROBE_EXT_PAIR(ZBS);
+		SET_HWPROBE_EXT_PAIR(ZBKB);
+		SET_HWPROBE_EXT_PAIR(ZBKC);
+		SET_HWPROBE_EXT_PAIR(ZBKX);
+		SET_HWPROBE_EXT_PAIR(ZKND);
+		SET_HWPROBE_EXT_PAIR(ZKNE);
+		SET_HWPROBE_EXT_PAIR(ZKNH);
+		SET_HWPROBE_EXT_PAIR(ZKR);
+		SET_HWPROBE_EXT_PAIR(ZKSED);
+		SET_HWPROBE_EXT_PAIR(ZKSH);
+		SET_HWPROBE_EXT_PAIR(ZKT);
 	}
 
 	/* Now turn off reporting features if any CPU is missing it. */
Signature · 1 line
2.41.0
#14 lore raw

PATCH v4 4/4 RISC-V: Implement archrandom when Zkr is available

In reply to Samuel Ortiz

The Zkr extension is ratified and provides 16 bits of entropy seed when reading the SEED CSR.

We can implement arch_get_random_seed_longs() by doing multiple csrrw to that CSR and filling an unsigned long with valid entropy bits.

---
 arch/riscv/include/asm/archrandom.h | 70 +++++++++++++++++++++++++++++
 arch/riscv/include/asm/csr.h        |  9 ++++
 2 files changed, 79 insertions(+)
 create mode 100644 arch/riscv/include/asm/archrandom.h
arch/riscv/include/asm/archrandom.h new file +70 -0
new file mode 100644
index 000000000000..38f3cced0fd0
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Kernel interface for the RISCV arch_random_* functions
+ *
+ * Copyright (c) 2023 by Rivos Inc.
+ *
+ */
+
+#ifndef ASM_RISCV_ARCHRANDOM_H
+#define ASM_RISCV_ARCHRANDOM_H
+
+#include <asm/csr.h>
+
+#define SEED_RETRY_LOOPS 100
+
+static inline bool __must_check csr_seed_long(unsigned long *v)
+{
+	unsigned int retry = SEED_RETRY_LOOPS, valid_seeds = 0;
+	const int needed_seeds = sizeof(long) / sizeof(u16);
+	u16 *entropy = (u16 *)v;
+
+	do {
+		/*
+		 * The SEED CSR (0x015) must be accessed with a read-write
+		 * instruction.
+		 */
+		unsigned long csr_seed = csr_swap(CSR_SEED, 0);
+
+		switch (csr_seed & SEED_OPST_MASK) {
+		case SEED_OPST_ES16:
+			entropy[valid_seeds++] = csr_seed & SEED_ENTROPY_MASK;
+			if (valid_seeds == needed_seeds)
+				return true;
+			break;
+
+		case SEED_OPST_DEAD:
+			pr_err_once("archrandom: Unrecoverable error\n");
+			return false;
+
+		case SEED_OPST_BIST:
+		case SEED_OPST_WAIT:
+		default:
+			continue;
+		}
+	} while (--retry);
+
+	return false;
+}
+
+static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
+{
+	return 0;
+}
+
+static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs)
+{
+	if (!max_longs)
+		return 0;
+
+	/*
+	 * If Zkr is supported and csr_seed_long succeeds, we return one long
+	 * worth of entropy.
+	 */
+	if (riscv_has_extension_likely(RISCV_ISA_EXT_ZKR) && csr_seed_long(v))
+		return 1;
+
+	return 0;
+}
+
+#endif /* ASM_RISCV_ARCHRANDOM_H */
arch/riscv/include/asm/csr.h +9 -0
index 7bac43a3176e..ff6f570487b9 100644
@@ -391,6 +391,15 @@
 #define CSR_VTYPE		0xc21
 #define CSR_VLENB		0xc22
 
+/* Scalar Crypto Extension - Entropy */
+#define CSR_SEED		0x015
+#define SEED_OPST_MASK		_AC(0xC0000000, UL)
+#define SEED_OPST_BIST		_AC(0x00000000, UL)
+#define SEED_OPST_WAIT		_AC(0x40000000, UL)
+#define SEED_OPST_ES16		_AC(0x80000000, UL)
+#define SEED_OPST_DEAD		_AC(0xC0000000, UL)
+#define SEED_ENTROPY_MASK	_AC(0xFFFF, UL)
+
 #ifdef CONFIG_RISCV_M_MODE
 # define CSR_STATUS	CSR_MSTATUS
 # define CSR_IE		CSR_MIE
Signature · 1 line
2.41.0