2023-07-12 08:59:03

by Samuel Ortiz

[permalink] [raw]
Subject: [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".

Tested-by: Jiatai He <[email protected]>
Tested-by: Heiko Stuebner <[email protected]>
Reviewed-by: Evan Green <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Reviewed-by: Heiko Stuebner <[email protected]>
Signed-off-by: Hongren (Zenithal) Zheng <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
---
arch/riscv/include/asm/hwcap.h | 11 +++++++++++
arch/riscv/kernel/cpu.c | 11 +++++++++++
arch/riscv/kernel/cpufeature.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index f041bfa7f6a0..b80ca6e77088 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -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
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index a2fc952318e9..10524322a4c0 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -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),
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index bdcf460ea53d..9a872a2007a5 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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
}
--
2.41.0



2023-07-12 11:09:10

by Conor Dooley

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

On Wed, Jul 12, 2023 at 11:39:16AM +0100, Conor Dooley wrote:
> Hey Samuel, Evan,
>
> On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > 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.
>
> > 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 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.

> (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.
>
> Co-developed-by: Hongren (Zenithal) Zheng <[email protected]>
> Signed-off-by: Hongren (Zenithal) Zheng <[email protected]>
> Co-developed-by: Samuel Ortiz <[email protected]>
> Signed-off-by: Samuel Ortiz <[email protected]>
> Signed-off-by: Conor Dooley <[email protected]>
> ---
> arch/riscv/include/asm/hwcap.h | 13 +++++
> arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
> 2 files changed, 94 insertions(+), 14 deletions(-)
>
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index b7b58258f6c7..46d54f31e162 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -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[];
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 5945dfc5f806..e862958d5495 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -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))
> --
> 2.40.1
>
>



Attachments:
(No filename) (10.19 kB)
signature.asc (235.00 B)
Download all attachments

2023-07-12 11:28:38

by Conor Dooley

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

Me again, spotted an issue after sending.

On Wed, Jul 12, 2023 at 11:46:52AM +0100, Conor Dooley wrote:
> On Wed, Jul 12, 2023 at 11:39:16AM +0100, Conor Dooley wrote:
> > On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > > 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.
> >
> > > 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 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...
>
> > (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.
> >
> > Co-developed-by: Hongren (Zenithal) Zheng <[email protected]>
> > Signed-off-by: Hongren (Zenithal) Zheng <[email protected]>
> > Co-developed-by: Samuel Ortiz <[email protected]>
> > Signed-off-by: Samuel Ortiz <[email protected]>
> > Signed-off-by: Conor Dooley <[email protected]>
> > ---
> > arch/riscv/include/asm/hwcap.h | 13 +++++
> > arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
> > 2 files changed, 94 insertions(+), 14 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> > index b7b58258f6c7..46d54f31e162 100644
> > --- a/arch/riscv/include/asm/hwcap.h
> > +++ b/arch/riscv/include/asm/hwcap.h
> > @@ -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;

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.

> > };
> >
> > extern const struct riscv_isa_ext_data riscv_isa_ext[];
> > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > index 5945dfc5f806..e862958d5495 100644
> > --- a/arch/riscv/kernel/cpufeature.c
> > +++ b/arch/riscv/kernel/cpufeature.c
> > @@ -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))
> > --
> > 2.40.1
> >
> >
>
>



Attachments:
(No filename) (10.91 kB)
signature.asc (235.00 B)
Download all attachments

2023-07-12 11:30:24

by Conor Dooley

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

Hey Samuel, Evan,

On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> 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.

> 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.

Co-developed-by: Hongren (Zenithal) Zheng <[email protected]>
Signed-off-by: Hongren (Zenithal) Zheng <[email protected]>
Co-developed-by: Samuel Ortiz <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Conor Dooley <[email protected]>
---
arch/riscv/include/asm/hwcap.h | 13 +++++
arch/riscv/kernel/cpufeature.c | 95 +++++++++++++++++++++++++++++-----
2 files changed, 94 insertions(+), 14 deletions(-)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index b7b58258f6c7..46d54f31e162 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -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[];
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 5945dfc5f806..e862958d5495 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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))
--
2.40.1



Attachments:
(No filename) (9.44 kB)
signature.asc (235.00 B)
Download all attachments

2023-07-12 18:14:33

by Conor Dooley

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

On Wed, Jul 12, 2023 at 10:43:33AM -0700, Evan Green wrote:

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

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

> 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.

> 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.


Attachments:
(No filename) (1.02 kB)
signature.asc (235.00 B)
Download all attachments

