diff mbox series

RISC-V: Add support for Ztso

Message ID 20220902034352.8825-1-palmer@rivosinc.com (mailing list archive)
State Changes Requested
Headers show
Series RISC-V: Add support for Ztso | expand

Commit Message

Palmer Dabbelt Sept. 2, 2022, 3:43 a.m. UTC
The Ztso extension was recently frozen, this adds support for running
binaries that depend on TSO on systems that support Ztso.

Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

---

This is very minimaly tested: I can run no-Ztso binaries on both
yes-Ztso and no-Ztso QEMU instances, but I don't have a yes-Ztso
userspace together in order to make sure that works.
---
 arch/riscv/include/asm/elf.h   | 18 ++++++++++++++++--
 arch/riscv/include/asm/hwcap.h |  3 +++
 arch/riscv/kernel/cpu.c        |  1 +
 arch/riscv/kernel/cpufeature.c |  3 +++
 4 files changed, 23 insertions(+), 2 deletions(-)

Comments

Andreas Schwab Sept. 2, 2022, 6:39 a.m. UTC | #1
On Sep 01 2022, Palmer Dabbelt wrote:

> @@ -31,10 +32,23 @@
>  #define ELF_DATA	ELFDATA2LSB
>  
>  /*
> - * This is used to ensure we don't load something for the wrong architecture.
> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
> + * prevent them from even being loaded.
> + */
> +#define EF_RISCV_TSO	0x0010

That should probably be defined in <asm/elf.h>.
Anup Patel Sept. 2, 2022, 6:50 a.m. UTC | #2
On Fri, Sep 2, 2022 at 9:17 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>
> The Ztso extension was recently frozen, this adds support for running
> binaries that depend on TSO on systems that support Ztso.
>
> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
>
> ---
>
> This is very minimaly tested: I can run no-Ztso binaries on both
> yes-Ztso and no-Ztso QEMU instances, but I don't have a yes-Ztso
> userspace together in order to make sure that works.
> ---
>  arch/riscv/include/asm/elf.h   | 18 ++++++++++++++++--
>  arch/riscv/include/asm/hwcap.h |  3 +++
>  arch/riscv/kernel/cpu.c        |  1 +
>  arch/riscv/kernel/cpufeature.c |  3 +++
>  4 files changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
> index 14fc7342490b..7a17d2275b76 100644
> --- a/arch/riscv/include/asm/elf.h
> +++ b/arch/riscv/include/asm/elf.h
> @@ -14,6 +14,7 @@
>  #include <asm/auxvec.h>
>  #include <asm/byteorder.h>
>  #include <asm/cacheinfo.h>
> +#include <asm/hwcap.h>
>
>  /*
>   * These are used to set parameters in the core dumps.
> @@ -31,10 +32,23 @@
>  #define ELF_DATA       ELFDATA2LSB
>
>  /*
> - * This is used to ensure we don't load something for the wrong architecture.
> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
> + * prevent them from even being loaded.
> + */
> +#define EF_RISCV_TSO   0x0010
> +
> +static inline int riscv_elf_tso_ok(long eflags)
> +{
> +       return likely(!(eflags & EF_RISCV_TSO)) || riscv_tso_hw;
> +}
> +
> +/*
> + * This is used to ensure we don't load something for the wrong architecture or
> + * variant.
>   */
>  #define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
> -                          ((x)->e_ident[EI_CLASS] == ELF_CLASS))
> +                          ((x)->e_ident[EI_CLASS] == ELF_CLASS) && \
> +                          riscv_elf_tso_ok((x)->e_flags))
>
>  extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
>  #define compat_elf_check_arch  compat_elf_check_arch
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index 6f59ec64175e..4e1d94c43d51 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -36,6 +36,8 @@ extern unsigned long elf_hwcap;
>  #define RISCV_ISA_EXT_s                ('s' - 'a')
>  #define RISCV_ISA_EXT_u                ('u' - 'a')
>
> +extern bool riscv_tso_hw;
> +
>  /*
>   * Increse this to higher value as kernel support more ISA extensions.
>   */
> @@ -58,6 +60,7 @@ enum riscv_isa_ext_id {
>         RISCV_ISA_EXT_ZICBOM,
>         RISCV_ISA_EXT_ZIHINTPAUSE,
>         RISCV_ISA_EXT_SSTC,
> +       RISCV_ISA_EXT_ZTSO,
>         RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
>  };
>
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 0be8a2403212..d8371c249cc8 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -95,6 +95,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
>         __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
>         __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
>         __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
> +       __RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
>         __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
>         __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
>  };
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 3b5583db9d80..b8ab2b0a9e78 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -25,6 +25,8 @@
>
>  unsigned long elf_hwcap __read_mostly;
>
> +bool riscv_tso_hw __read_mostly;

