[PATCH v2] riscv: hwprobe: allow querying available RISCV_HWPROBE_KEY_IMA_EXT_0 bits
Alexandre Ghiti
alex at ghiti.fr
Thu Aug 14 04:22:46 PDT 2025
On 8/14/25 12:32, Paris Oplopoios wrote:
> Hello Alexandre,
>
>> trying to figure out if an extension is available will likely result in a SIGILL, so that will kill your application
> SIGILL can be captured with a signal handler and extension support can
> be checked this way. Not all extensions can be detected using this
> method, and it's much more straightforward to ask the kernel.
>
>> Why don't you check the kernel config or even the hwprobe.h header? Since basically here, you use a syscall to return an information that is visible already from userspace.
> To give an example, imagine a new extension Znew comes out, it
> occupies the bit 1<<59. Let's say my kernel version was built with
> support for detecting it and yours wasn't, but we both have the same
> hardware. I compile a binary of a program that wants to do runtime
> extension detection and I want to distribute it.
>
> If I use the config or the hwprobe.h header during compilation time,
> the compiled binary is assuming that both mine and your system have
> this new bit. So when my program tries to detect it, it will find it
> on my hardware but not yours. That's because my kernel was built to
> support this bit in hwprobe but yours wasn't.
>
> But in reality your hardware does have the extension. However, how
> will my program differentiate from "doesn't have an extension" and
> "kernel version not new enough"? Maybe I'd like to know that the
> kernel doesn't have the bit, and notify the user with an "update your
> kernel" message. Maybe I'd like to do the fallback SIGILL extension
> detection instead.
What about parsing the isa string? And do you have a real usecase in
mind? I mean which project would benefit from this?
>
> PS: I'm assuming you meant checking config/hwprobe.h at compilation
> time. If you meant parsing it at runtime, that simply wouldn't be
> possible on all environments (think chroots).
>
> On Thu, 14 Aug 2025 at 12:37, Alexandre Ghiti <alex at ghiti.fr> wrote:
>> Hi Paris,
>>
>> On 8/13/25 20:05, offtkp wrote:
>>> When probing for extensions using RISCV_HWPROBE_KEY_IMA_EXT_0, a missing
>>> bit in the resulting bitmask means the extension is not available or the
>>> kernel is not recent enough to support the bit. Currently, there's no
>>> way to differentiate between the two.
>>>
>>> This adds a new riscv_hwprobe key, RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL,
>>> which returns a bitmask of all the queryable extensions supported by the
>>> kernel in RISCV_HWPROBE_KEY_IMA_EXT_0. This can allow programs to use a
>>> fallback extension detection method when the bit they want to query is
>>> not available in the kernel they are running on.
>>
>> Admittedly, I'm not convinced this is necessary. As you showed in your
>> v1, trying to figure out if an extension is available will likely result
>> in a SIGILL, so that will kill your application. Why don't you check the
>> kernel config or even the hwprobe.h header? Since basically here, you
>> use a syscall to return an information that is visible already from
>> userspace.
>>
>> But maybe I'm missing an interesting usecase, just let me know.
>>
>> Thanks,
>>
>> Alex
>>
>>
>>> Signed-off-by: offtkp <parisoplop at gmail.com>
>>> ---
>>> Changes in v2:
>>> - convert spaces to tabs
>>> - use git format-patch to create diff
>>>
>>> Documentation/arch/riscv/hwprobe.rst | 5 ++++-
>>> arch/riscv/include/asm/hwprobe.h | 3 ++-
>>> arch/riscv/include/uapi/asm/hwprobe.h | 2 ++
>>> arch/riscv/kernel/sys_hwprobe.c | 4 ++++
>>> 4 files changed, 12 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
>>> index 2aa9be272d5d..6d77def0a46e 100644
>>> --- a/Documentation/arch/riscv/hwprobe.rst
>>> +++ b/Documentation/arch/riscv/hwprobe.rst
>>> @@ -360,4 +360,7 @@ The following keys are defined:
>>>
>>> * :c:macro:`RISCV_HWPROBE_VENDOR_EXT_XSFVFWMACCQQQ`: The Xsfvfwmaccqqq
>>> vendor extension is supported in version 1.0 of Matrix Multiply Accumulate
>>> - Instruction Extensions Specification.
>>> \ No newline at end of file
>>> + Instruction Extensions Specification.
>>> +
>>> +* :c:macro:`RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL`: A bitmask containing the extensions
>>> + that can be probed using the :c:macro:`RISCV_HWPROBE_KEY_IMA_EXT_0` key.
>>> \ No newline at end of file
>>> diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
>>> index 7fe0a379474a..501d49b7a02a 100644
>>> --- a/arch/riscv/include/asm/hwprobe.h
>>> +++ b/arch/riscv/include/asm/hwprobe.h
>>> @@ -8,7 +8,8 @@
>>>
>>> #include <uapi/asm/hwprobe.h>
>>>
>>> -#define RISCV_HWPROBE_MAX_KEY 13
>>> +#define RISCV_HWPROBE_MAX_KEY 14
>>> +#define RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL_VALUE ((1ULL << 59) - 1)
>>>
>>> static inline bool riscv_hwprobe_key_is_valid(__s64 key)
>>> {
>>> diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
>>> index aaf6ad970499..a3b92df4dc05 100644
>>> --- a/arch/riscv/include/uapi/asm/hwprobe.h
>>> +++ b/arch/riscv/include/uapi/asm/hwprobe.h
>>> @@ -82,6 +82,7 @@ struct riscv_hwprobe {
>>> #define RISCV_HWPROBE_EXT_ZAAMO (1ULL << 56)
>>> #define RISCV_HWPROBE_EXT_ZALRSC (1ULL << 57)
>>> #define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
>>> +/* Change RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL_VALUE when adding items. */
>>> #define RISCV_HWPROBE_KEY_CPUPERF_0 5
>>> #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
>>> #define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
>>> @@ -106,6 +107,7 @@ struct riscv_hwprobe {
>>> #define RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 11
>>> #define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE 12
>>> #define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0 13
>>> +#define RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL 14
>>> /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
>>>
>>> /* Flags */
>>> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
>>> index 0b170e18a2be..40e7fa5f85f3 100644
>>> --- a/arch/riscv/kernel/sys_hwprobe.c
>>> +++ b/arch/riscv/kernel/sys_hwprobe.c
>>> @@ -310,6 +310,10 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
>>> hwprobe_isa_vendor_ext_thead_0(pair, cpus);
>>> break;
>>>
>>> + case RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL:
>>> + pair->value = RISCV_HWPROBE_KEY_IMA_EXT_0_AVAIL_VALUE;
>>> + break;
>>> +
>>> /*
>>> * For forward compatibility, unknown keys don't fail the whole
>>> * call, but get their element key set to -1 and value set to 0
>>>
>>> _______________________________________________
>>> linux-riscv mailing list
>>> linux-riscv at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-riscv
More information about the linux-riscv
mailing list