Skip to content

Commit 89793a6

Browse files
RISC-V: Use the extension probing code to enable the FPU
This pull the static key management code for the FPU into the generic ISA extension probing code, so it can be used by other extensions that need static keys. * 'riscv-static_key' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/palmer/linux: riscv: switch has_fpu() to the unified static key mechanism riscv: introduce unified static key mechanism for ISA extensions
2 parents f2906aa + 5d0fbbb commit 89793a6

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

arch/riscv/include/asm/hwcap.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <uapi/asm/hwcap.h>
1313

1414
#ifndef __ASSEMBLY__
15+
#include <linux/jump_label.h>
1516
/*
1617
* This yields a mask that user programs can use to figure out what
1718
* instruction set this cpu supports.
@@ -56,13 +57,37 @@ enum riscv_isa_ext_id {
5657
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
5758
};
5859

60+
/*
61+
* This enum represents the logical ID for each RISC-V ISA extension static
62+
* keys. We can use static key to optimize code path if some ISA extensions
63+
* are available.
64+
*/
65+
enum riscv_isa_ext_key {
66+
RISCV_ISA_EXT_KEY_FPU, /* For 'F' and 'D' */
67+
RISCV_ISA_EXT_KEY_MAX,
68+
};
69+
5970
struct riscv_isa_ext_data {
6071
/* Name of the extension displayed to userspace via /proc/cpuinfo */
6172
char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];
6273
/* The logical ISA extension ID */
6374
unsigned int isa_ext_id;
6475
};
6576

77+
extern struct static_key_false riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_MAX];
78+
79+
static __always_inline int riscv_isa_ext2key(int num)
80+
{
81+
switch (num) {
82+
case RISCV_ISA_EXT_f:
83+
return RISCV_ISA_EXT_KEY_FPU;
84+
case RISCV_ISA_EXT_d:
85+
return RISCV_ISA_EXT_KEY_FPU;
86+
default:
87+
return -EINVAL;
88+
}
89+
}
90+
6691
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
6792

6893
#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)

arch/riscv/include/asm/switch_to.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <linux/jump_label.h>
1010
#include <linux/sched/task_stack.h>
11+
#include <asm/hwcap.h>
1112
#include <asm/processor.h>
1213
#include <asm/ptrace.h>
1314
#include <asm/csr.h>
@@ -56,10 +57,9 @@ static inline void __switch_to_aux(struct task_struct *prev,
5657
fstate_restore(next, task_pt_regs(next));
5758
}
5859

59-
extern struct static_key_false cpu_hwcap_fpu;
6060
static __always_inline bool has_fpu(void)
6161
{
62-
return static_branch_likely(&cpu_hwcap_fpu);
62+
return static_branch_likely(&riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_FPU]);
6363
}
6464
#else
6565
static __always_inline bool has_fpu(void) { return false; }

arch/riscv/kernel/cpufeature.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ unsigned long elf_hwcap __read_mostly;
2727
/* Host ISA bitmap */
2828
static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
2929

30-
#ifdef CONFIG_FPU
31-
__ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu);
32-
#endif
30+
__ro_after_init DEFINE_STATIC_KEY_ARRAY_FALSE(riscv_isa_ext_keys, RISCV_ISA_EXT_KEY_MAX);
31+
EXPORT_SYMBOL(riscv_isa_ext_keys);
3332

3433
/**
3534
* riscv_isa_extension_base() - Get base extension word
@@ -238,10 +237,11 @@ void __init riscv_fill_hwcap(void)
238237
print_str[j++] = (char)('a' + i);
239238
pr_info("riscv: ELF capabilities %s\n", print_str);
240239

241-
#ifdef CONFIG_FPU
242-
if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
243-
static_branch_enable(&cpu_hwcap_fpu);
244-
#endif
240+
for_each_set_bit(i, riscv_isa, RISCV_ISA_EXT_MAX) {
241+
j = riscv_isa_ext2key(i);
242+
if (j >= 0)
243+
static_branch_enable(&riscv_isa_ext_keys[j]);
244+
}
245245
}
246246

247247
#ifdef CONFIG_RISCV_ALTERNATIVE

0 commit comments

Comments
 (0)