This is not set anywhere. Maybe riscv_fill_hwcap() should set it ?

> +
>  /* Host ISA bitmap */
>  static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
>
> @@ -204,6 +206,7 @@ void __init riscv_fill_hwcap(void)
>                                 SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
>                                 SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
>                                 SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
> +                               SET_ISA_EXT_MAP("ztso", RISCV_ISA_EXT_ZTSO);
>                         }
>  #undef SET_ISA_EXT_MAP
>                 }
> --
> 2.34.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

Regards,
Anup
Conor Dooley Sept. 16, 2022, 10 a.m. UTC | #3
On 02/09/2022 04:43, Palmer Dabbelt wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> The Ztso extension was recently frozen, this adds support for running
> binaries that depend on TSO on systems that support Ztso.
> 
> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

>   /*
> - * This is used to ensure we don't load something for the wrong architecture.
> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
> + * prevent them from even being loaded.
> + */
> +#define EF_RISCV_TSO   0x0010

My only comment, and I asked this on the other patch too, is why is this
not s/EF/ELF like the other defines in the file?

Thanks,
Conor.
Palmer Dabbelt Sept. 16, 2022, 2:09 p.m. UTC | #4
On Fri, 16 Sep 2022 03:00:35 PDT (-0700), Conor.Dooley@microchip.com wrote:
> On 02/09/2022 04:43, Palmer Dabbelt wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>> 
>> The Ztso extension was recently frozen, this adds support for running
>> binaries that depend on TSO on systems that support Ztso.
>> 
>> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
> 
>>   /*
>> - * This is used to ensure we don't load something for the wrong architecture.
>> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
>> + * prevent them from even being loaded.
>> + */
>> +#define EF_RISCV_TSO   0x0010
> 
> My only comment, and I asked this on the other patch too, is why is this
> not s/EF/ELF like the other defines in the file?

It's EF_RISCV_TSO in the ELF spec, and that's what other ports do (see 
EF_ARM, for example).

> 
> Thanks,
> Conor.
>
Palmer Dabbelt Sept. 16, 2022, 2:09 p.m. UTC | #5
On Thu, 01 Sep 2022 23:39:15 PDT (-0700), schwab@linux-m68k.org wrote:
> On Sep 01 2022, Palmer Dabbelt wrote:
>
>> @@ -31,10 +32,23 @@
>>  #define ELF_DATA	ELFDATA2LSB
>>
>>  /*
>> - * This is used to ensure we don't load something for the wrong architecture.
>> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
>> + * prevent them from even being loaded.
>> + */
>> +#define EF_RISCV_TSO	0x0010
>
> That should probably be defined in <asm/elf.h>.

Sorry, not sure if I'm missing something here?  This is 
<arch/riscv/include/asm/elf.h>, we just don't have any ELF flags defined 
for RISC-V yet in the kernel because we don't use them.
Conor Dooley Sept. 16, 2022, 2:13 p.m. UTC | #6
On 16/09/2022 15:09, Palmer Dabbelt wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, 16 Sep 2022 03:00:35 PDT (-0700), Conor.Dooley@microchip.com wrote:
>> On 02/09/2022 04:43, Palmer Dabbelt wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>
>>> The Ztso extension was recently frozen, this adds support for running
>>> binaries that depend on TSO on systems that support Ztso.
>>>
>>> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
>>
>>>   /*
>>> - * This is used to ensure we don't load something for the wrong architecture.
>>> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
>>> + * prevent them from even being loaded.
>>> + */
>>> +#define EF_RISCV_TSO   0x0010
>>
>> My only comment, and I asked this on the other patch too, is why is this
>> not s/EF/ELF like the other defines in the file?
> 
> It's EF_RISCV_TSO in the ELF spec, and that's what other ports do (see
> EF_ARM, for example).

