Message ID | 20230424194911.264850-2-heiko.stuebner@vrull.eu (mailing list archive) |
---|---|
State | Rejected |
Headers | show |
Series | Expose the isa-string via the AT_BASE_PLATFORM aux vector | expand |
Context | Check | Description |
---|---|---|
conchuod/cover_letter | success | Series has a cover letter |
conchuod/tree_selection | success | Guessed tree name to be for-next at HEAD 310c33dc7a12 |
conchuod/fixes_present | success | Fixes tag not required for -next series |
conchuod/maintainers_pattern | success | MAINTAINERS pattern errors before the patch: 1 and now 1 |
conchuod/verify_signedoff | success | Signed-off-by tag matches author and committer |
conchuod/kdoc | success | Errors and warnings before: 0 this patch: 0 |
conchuod/build_rv64_clang_allmodconfig | success | Errors and warnings before: 18 this patch: 18 |
conchuod/module_param | success | Was 0 now: 0 |
conchuod/build_rv64_gcc_allmodconfig | fail | Errors and warnings before: 19 this patch: 20 |
conchuod/build_rv32_defconfig | success | Build OK |
conchuod/dtb_warn_rv64 | success | Errors and warnings before: 3 this patch: 3 |
conchuod/header_inline | success | No static functions without inline keyword in header files |
conchuod/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 98 lines checked |
conchuod/source_inline | success | Was 0 now: 0 |
conchuod/build_rv64_nommu_k210_defconfig | success | Build OK |
conchuod/verify_fixes | success | No Fixes tag |
conchuod/build_rv64_nommu_virt_defconfig | success | Build OK |
Hi Heiko,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20230424]
[also build test WARNING on v6.3]
[cannot apply to soc/for-next linus/master kees/for-next/execve v6.3 v6.3-rc7 v6.3-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Heiko-Stuebner/RISC-V-create-ISA-string-separately-not-as-part-of-cpuinfo/20230425-035214
base: next-20230424
patch link: https://lore.kernel.org/r/20230424194911.264850-2-heiko.stuebner%40vrull.eu
patch subject: [PATCH 1/4] RISC-V: create ISA string separately - not as part of cpuinfo
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20230425/202304250614.g73yVtvv-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/8f1a5a16616d673f2c82cdc54ff845fd8b125a21
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Heiko-Stuebner/RISC-V-create-ISA-string-separately-not-as-part-of-cpuinfo/20230425-035214
git checkout 8f1a5a16616d673f2c82cdc54ff845fd8b125a21
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash arch/riscv/kernel/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304250614.g73yVtvv-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/string.h:254,
from include/linux/bitmap.h:11,
from include/linux/cpumask.h:12,
from include/linux/smp.h:13,
from include/linux/lockdep.h:14,
from include/linux/rcupdate.h:29,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/node.h:18,
from include/linux/cpu.h:17,
from arch/riscv/kernel/cpu.c:6:
In function 'strnlen',
inlined from 'strncat' at include/linux/fortify-string.h:404:13,
inlined from 'riscv_create_isa_string' at arch/riscv/kernel/cpu.c:269:4:
>> include/linux/fortify-string.h:29:33: warning: 'strlen' argument missing terminating nul [-Wstringop-overread]
29 | __ret = __builtin_strlen(__p); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:195:24: note: in expansion of macro '__compiletime_strlen'
195 | size_t p_len = __compiletime_strlen(p);
| ^~~~~~~~~~~~~~~~~~~~
arch/riscv/kernel/cpu.c: In function 'riscv_create_isa_string':
arch/riscv/kernel/cpu.c:245:19: note: referenced argument declared here
245 | static const char base_riscv_exts[13] = "imafdqcbkjpvh";
| ^~~~~~~~~~~~~~~
vim +/strlen +29 include/linux/fortify-string.h
a28a6e860c6cf2 Francis Laniel 2021-02-25 18
3009f891bb9f32 Kees Cook 2021-08-02 19 #define __compiletime_strlen(p) \
3009f891bb9f32 Kees Cook 2021-08-02 20 ({ \
e9a40e1585d792 Kees Cook 2022-10-25 21 char *__p = (char *)(p); \
311fb40aa0569a Kees Cook 2022-09-02 22 size_t __ret = SIZE_MAX; \
9f7d69c5cd2390 Kees Cook 2022-09-19 23 size_t __p_size = __member_size(p); \
311fb40aa0569a Kees Cook 2022-09-02 24 if (__p_size != SIZE_MAX && \
d07c0acb4f41cc Kees Cook 2022-09-02 25 __builtin_constant_p(*__p)) { \
95cadae320be46 Qian Cai 2021-10-25 26 size_t __p_len = __p_size - 1; \
95cadae320be46 Qian Cai 2021-10-25 27 if (__builtin_constant_p(__p[__p_len]) && \
95cadae320be46 Qian Cai 2021-10-25 28 __p[__p_len] == '\0') \
95cadae320be46 Qian Cai 2021-10-25 @29 __ret = __builtin_strlen(__p); \
3009f891bb9f32 Kees Cook 2021-08-02 30 } \
95cadae320be46 Qian Cai 2021-10-25 31 __ret; \
3009f891bb9f32 Kees Cook 2021-08-02 32 })
3009f891bb9f32 Kees Cook 2021-08-02 33
Hi Heiko, kernel test robot noticed the following build warnings: [auto build test WARNING on next-20230424] [also build test WARNING on v6.3] [cannot apply to soc/for-next linus/master kees/for-next/execve v6.3 v6.3-rc7 v6.3-rc6] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Heiko-Stuebner/RISC-V-create-ISA-string-separately-not-as-part-of-cpuinfo/20230425-035214 base: next-20230424 patch link: https://lore.kernel.org/r/20230424194911.264850-2-heiko.stuebner%40vrull.eu patch subject: [PATCH 1/4] RISC-V: create ISA string separately - not as part of cpuinfo config: riscv-allnoconfig (https://download.01.org/0day-ci/archive/20230425/202304251640.IVxoyd0v-lkp@intel.com/config) compiler: riscv64-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/8f1a5a16616d673f2c82cdc54ff845fd8b125a21 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Heiko-Stuebner/RISC-V-create-ISA-string-separately-not-as-part-of-cpuinfo/20230425-035214 git checkout 8f1a5a16616d673f2c82cdc54ff845fd8b125a21 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash arch/riscv/kernel/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Link: https://lore.kernel.org/oe-kbuild-all/202304251640.IVxoyd0v-lkp@intel.com/ All warnings (new ones prefixed by >>): arch/riscv/kernel/cpu.c: In function 'riscv_create_isa_string': >> arch/riscv/kernel/cpu.c:269:25: warning: 'strncat' output may be truncated copying 1 byte from a string of length 13 [-Wstringop-truncation] 269 | strncat(isa_str, &base_riscv_exts[i], 1); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/strncat +269 arch/riscv/kernel/cpu.c 246 247 static char *riscv_create_isa_string(const char *isa) 248 { 249 int maxlen = 4; 250 char *isa_str; 251 int i; 252 253 /* calculate the needed string length */ 254 for (i = 0; i < sizeof(base_riscv_exts); i++) 255 if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) 256 maxlen++; 257 maxlen += strlen_isa_ext(); 258 259 isa_str = kzalloc(maxlen, GFP_KERNEL); 260 if (!isa_str) 261 return ERR_PTR(-ENOMEM); 262 263 /* Print the rv[64/32] part */ 264 strncat(isa_str, isa, 4); 265 266 for (i = 0; i < sizeof(base_riscv_exts); i++) { 267 if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) 268 /* Print only enabled the base ISA extensions */ > 269 strncat(isa_str, &base_riscv_exts[i], 1); 270 } 271 272 strcat_isa_ext(isa_str); 273 274 return isa_str; 275 } 276
On Mon, Apr 24, 2023 at 09:49:08PM +0200, Heiko Stuebner wrote: > From: Heiko Stuebner <heiko.stuebner@vrull.eu> > > The isa string is a very central part of the RISC-V architecture, so will > be needed in other places as well. > > So in a first step decouple the generation of the runtime isa-string from > /proc/cpuinfo - its current only user. > > The resulting string should not differ from the previously generated one. > > Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu> > --- > arch/riscv/kernel/cpu.c | 70 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 62 insertions(+), 8 deletions(-) > > diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c > index 3df38052dcbd..ebc478f0a16c 100644 > --- a/arch/riscv/kernel/cpu.c > +++ b/arch/riscv/kernel/cpu.c > @@ -193,10 +193,33 @@ static struct riscv_isa_ext_data isa_ext_arr[] = { > __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX), > }; > > -static void print_isa_ext(struct seq_file *f) > +static int strlen_isa_ext(void) > { > struct riscv_isa_ext_data *edata; > - int i = 0, arr_sz; > + int ext_len = 0, i, arr_sz; > + > + arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; I see this subtracting of 1 here and then using <= below comes from the current print_isa_ext(), but it seems odd. How about just static int strlen_isa_ext(void) { int ext_len = 0; for (int i = 0; i < ARRAY_SIZE(isa_ext_arr); ++i) { struct riscv_isa_ext_data *edata = &isa_ext_arr[i]; ... } return ext_len; } > + > + /* No extension support available */ > + if (arr_sz <= 0) > + return 0; > + > + for (i = 0; i <= arr_sz; i++) { > + edata = &isa_ext_arr[i]; > + if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > + continue; > + > + /* string length + underscore */ > + ext_len += strlen(edata->uprop) + 1; > + } > + > + return ext_len; > +} > + > +static void strcat_isa_ext(char *isa_str) > +{ > + struct riscv_isa_ext_data *edata; > + int i, arr_sz; > > arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; > > @@ -208,7 +231,8 @@ static void print_isa_ext(struct seq_file *f) > edata = &isa_ext_arr[i]; > if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > continue; > - seq_printf(f, "_%s", edata->uprop); > + strcat(isa_str, "_"); > + strcat(isa_str, edata->uprop); > } > } > > @@ -220,19 +244,49 @@ static void print_isa_ext(struct seq_file *f) > */ > static const char base_riscv_exts[13] = "imafdqcbkjpvh"; > > -static void print_isa(struct seq_file *f, const char *isa) > +static char *riscv_create_isa_string(const char *isa) > { > + int maxlen = 4; > + char *isa_str; > int i; > > - seq_puts(f, "isa\t\t: "); > + /* calculate the needed string length */ > + for (i = 0; i < sizeof(base_riscv_exts); i++) > + if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > + maxlen++; > + maxlen += strlen_isa_ext(); > + > + isa_str = kzalloc(maxlen, GFP_KERNEL); > + if (!isa_str) > + return ERR_PTR(-ENOMEM); > + > /* Print the rv[64/32] part */ > - seq_write(f, isa, 4); > + strncat(isa_str, isa, 4); > + > for (i = 0; i < sizeof(base_riscv_exts); i++) { > if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > /* Print only enabled the base ISA extensions */ > - seq_write(f, &base_riscv_exts[i], 1); > + strncat(isa_str, &base_riscv_exts[i], 1); > + } > + > + strcat_isa_ext(isa_str); > + > + return isa_str; > +} > + > +static void print_isa(struct seq_file *f, const char *isa) > +{ > + char *isa_str; > + > + seq_puts(f, "isa\t\t: "); > + > + isa_str = riscv_create_isa_string(isa); > + if (!IS_ERR(isa_str)) { > + seq_write(f, isa_str, strlen(isa_str)); > + kfree(isa_str); > + } else { > + seq_puts(f, "unknown"); > } > - print_isa_ext(f); > seq_puts(f, "\n"); > } > > -- > 2.39.0 Otherwise, Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
On Mon, Apr 24, 2023 at 09:49:08PM +0200, Heiko Stuebner wrote: > From: Heiko Stuebner <heiko.stuebner@vrull.eu> > > The isa string is a very central part of the RISC-V architecture, so will > be needed in other places as well. > > So in a first step decouple the generation of the runtime isa-string from > /proc/cpuinfo - its current only user. > > The resulting string should not differ from the previously generated one. > > Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu> > --- > arch/riscv/kernel/cpu.c | 70 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 62 insertions(+), 8 deletions(-) > > diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c > index 3df38052dcbd..ebc478f0a16c 100644 > --- a/arch/riscv/kernel/cpu.c > +++ b/arch/riscv/kernel/cpu.c > @@ -193,10 +193,33 @@ static struct riscv_isa_ext_data isa_ext_arr[] = { > __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX), > }; > > -static void print_isa_ext(struct seq_file *f) > +static int strlen_isa_ext(void) > { > struct riscv_isa_ext_data *edata; > - int i = 0, arr_sz; > + int ext_len = 0, i, arr_sz; > + > + arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; > + > + /* No extension support available */ > + if (arr_sz <= 0) > + return 0; > + > + for (i = 0; i <= arr_sz; i++) { > + edata = &isa_ext_arr[i]; > + if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > + continue; > + > + /* string length + underscore */ > + ext_len += strlen(edata->uprop) + 1; > + } > + > + return ext_len; > +} > + > +static void strcat_isa_ext(char *isa_str) > +{ > + struct riscv_isa_ext_data *edata; > + int i, arr_sz; > > arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; > > @@ -208,7 +231,8 @@ static void print_isa_ext(struct seq_file *f) > edata = &isa_ext_arr[i]; > if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > continue; > - seq_printf(f, "_%s", edata->uprop); > + strcat(isa_str, "_"); > + strcat(isa_str, edata->uprop); > } > } > > @@ -220,19 +244,49 @@ static void print_isa_ext(struct seq_file *f) > */ > static const char base_riscv_exts[13] = "imafdqcbkjpvh"; > > -static void print_isa(struct seq_file *f, const char *isa) > +static char *riscv_create_isa_string(const char *isa) > { > + int maxlen = 4; > + char *isa_str; > int i; > > - seq_puts(f, "isa\t\t: "); > + /* calculate the needed string length */ > + for (i = 0; i < sizeof(base_riscv_exts); i++) > + if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > + maxlen++; > + maxlen += strlen_isa_ext(); > + > + isa_str = kzalloc(maxlen, GFP_KERNEL); > + if (!isa_str) > + return ERR_PTR(-ENOMEM); > + > /* Print the rv[64/32] part */ > - seq_write(f, isa, 4); > + strncat(isa_str, isa, 4); > + > for (i = 0; i < sizeof(base_riscv_exts); i++) { > if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > /* Print only enabled the base ISA extensions */ > - seq_write(f, &base_riscv_exts[i], 1); > + strncat(isa_str, &base_riscv_exts[i], 1); > + } > + > + strcat_isa_ext(isa_str); > + > + return isa_str; > +} > + > +static void print_isa(struct seq_file *f, const char *isa) > +{ > + char *isa_str; > + > + seq_puts(f, "isa\t\t: "); > + > + isa_str = riscv_create_isa_string(isa); Shouldn't there be another patch in this series that switches this to using the new riscv_base_platform. The allocation/regeneration/freeing doesn't seem necessary each time we cat cpuinfo. Thanks, drew > + if (!IS_ERR(isa_str)) { > + seq_write(f, isa_str, strlen(isa_str)); > + kfree(isa_str); > + } else { > + seq_puts(f, "unknown"); > } > - print_isa_ext(f); > seq_puts(f, "\n"); > } > > -- > 2.39.0 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
On Mon, 24 Apr 2023 12:49:08 PDT (-0700), heiko@sntech.de wrote: > From: Heiko Stuebner <heiko.stuebner@vrull.eu> > > The isa string is a very central part of the RISC-V architecture, so will > be needed in other places as well. > > So in a first step decouple the generation of the runtime isa-string from > /proc/cpuinfo - its current only user. I'm also going to leave this one out, both because it fails to build and because the proposed second user isn't going to fly. I'm not opposed to the refactoring, but too late for this merge window. > The resulting string should not differ from the previously generated one. > > Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu> > --- > arch/riscv/kernel/cpu.c | 70 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 62 insertions(+), 8 deletions(-) > > diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c > index 3df38052dcbd..ebc478f0a16c 100644 > --- a/arch/riscv/kernel/cpu.c > +++ b/arch/riscv/kernel/cpu.c > @@ -193,10 +193,33 @@ static struct riscv_isa_ext_data isa_ext_arr[] = { > __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX), > }; > > -static void print_isa_ext(struct seq_file *f) > +static int strlen_isa_ext(void) > { > struct riscv_isa_ext_data *edata; > - int i = 0, arr_sz; > + int ext_len = 0, i, arr_sz; > + > + arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; > + > + /* No extension support available */ > + if (arr_sz <= 0) > + return 0; > + > + for (i = 0; i <= arr_sz; i++) { > + edata = &isa_ext_arr[i]; > + if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > + continue; > + > + /* string length + underscore */ > + ext_len += strlen(edata->uprop) + 1; > + } > + > + return ext_len; > +} > + > +static void strcat_isa_ext(char *isa_str) > +{ > + struct riscv_isa_ext_data *edata; > + int i, arr_sz; > > arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; > > @@ -208,7 +231,8 @@ static void print_isa_ext(struct seq_file *f) > edata = &isa_ext_arr[i]; > if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) > continue; > - seq_printf(f, "_%s", edata->uprop); > + strcat(isa_str, "_"); > + strcat(isa_str, edata->uprop); > } > } > > @@ -220,19 +244,49 @@ static void print_isa_ext(struct seq_file *f) > */ > static const char base_riscv_exts[13] = "imafdqcbkjpvh"; > > -static void print_isa(struct seq_file *f, const char *isa) > +static char *riscv_create_isa_string(const char *isa) > { > + int maxlen = 4; > + char *isa_str; > int i; > > - seq_puts(f, "isa\t\t: "); > + /* calculate the needed string length */ > + for (i = 0; i < sizeof(base_riscv_exts); i++) > + if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > + maxlen++; > + maxlen += strlen_isa_ext(); > + > + isa_str = kzalloc(maxlen, GFP_KERNEL); > + if (!isa_str) > + return ERR_PTR(-ENOMEM); > + > /* Print the rv[64/32] part */ > - seq_write(f, isa, 4); > + strncat(isa_str, isa, 4); > + > for (i = 0; i < sizeof(base_riscv_exts); i++) { > if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) > /* Print only enabled the base ISA extensions */ > - seq_write(f, &base_riscv_exts[i], 1); > + strncat(isa_str, &base_riscv_exts[i], 1); > + } > + > + strcat_isa_ext(isa_str); > + > + return isa_str; > +} > + > +static void print_isa(struct seq_file *f, const char *isa) > +{ > + char *isa_str; > + > + seq_puts(f, "isa\t\t: "); > + > + isa_str = riscv_create_isa_string(isa); > + if (!IS_ERR(isa_str)) { > + seq_write(f, isa_str, strlen(isa_str)); > + kfree(isa_str); > + } else { > + seq_puts(f, "unknown"); > } > - print_isa_ext(f); > seq_puts(f, "\n"); > }
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 3df38052dcbd..ebc478f0a16c 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -193,10 +193,33 @@ static struct riscv_isa_ext_data isa_ext_arr[] = { __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX), }; -static void print_isa_ext(struct seq_file *f) +static int strlen_isa_ext(void) { struct riscv_isa_ext_data *edata; - int i = 0, arr_sz; + int ext_len = 0, i, arr_sz; + + arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; + + /* No extension support available */ + if (arr_sz <= 0) + return 0; + + for (i = 0; i <= arr_sz; i++) { + edata = &isa_ext_arr[i]; + if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) + continue; + + /* string length + underscore */ + ext_len += strlen(edata->uprop) + 1; + } + + return ext_len; +} + +static void strcat_isa_ext(char *isa_str) +{ + struct riscv_isa_ext_data *edata; + int i, arr_sz; arr_sz = ARRAY_SIZE(isa_ext_arr) - 1; @@ -208,7 +231,8 @@ static void print_isa_ext(struct seq_file *f) edata = &isa_ext_arr[i]; if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id)) continue; - seq_printf(f, "_%s", edata->uprop); + strcat(isa_str, "_"); + strcat(isa_str, edata->uprop); } } @@ -220,19 +244,49 @@ static void print_isa_ext(struct seq_file *f) */ static const char base_riscv_exts[13] = "imafdqcbkjpvh"; -static void print_isa(struct seq_file *f, const char *isa) +static char *riscv_create_isa_string(const char *isa) { + int maxlen = 4; + char *isa_str; int i; - seq_puts(f, "isa\t\t: "); + /* calculate the needed string length */ + for (i = 0; i < sizeof(base_riscv_exts); i++) + if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) + maxlen++; + maxlen += strlen_isa_ext(); + + isa_str = kzalloc(maxlen, GFP_KERNEL); + if (!isa_str) + return ERR_PTR(-ENOMEM); + /* Print the rv[64/32] part */ - seq_write(f, isa, 4); + strncat(isa_str, isa, 4); + for (i = 0; i < sizeof(base_riscv_exts); i++) { if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a')) /* Print only enabled the base ISA extensions */ - seq_write(f, &base_riscv_exts[i], 1); + strncat(isa_str, &base_riscv_exts[i], 1); + } + + strcat_isa_ext(isa_str); + + return isa_str; +} + +static void print_isa(struct seq_file *f, const char *isa) +{ + char *isa_str; + + seq_puts(f, "isa\t\t: "); + + isa_str = riscv_create_isa_string(isa); + if (!IS_ERR(isa_str)) { + seq_write(f, isa_str, strlen(isa_str)); + kfree(isa_str); + } else { + seq_puts(f, "unknown"); } - print_isa_ext(f); seq_puts(f, "\n"); }