2023-07-12 18:21:22

by Evan Green

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

On Wed, Jul 12, 2023 at 3:39 AM Conor Dooley <[email protected]> wrote:
>
> Hey Samuel, Evan,
>
> On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > 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.
>
> > 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.
>

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(-)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index b7b58258f6c7..7d2d10b42cf3 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -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[];
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 5945dfc5f806..2a1f958c1777 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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)
{
@@ -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
}
}

2023-07-13 09:06:49

by Andrew Jones

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

On Wed, Jul 12, 2023 at 10:43:33AM -0700, Evan Green wrote:
> On Wed, Jul 12, 2023 at 3:39 AM Conor Dooley <[email protected]> wrote:
> >
> > Hey Samuel, Evan,
> >
> > On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > > 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.
> >
> > > 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.
> >
>
> 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

> 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(-)
>
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index b7b58258f6c7..7d2d10b42cf3 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -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[];
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 5945dfc5f806..2a1f958c1777 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -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)
> {
> @@ -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
> }
> }

2023-07-13 11:42:32

by Conor Dooley

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

On Thu, Jul 13, 2023 at 10:46:14AM +0200, Andrew Jones wrote:
> On Wed, Jul 12, 2023 at 10:43:33AM -0700, Evan Green wrote:
> > On Wed, Jul 12, 2023 at 3:39 AM Conor Dooley <[email protected]> wrote:
> > > On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > > > 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.
> > >
> > > > 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.
> > >
> >
> > 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

Co-developed-by: Conor Dooley <[email protected]>
Signed-off-by: Conor Dooley <[email protected]>
---
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(-)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index b7b58258f6c7..f74308633e45 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -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[];
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index ccbe27b3060b..d999d73554f0 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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) \
+}
+
+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,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);
--
2.40.1



Attachments:
(No filename) (10.44 kB)
signature.asc (235.00 B)
Download all attachments

2023-07-13 12:48:33

by Andrew Jones

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

On Thu, Jul 13, 2023 at 12:27:24PM +0100, Conor Dooley wrote:
> On Thu, Jul 13, 2023 at 10:46:14AM +0200, Andrew Jones wrote:
> > On Wed, Jul 12, 2023 at 10:43:33AM -0700, Evan Green wrote:
> > > On Wed, Jul 12, 2023 at 3:39 AM Conor Dooley <[email protected]> wrote:
> > > > On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > > > > 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.
> > > >
> > > > > 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.
> > > >
> > >
> > > 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
>
> Co-developed-by: Conor Dooley <[email protected]>
> Signed-off-by: Conor Dooley <[email protected]>
> ---
> 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(-)
>
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index b7b58258f6c7..f74308633e45 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -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[];
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index ccbe27b3060b..d999d73554f0 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -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) \
> +}
> +
> +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.

> +};
> +
> +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

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

> +};
> +
> /*
> * 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);
> --
> 2.40.1
>
>



2023-07-13 14:08:43

by Conor Dooley

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

On Thu, Jul 13, 2023 at 02:45:57PM +0200, Andrew Jones wrote:
> On Thu, Jul 13, 2023 at 12:27:24PM +0100, Conor Dooley wrote:

> > +#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) { \
> > + .name = #_name, \
> > + .property = #_name, \
> > + .bundle_ids = _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,
>
> I think RISCV_ISA_EXT_ZKNH also belongs in this bundle,
> since the spec says zk is the zkn bundle plus zkr and 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
>
> 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.

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

WFM at least.

> 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...

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.

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


Attachments:
(No filename) (2.71 kB)
signature.asc (235.00 B)
Download all attachments

2023-10-12 16:28:35

by Evan Green

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

On Thu, Jul 13, 2023 at 4:28 AM Conor Dooley <[email protected]> wrote:
>
> On Thu, Jul 13, 2023 at 10:46:14AM +0200, Andrew Jones wrote:
> > On Wed, Jul 12, 2023 at 10:43:33AM -0700, Evan Green wrote:
> > > On Wed, Jul 12, 2023 at 3:39 AM Conor Dooley <[email protected]> wrote:
> > > > On Wed, Jul 12, 2023 at 10:41:17AM +0200, Samuel Ortiz wrote:
> > > > > 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.
> > > >
> > > > > 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.
> > > >
> > >
> > > 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
>
> Co-developed-by: Conor Dooley <[email protected]>
> Signed-off-by: Conor Dooley <[email protected]>
> ---
> 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!

Signed-off-by: Evan Green <[email protected]>