Skip to content

Commit

Permalink
riscv: hwprobe: Add thead vendor extension probing
Browse files Browse the repository at this point in the history
Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
vendor extension.

This new key will allow userspace code to probe for which thead vendor
extensions are supported. This API is modeled to be consistent with
RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
corresponding to a supported thead vendor extension of the cpumask set.
Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
to determine all of the supported thead vendor extensions in one call.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Reviewed-by: Evan Green <evan@rivosinc.com>
Tested-by: Yangyu Chen <cyy@cyyself.name>
Link: https://lore.kernel.org/r/20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
  • Loading branch information
Charlie Jenkins authored and Palmer Dabbelt committed Jan 18, 2025
1 parent d863910 commit a5ea53d
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 3 deletions.
5 changes: 3 additions & 2 deletions arch/riscv/include/asm/hwprobe.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright 2023 Rivos, Inc
* Copyright 2023-2024 Rivos, Inc
*/

#ifndef _ASM_HWPROBE_H
#define _ASM_HWPROBE_H

#include <uapi/asm/hwprobe.h>

#define RISCV_HWPROBE_MAX_KEY 10
#define RISCV_HWPROBE_MAX_KEY 11

static inline bool riscv_hwprobe_key_is_valid(__s64 key)
{
Expand All @@ -21,6 +21,7 @@ static inline bool hwprobe_key_is_bitmask(__s64 key)
case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
case RISCV_HWPROBE_KEY_IMA_EXT_0:
case RISCV_HWPROBE_KEY_CPUPERF_0:
case RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0:
return true;
}

Expand Down
19 changes: 19 additions & 0 deletions arch/riscv/include/asm/vendor_extensions/thead_hwprobe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_HWPROBE_H
#define _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_HWPROBE_H

#include <linux/cpumask.h>

#include <uapi/asm/hwprobe.h>

#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair, const struct cpumask *cpus);
#else
static inline void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair,
const struct cpumask *cpus)
{
pair->value = 0;
}
#endif

#endif
37 changes: 37 additions & 0 deletions arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2024 Rivos, Inc
*/

#ifndef _ASM_RISCV_SYS_HWPROBE_H
#define _ASM_RISCV_SYS_HWPROBE_H

#include <asm/cpufeature.h>

#define VENDOR_EXT_KEY(ext) \
do { \
if (__riscv_isa_extension_available(isainfo->isa, RISCV_ISA_VENDOR_EXT_##ext)) \
pair->value |= RISCV_HWPROBE_VENDOR_EXT_##ext; \
else \
missing |= RISCV_HWPROBE_VENDOR_EXT_##ext; \
} while (false)

/*
* Loop through and record extensions that 1) anyone has, and 2) anyone
* doesn't have.
*
* _extension_checks is an arbitrary C block to set the values of pair->value
* and missing. It should be filled with VENDOR_EXT_KEY expressions.
*/
#define VENDOR_EXTENSION_SUPPORTED(pair, cpus, per_hart_vendor_bitmap, _extension_checks) \
do { \
int cpu; \
u64 missing = 0; \
for_each_cpu(cpu, (cpus)) { \
struct riscv_isavendorinfo *isainfo = &(per_hart_vendor_bitmap)[cpu]; \
_extension_checks \
} \
(pair)->value &= ~missing; \
} while (false) \

#endif /* _ASM_RISCV_SYS_HWPROBE_H */
3 changes: 2 additions & 1 deletion arch/riscv/include/uapi/asm/hwprobe.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright 2023 Rivos, Inc
* Copyright 2023-2024 Rivos, Inc
*/

#ifndef _UAPI_ASM_HWPROBE_H
Expand Down Expand Up @@ -94,6 +94,7 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW 2
#define RISCV_HWPROBE_MISALIGNED_VECTOR_FAST 3
#define RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED 4
#define RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 11
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */

/* Flags */
Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/include/uapi/asm/vendor/thead.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */

#define RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR (1 << 0)
5 changes: 5 additions & 0 deletions arch/riscv/kernel/sys_hwprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/vector.h>
#include <asm/vendor_extensions/thead_hwprobe.h>
#include <vdso/vsyscall.h>


Expand Down Expand Up @@ -286,6 +287,10 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
pair->value = riscv_timebase;
break;

case RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0:
hwprobe_isa_vendor_ext_thead_0(pair, cpus);
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
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/kernel/vendor_extensions/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_ANDES) += andes.o
obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_THEAD) += thead.o
obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_THEAD) += thead_hwprobe.o
19 changes: 19 additions & 0 deletions arch/riscv/kernel/vendor_extensions/thead_hwprobe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only

#include <asm/vendor_extensions/thead.h>
#include <asm/vendor_extensions/thead_hwprobe.h>
#include <asm/vendor_extensions/vendor_hwprobe.h>

#include <linux/cpumask.h>
#include <linux/types.h>

#include <uapi/asm/hwprobe.h>
#include <uapi/asm/vendor/thead.h>

void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair, const struct cpumask *cpus)
{
VENDOR_EXTENSION_SUPPORTED(pair, cpus,
riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap, {
VENDOR_EXT_KEY(XTHEADVECTOR);
});
}

0 comments on commit a5ea53d

Please sign in to comment.