Right. I did try looking in arm, but I must've missed it. These spec
people really have it out for my OCD...
Palmer Dabbelt Sept. 16, 2022, 2:15 p.m. UTC | #7
On Thu, 01 Sep 2022 23:50:50 PDT (-0700), anup@brainfault.org wrote:
> On Fri, Sep 2, 2022 at 9:17 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>>
>> The Ztso extension was recently frozen, this adds support for running
>> binaries that depend on TSO on systems that support Ztso.
>>
>> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
>>
>> ---
>>
>> This is very minimaly tested: I can run no-Ztso binaries on both
>> yes-Ztso and no-Ztso QEMU instances, but I don't have a yes-Ztso
>> userspace together in order to make sure that works.
>> ---
>>  arch/riscv/include/asm/elf.h   | 18 ++++++++++++++++--
>>  arch/riscv/include/asm/hwcap.h |  3 +++
>>  arch/riscv/kernel/cpu.c        |  1 +
>>  arch/riscv/kernel/cpufeature.c |  3 +++
>>  4 files changed, 23 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
>> index 14fc7342490b..7a17d2275b76 100644
>> --- a/arch/riscv/include/asm/elf.h
>> +++ b/arch/riscv/include/asm/elf.h
>> @@ -14,6 +14,7 @@
>>  #include <asm/auxvec.h>
>>  #include <asm/byteorder.h>
>>  #include <asm/cacheinfo.h>
>> +#include <asm/hwcap.h>
>>
>>  /*
>>   * These are used to set parameters in the core dumps.
>> @@ -31,10 +32,23 @@
>>  #define ELF_DATA       ELFDATA2LSB
>>
>>  /*
>> - * This is used to ensure we don't load something for the wrong architecture.
>> + * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
>> + * prevent them from even being loaded.
>> + */
>> +#define EF_RISCV_TSO   0x0010
>> +
>> +static inline int riscv_elf_tso_ok(long eflags)
>> +{
>> +       return likely(!(eflags & EF_RISCV_TSO)) || riscv_tso_hw;
>> +}
>> +
>> +/*
>> + * This is used to ensure we don't load something for the wrong architecture or
>> + * variant.
>>   */
>>  #define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
>> -                          ((x)->e_ident[EI_CLASS] == ELF_CLASS))
>> +                          ((x)->e_ident[EI_CLASS] == ELF_CLASS) && \
>> +                          riscv_elf_tso_ok((x)->e_flags))
>>
>>  extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
>>  #define compat_elf_check_arch  compat_elf_check_arch
>> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
>> index 6f59ec64175e..4e1d94c43d51 100644
>> --- a/arch/riscv/include/asm/hwcap.h
>> +++ b/arch/riscv/include/asm/hwcap.h
>> @@ -36,6 +36,8 @@ extern unsigned long elf_hwcap;
>>  #define RISCV_ISA_EXT_s                ('s' - 'a')
>>  #define RISCV_ISA_EXT_u                ('u' - 'a')
>>
>> +extern bool riscv_tso_hw;
>> +
>>  /*
>>   * Increse this to higher value as kernel support more ISA extensions.
>>   */
>> @@ -58,6 +60,7 @@ enum riscv_isa_ext_id {
>>         RISCV_ISA_EXT_ZICBOM,
>>         RISCV_ISA_EXT_ZIHINTPAUSE,
>>         RISCV_ISA_EXT_SSTC,
>> +       RISCV_ISA_EXT_ZTSO,
>>         RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
>>  };
>>
>> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
>> index 0be8a2403212..d8371c249cc8 100644
>> --- a/arch/riscv/kernel/cpu.c
>> +++ b/arch/riscv/kernel/cpu.c
>> @@ -95,6 +95,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
>>         __RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
>>         __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
>>         __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
>> +       __RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
>>         __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
>>         __RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
>>  };
>> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
>> index 3b5583db9d80..b8ab2b0a9e78 100644
>> --- a/arch/riscv/kernel/cpufeature.c
>> +++ b/arch/riscv/kernel/cpufeature.c
>> @@ -25,6 +25,8 @@
>>
>>  unsigned long elf_hwcap __read_mostly;
>>
>> +bool riscv_tso_hw __read_mostly;
>
> This is not set anywhere. Maybe riscv_fill_hwcap() should set it ?

