diff mbox series

[v3,3/5] RISC-V: Fix unsupported isa string info.

Message ID 20190801005843.10343-4-atish.patra@wdc.com (mailing list archive)
State New, archived
Headers show
Series Miscellaneous fixes | expand

Commit Message

Atish Patra Aug. 1, 2019, 12:58 a.m. UTC
Currently, kernel prints a info warning if any of the extensions
from "mafdcsu" is missing in device tree. This is not entirely
correct as Linux can boot with "f or d" extensions if kernel is
configured accordingly. Moreover, it will continue to print the
info string for future extensions such as hypervisor as well which
is misleading. /proc/cpuinfo also doesn't print any other extensions
except "mafdcsu".

Make sure that info log is only printed only if kernel is configured
to have any mandatory extensions but device tree doesn't describe it.
All the extensions present in device tree and follow the order
described in the RISC-V specification (except 'S') are printed via
/proc/cpuinfo always.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
 arch/riscv/kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 10 deletions(-)

Comments

Paul Walmsley Aug. 6, 2019, 11:27 p.m. UTC | #1
On Wed, 31 Jul 2019, Atish Patra wrote:

> Currently, kernel prints a info warning if any of the extensions
> from "mafdcsu" is missing in device tree. This is not entirely
> correct as Linux can boot with "f or d" extensions if kernel is
> configured accordingly. Moreover, it will continue to print the
> info string for future extensions such as hypervisor as well which
> is misleading. /proc/cpuinfo also doesn't print any other extensions
> except "mafdcsu".
> 
> Make sure that info log is only printed only if kernel is configured
> to have any mandatory extensions but device tree doesn't describe it.
> All the extensions present in device tree and follow the order
> described in the RISC-V specification (except 'S') are printed via
> /proc/cpuinfo always.
> 
> Signed-off-by: Atish Patra <atish.patra@wdc.com>

I tested this patch after dropping the CONFIG_ISA_RISCV_C test (see 
below).  Running "cat /proc/cpuinfo" generated the following kernel 
warnings:
          
[   73.412626] unsupported ISA extensions "su" in device tree for cpu [0]
[   73.418417] unsupported ISA extensions "su" in device tree for cpu [1]
[   73.424912] unsupported ISA extensions "su" in device tree for cpu [2]
[   73.431425] unsupported ISA extensions "su" in device tree for cpu [3]

Seems like the "su" should be dropped from mandatory_ext.  What do you 
think?

