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

Conor Dooley conor.dooley at microchip.com
Wed Jul 12 04:17:15 PDT 2023


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" <i at zenithal.me>
> > > 
> > > 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 <conor.dooley at microchip.com>
> > 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 <i at zenithal.me>
> > Signed-off-by: Hongren (Zenithal) Zheng <i at zenithal.me>
> > Co-developed-by: Samuel Ortiz <sameo at rivosinc.com>
> > Signed-off-by: Samuel Ortiz <sameo at rivosinc.com>
> > Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> > ---
> >  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
> > 
> > 
> 
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20230712/c39f651d/attachment.sig>


More information about the linux-riscv mailing list