Even worse: I got half way through writing the code, realized I should 
have just used a static branch, got distracted, wrote the QEMU code, and 
then forgot about it.  I'll fix it for the v2.

>
>> +
>>  /* Host ISA bitmap */
>>  static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
>>
>> @@ -204,6 +206,7 @@ void __init riscv_fill_hwcap(void)
>>                                 SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
>>                                 SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
>>                                 SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
>> +                               SET_ISA_EXT_MAP("ztso", RISCV_ISA_EXT_ZTSO);
>>                         }
>>  #undef SET_ISA_EXT_MAP
>>                 }
>> --
>> 2.34.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Regards,
> Anup
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 14fc7342490b..7a17d2275b76 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -14,6 +14,7 @@ 
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
 #include <asm/cacheinfo.h>
+#include <asm/hwcap.h>
 
 /*
  * These are used to set parameters in the core dumps.
@@ -31,10 +32,23 @@ 
 #define ELF_DATA	ELFDATA2LSB
 
 /*
- * This is used to ensure we don't load something for the wrong architecture.
+ * Binaries that assume TSO cannot be correctly run on non-TSO systems, so
+ * prevent them from even being loaded.
+ */
+#define EF_RISCV_TSO	0x0010
+
+static inline int riscv_elf_tso_ok(long eflags)
+{
+	return likely(!(eflags & EF_RISCV_TSO)) || riscv_tso_hw;
+}
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture or
+ * variant.
  */
 #define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
-			   ((x)->e_ident[EI_CLASS] == ELF_CLASS))
+			   ((x)->e_ident[EI_CLASS] == ELF_CLASS) && \
+			   riscv_elf_tso_ok((x)->e_flags))
 
 extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
 #define compat_elf_check_arch	compat_elf_check_arch
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 6f59ec64175e..4e1d94c43d51 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -36,6 +36,8 @@  extern unsigned long elf_hwcap;
 #define RISCV_ISA_EXT_s		('s' - 'a')
 #define RISCV_ISA_EXT_u		('u' - 'a')
 
+extern bool riscv_tso_hw;
+
 /*
  * Increse this to higher value as kernel support more ISA extensions.
  */
@@ -58,6 +60,7 @@  enum riscv_isa_ext_id {
 	RISCV_ISA_EXT_ZICBOM,
 	RISCV_ISA_EXT_ZIHINTPAUSE,
 	RISCV_ISA_EXT_SSTC,
+	RISCV_ISA_EXT_ZTSO,
 	RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
 };
 
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 0be8a2403212..d8371c249cc8 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -95,6 +95,7 @@  static struct riscv_isa_ext_data isa_ext_arr[] = {
 	__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
 	__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
 	__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
+	__RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
 	__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
 	__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
 };
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3b5583db9d80..b8ab2b0a9e78 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -25,6 +25,8 @@ 
 
 unsigned long elf_hwcap __read_mostly;
 
+bool riscv_tso_hw __read_mostly;
+
 /* Host ISA bitmap */
 static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
 
@@ -204,6 +206,7 @@  void __init riscv_fill_hwcap(void)
 				SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
 				SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
 				SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
+				SET_ISA_EXT_MAP("ztso", RISCV_ISA_EXT_ZTSO);
 			}
 #undef SET_ISA_EXT_MAP
 		}