> ---
>  arch/riscv/kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++---------
>  1 file changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 7da3c6a93abd..9b1d4550fbe6 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -7,6 +7,7 @@
>  #include <linux/seq_file.h>
>  #include <linux/of.h>
>  #include <asm/smp.h>
> +#include <asm/hwcap.h>
>  
>  /*
>   * Returns the hart ID of the given device tree node, or -ENODEV if the node
> @@ -46,11 +47,14 @@ int riscv_of_processor_hartid(struct device_node *node)
>  
>  #ifdef CONFIG_PROC_FS
>  
> -static void print_isa(struct seq_file *f, const char *orig_isa)
> +static void print_isa(struct seq_file *f, const char *orig_isa,
> +		      unsigned long cpuid)
>  {
> -	static const char *ext = "mafdcsu";
> +	static const char *mandatory_ext = "mafdcsu";
>  	const char *isa = orig_isa;
>  	const char *e;
> +	char unsupported_isa[26] = {0};
> +	int index = 0;
>  
>  	/*
>  	 * Linux doesn't support rv32e or rv128i, and we only support booting
> @@ -70,27 +74,50 @@ static void print_isa(struct seq_file *f, const char *orig_isa)
>  	isa += 5;
>  
>  	/*
> -	 * Check the rest of the ISA string for valid extensions, printing those
> -	 * we find.  RISC-V ISA strings define an order, so we only print the
> +	 * RISC-V ISA strings define an order, so we only print all the
>  	 * extension bits when they're in order. Hide the supervisor (S)
>  	 * extension from userspace as it's not accessible from there.
> +	 * Throw a warning only if any mandatory extensions are not available
> +	 * and kernel is configured to have that mandatory extensions.
>  	 */
> -	for (e = ext; *e != '\0'; ++e) {
> -		if (isa[0] == e[0]) {
> +	for (e = mandatory_ext; *e != '\0'; ++e) {
> +		if (isa[0] != e[0]) {
> +#if defined(CONFIG_ISA_RISCV_C)

There's no Kconfig option by this name, and we're requiring compressed 
instruction support as part of the RISC-V Linux baseline.  Could you share 
the rationale behind this?  Looks to me like this should be dropped.


> +			if (isa[0] == 'c')
> +				continue;
> +#endif
> +#if defined(CONFIG_FP)
> +			if ((isa[0] == 'f') || (isa[0] == 'd'))
> +				continue;
> +#endif
> +			unsupported_isa[index] = e[0];
> +			index++;
> +		}
> +		/* Only write if part of isa string */
> +		if (isa[0] != '\0') {
>  			if (isa[0] != 's')
>  				seq_write(f, isa, 1);
> -
>  			isa++;
>  		}
>  	}
> +	if (isa[0] != '\0') {
> +		/* Add remainging isa strings */
> +		for (e = isa; *e != '\0'; ++e) {
> +#if !defined(CONFIG_VIRTUALIZATION)
> +			if (e[0] != 'h')
> +#endif
> +				seq_write(f, e, 1);
> +		}
> +	}
>  	seq_puts(f, "\n");
>  
>  	/*
>  	 * If we were given an unsupported ISA in the device tree then print
>  	 * a bit of info describing what went wrong.
>  	 */
> -	if (isa[0] != '\0')
> -		pr_info("unsupported ISA \"%s\" in device tree\n", orig_isa);
> +	if (unsupported_isa[0])
> +		pr_info("unsupported ISA extensions \"%s\" in device tree for cpu [%ld]\n",
> +			unsupported_isa, cpuid);
>  }
>  
>  static void print_mmu(struct seq_file *f, const char *mmu_type)
> @@ -134,7 +161,7 @@ static int c_show(struct seq_file *m, void *v)
>  	seq_printf(m, "processor\t: %lu\n", cpu_id);
>  	seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
>  	if (!of_property_read_string(node, "riscv,isa", &isa))
> -		print_isa(m, isa);
> +		print_isa(m, isa, cpu_id);
>  	if (!of_property_read_string(node, "mmu-type", &mmu))
>  		print_mmu(m, mmu);
>  	if (!of_property_read_string(node, "compatible", &compat)
> -- 
> 2.21.0
> 
> 


- Paul
Atish Patra Aug. 7, 2019, 1:13 a.m. UTC | #2
On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
> On Wed, 31 Jul 2019, Atish Patra wrote:
> 
> > Currently, kernel prints a info warning if any of the extensions
> > from "mafdcsu" is missing in device tree. This is not entirely
> > correct as Linux can boot with "f or d" extensions if kernel is
> > configured accordingly. Moreover, it will continue to print the
> > info string for future extensions such as hypervisor as well which
> > is misleading. /proc/cpuinfo also doesn't print any other
> > extensions
> > except "mafdcsu".
> > 
> > Make sure that info log is only printed only if kernel is
> > configured
> > to have any mandatory extensions but device tree doesn't describe
> > it.
> > All the extensions present in device tree and follow the order
> > described in the RISC-V specification (except 'S') are printed via
> > /proc/cpuinfo always.
> > 
> > Signed-off-by: Atish Patra <atish.patra@wdc.com>
> 
> I tested this patch after dropping the CONFIG_ISA_RISCV_C test (see 
> below).  Running "cat /proc/cpuinfo" generated the following kernel 
> warnings:
>           
> [   73.412626] unsupported ISA extensions "su" in device tree for cpu
> [0]
> [   73.418417] unsupported ISA extensions "su" in device tree for cpu
> [1]
> [   73.424912] unsupported ISA extensions "su" in device tree for cpu
> [2]
> [   73.431425] unsupported ISA extensions "su" in device tree for cpu
> [3]
> 

yeah. I just tested in QEMU. It seems that QEMU has 
"rv64imafdcsu" as isa string in its DT. That's why I never saw this.

> Seems like the "su" should be dropped from mandatory_ext.  What do
> you 
> think?
> 

Yup. As DT binding only mention imafdc, mandatory extensions should
contain only that and just consider "su" extensions are considered as
implicit as we are running Linux. 

Do you think QEMU DT should be updated to reflect that ?

> > ---
> >  arch/riscv/kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++-----
> > ----
> >  1 file changed, 37 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> > index 7da3c6a93abd..9b1d4550fbe6 100644
> > --- a/arch/riscv/kernel/cpu.c
> > +++ b/arch/riscv/kernel/cpu.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/seq_file.h>
> >  #include <linux/of.h>
> >  #include <asm/smp.h>
> > +#include <asm/hwcap.h>
> >  
> >  /*
> >   * Returns the hart ID of the given device tree node, or -ENODEV
> > if the node
> > @@ -46,11 +47,14 @@ int riscv_of_processor_hartid(struct
> > device_node *node)
> >  
> >  #ifdef CONFIG_PROC_FS
> >  
> > -static void print_isa(struct seq_file *f, const char *orig_isa)
> > +static void print_isa(struct seq_file *f, const char *orig_isa,
> > +		      unsigned long cpuid)
> >  {
> > -	static const char *ext = "mafdcsu";
> > +	static const char *mandatory_ext = "mafdcsu";
> >  	const char *isa = orig_isa;
> >  	const char *e;
> > +	char unsupported_isa[26] = {0};
> > +	int index = 0;
> >  
> >  	/*
> >  	 * Linux doesn't support rv32e or rv128i, and we only support
> > booting
> > @@ -70,27 +74,50 @@ static void print_isa(struct seq_file *f, const
> > char *orig_isa)
> >  	isa += 5;
> >  
> >  	/*
> > -	 * Check the rest of the ISA string for valid extensions,
> > printing those
> > -	 * we find.  RISC-V ISA strings define an order, so we only
> > print the
> > +	 * RISC-V ISA strings define an order, so we only print all the
> >  	 * extension bits when they're in order. Hide the supervisor
> > (S)
> >  	 * extension from userspace as it's not accessible from there.
> > +	 * Throw a warning only if any mandatory extensions are not
> > available
> > +	 * and kernel is configured to have that mandatory extensions.
> >  	 */
> > -	for (e = ext; *e != '\0'; ++e) {
> > -		if (isa[0] == e[0]) {
> > +	for (e = mandatory_ext; *e != '\0'; ++e) {
> > +		if (isa[0] != e[0]) {
> > +#if defined(CONFIG_ISA_RISCV_C)
> 
> There's no Kconfig option by this name, and we're requiring
> compressed 

Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.

> instruction support as part of the RISC-V Linux baseline.  Could you
> share 
> the rationale behind this?  

I think I added this check at the config file. Looking at the Kconfig,
RISCV_ISA_C is always enabled. So we can drop this.

Regards,
Atish
> Looks to me like this should be dropped.
> 
> 
> > +			if (isa[0] == 'c')
> > +				continue;
> > +#endif
> > +#if defined(CONFIG_FP)
> > +			if ((isa[0] == 'f') || (isa[0] == 'd'))
> > +				continue;
> > +#endif
> > +			unsupported_isa[index] = e[0];
> > +			index++;
> > +		}
> > +		/* Only write if part of isa string */
> > +		if (isa[0] != '\0') {
> >  			if (isa[0] != 's')
> >  				seq_write(f, isa, 1);
> > -
> >  			isa++;
> >  		}
> >  	}
> > +	if (isa[0] != '\0') {
> > +		/* Add remainging isa strings */
> > +		for (e = isa; *e != '\0'; ++e) {
> > +#if !defined(CONFIG_VIRTUALIZATION)
> > +			if (e[0] != 'h')
> > +#endif
> > +				seq_write(f, e, 1);
> > +		}
> > +	}
> >  	seq_puts(f, "\n");
> >  
> >  	/*
> >  	 * If we were given an unsupported ISA in the device tree then
> > print
> >  	 * a bit of info describing what went wrong.
> >  	 */
> > -	if (isa[0] != '\0')
> > -		pr_info("unsupported ISA \"%s\" in device tree\n",
> > orig_isa);
> > +	if (unsupported_isa[0])
> > +		pr_info("unsupported ISA extensions \"%s\" in device
> > tree for cpu [%ld]\n",
> > +			unsupported_isa, cpuid);
> >  }
> >  
> >  static void print_mmu(struct seq_file *f, const char *mmu_type)
> > @@ -134,7 +161,7 @@ static int c_show(struct seq_file *m, void *v)
> >  	seq_printf(m, "processor\t: %lu\n", cpu_id);
> >  	seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
> >  	if (!of_property_read_string(node, "riscv,isa", &isa))
> > -		print_isa(m, isa);
> > +		print_isa(m, isa, cpu_id);
> >  	if (!of_property_read_string(node, "mmu-type", &mmu))
> >  		print_mmu(m, mmu);
> >  	if (!of_property_read_string(node, "compatible", &compat)
> > -- 
> > 2.21.0
> > 
> > 
> 
> - Paul
Paul Walmsley Aug. 7, 2019, 1:26 a.m. UTC | #3
On Wed, 7 Aug 2019, Atish Patra wrote:

> On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
> 
> > Seems like the "su" should be dropped from mandatory_ext.  What do you 
> > think?
> > 
> 
> Yup. As DT binding only mention imafdc, mandatory extensions should
> contain only that and just consider "su" extensions are considered as
> implicit as we are running Linux. 

Discussing this with Andrew and Palmer, it looks like "su" is currently 
non-compliant.  Section 22.6 of the user-level specification states that 
the "s" character indicates that a longer standard supervisor extension 
name will follow.  So far I don't think any of these have been defined.

> Do you think QEMU DT should be updated to reflect that ?

Yes.

> > There's no Kconfig option by this name, and we're requiring
> > compressed 
> 
> Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.
> 
> > instruction support as part of the RISC-V Linux baseline.  Could you 
> > share the rationale behind this?
> 
> I think I added this check at the config file. Looking at the Kconfig,
> RISCV_ISA_C is always enabled. So we can drop this.

OK great.  Do you want to resend an updated patch, or would you like me to 
fix it up here?

I'll also send a patch to drop CONFIG_RISCV_ISA_C.


- Paul
Palmer Dabbelt Aug. 7, 2019, 3:37 p.m. UTC | #4
On Tue, 06 Aug 2019 18:26:08 PDT (-0700), Paul Walmsley wrote:
> On Wed, 7 Aug 2019, Atish Patra wrote:
>
>> On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
>>
>> > Seems like the "su" should be dropped from mandatory_ext.  What do you
>> > think?
>> >
>>
>> Yup. As DT binding only mention imafdc, mandatory extensions should
>> contain only that and just consider "su" extensions are considered as
>> implicit as we are running Linux.
>
> Discussing this with Andrew and Palmer, it looks like "su" is currently
> non-compliant.  Section 22.6 of the user-level specification states that
> the "s" character indicates that a longer standard supervisor extension
> name will follow.  So far I don't think any of these have been defined.
>
>> Do you think QEMU DT should be updated to reflect that ?
>
> Yes.

https://lists.nongnu.org/archive/html/qemu-riscv/2019-08/msg00141.html

>
>> > There's no Kconfig option by this name, and we're requiring
>> > compressed
>>
>> Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.
>>
>> > instruction support as part of the RISC-V Linux baseline.  Could you
>> > share the rationale behind this?
>>
>> I think I added this check at the config file. Looking at the Kconfig,
>> RISCV_ISA_C is always enabled. So we can drop this.
>
> OK great.  Do you want to resend an updated patch, or would you like me to
> fix it up here?
>
> I'll also send a patch to drop CONFIG_RISCV_ISA_C.
>
>
> - Paul
Atish Patra Aug. 7, 2019, 5:31 p.m. UTC | #5
On Tue, 2019-08-06 at 18:26 -0700, Paul Walmsley wrote:
> On Wed, 7 Aug 2019, Atish Patra wrote:
> 
> > On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
> > 
> > > Seems like the "su" should be dropped from mandatory_ext.  What
> > > do you 
> > > think?
> > > 
> > 
> > Yup. As DT binding only mention imafdc, mandatory extensions should
> > contain only that and just consider "su" extensions are considered
> > as
> > implicit as we are running Linux. 
> 
> Discussing this with Andrew and Palmer, it looks like "su" is
> currently 
> non-compliant.  Section 22.6 of the user-level specification states
> that 
> the "s" character indicates that a longer standard supervisor
> extension 
> name will follow.  So far I don't think any of these have been
> defined.
> 
> > Do you think QEMU DT should be updated to reflect that ?
> 
> Yes.
> 
> > > There's no Kconfig option by this name, and we're requiring
> > > compressed 
> > 
> > Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.
> > 
> > > instruction support as part of the RISC-V Linux baseline.  Could
> > > you 
> > > share the rationale behind this?
> > 
> > I think I added this check at the config file. Looking at the
> > Kconfig,
> > RISCV_ISA_C is always enabled. So we can drop this.
> 
> OK great.  Do you want to resend an updated patch, or would you like
> me to 
> fix it up here?
> 

I am sending the patch right now. We can remove the 'S' mode check as
palmer have already sent the QEMU patch as well, .

Regards,
Atish
> I'll also send a patch to drop CONFIG_RISCV_ISA_C.
> 
> 
> - Paul
Palmer Dabbelt Aug. 7, 2019, 5:42 p.m. UTC | #6
On Wed, 07 Aug 2019 10:31:51 PDT (-0700), Atish Patra wrote:
> On Tue, 2019-08-06 at 18:26 -0700, Paul Walmsley wrote:
>> On Wed, 7 Aug 2019, Atish Patra wrote:
>> 
>> > On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
>> > 
>> > > Seems like the "su" should be dropped from mandatory_ext.  What
>> > > do you 
>> > > think?
>> > > 
>> > 
>> > Yup. As DT binding only mention imafdc, mandatory extensions should
>> > contain only that and just consider "su" extensions are considered
>> > as
>> > implicit as we are running Linux. 
>> 
>> Discussing this with Andrew and Palmer, it looks like "su" is
>> currently 
>> non-compliant.  Section 22.6 of the user-level specification states
>> that 
>> the "s" character indicates that a longer standard supervisor
>> extension 
>> name will follow.  So far I don't think any of these have been
>> defined.
>> 
>> > Do you think QEMU DT should be updated to reflect that ?
>> 
>> Yes.
>> 
>> > > There's no Kconfig option by this name, and we're requiring
>> > > compressed 
>> > 
>> > Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.
>> > 
>> > > instruction support as part of the RISC-V Linux baseline.  Could
>> > > you 
>> > > share the rationale behind this?
>> > 
>> > I think I added this check at the config file. Looking at the
>> > Kconfig,
>> > RISCV_ISA_C is always enabled. So we can drop this.
>> 
>> OK great.  Do you want to resend an updated patch, or would you like
>> me to 
>> fix it up here?
>> 
> 
> I am sending the patch right now. We can remove the 'S' mode check as
> palmer have already sent the QEMU patch as well, .

Looks like I missed the boat for 4.1, though.

> 
> Regards,
> Atish
>> I'll also send a patch to drop CONFIG_RISCV_ISA_C.
>> 
>> 
>> - Paul
>
diff mbox series

Patch

diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 7da3c6a93abd..9b1d4550fbe6 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -7,6 +7,7 @@ 
 #include <linux/seq_file.h>
 #include <linux/of.h>
 #include <asm/smp.h>
+#include <asm/hwcap.h>
 
 /*
  * Returns the hart ID of the given device tree node, or -ENODEV if the node
@@ -46,11 +47,14 @@  int riscv_of_processor_hartid(struct device_node *node)
 
 #ifdef CONFIG_PROC_FS
 
-static void print_isa(struct seq_file *f, const char *orig_isa)
+static void print_isa(struct seq_file *f, const char *orig_isa,
+		      unsigned long cpuid)
 {
-	static const char *ext = "mafdcsu";
+	static const char *mandatory_ext = "mafdcsu";
 	const char *isa = orig_isa;
 	const char *e;
+	char unsupported_isa[26] = {0};
+	int index = 0;
 
 	/*
 	 * Linux doesn't support rv32e or rv128i, and we only support booting
@@ -70,27 +74,50 @@  static void print_isa(struct seq_file *f, const char *orig_isa)
 	isa += 5;
 
 	/*
-	 * Check the rest of the ISA string for valid extensions, printing those
-	 * we find.  RISC-V ISA strings define an order, so we only print the
+	 * RISC-V ISA strings define an order, so we only print all the
 	 * extension bits when they're in order. Hide the supervisor (S)
 	 * extension from userspace as it's not accessible from there.
+	 * Throw a warning only if any mandatory extensions are not available
+	 * and kernel is configured to have that mandatory extensions.
 	 */
-	for (e = ext; *e != '\0'; ++e) {
-		if (isa[0] == e[0]) {
+	for (e = mandatory_ext; *e != '\0'; ++e) {
+		if (isa[0] != e[0]) {
+#if defined(CONFIG_ISA_RISCV_C)
+			if (isa[0] == 'c')
+				continue;
+#endif
+#if defined(CONFIG_FP)
+			if ((isa[0] == 'f') || (isa[0] == 'd'))
+				continue;
+#endif
+			unsupported_isa[index] = e[0];
+			index++;
+		}
+		/* Only write if part of isa string */
+		if (isa[0] != '\0') {
 			if (isa[0] != 's')
 				seq_write(f, isa, 1);
-
 			isa++;
 		}
 	}
+	if (isa[0] != '\0') {
+		/* Add remainging isa strings */
+		for (e = isa; *e != '\0'; ++e) {
+#if !defined(CONFIG_VIRTUALIZATION)
+			if (e[0] != 'h')
+#endif
+				seq_write(f, e, 1);
+		}
+	}
 	seq_puts(f, "\n");
 
 	/*
 	 * If we were given an unsupported ISA in the device tree then print
 	 * a bit of info describing what went wrong.
 	 */
-	if (isa[0] != '\0')
-		pr_info("unsupported ISA \"%s\" in device tree\n", orig_isa);
+	if (unsupported_isa[0])
+		pr_info("unsupported ISA extensions \"%s\" in device tree for cpu [%ld]\n",
+			unsupported_isa, cpuid);
 }
 
 static void print_mmu(struct seq_file *f, const char *mmu_type)
@@ -134,7 +161,7 @@  static int c_show(struct seq_file *m, void *v)
 	seq_printf(m, "processor\t: %lu\n", cpu_id);
 	seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
 	if (!of_property_read_string(node, "riscv,isa", &isa))
-		print_isa(m, isa);
+		print_isa(m, isa, cpu_id);
 	if (!of_property_read_string(node, "mmu-type", &mmu))
 		print_mmu(m, mmu);
 	if (!of_property_read_string(node, "compatible", &compat)