Skip to content

Commit 43c16d5

Browse files
Andrew Jonespalmer-dabbelt
authored andcommitted
RISC-V: Enable cbo.zero in usermode
When Zicboz is present, enable its instruction (cbo.zero) in usermode by setting its respective senvcfg bit. We don't bother trying to set this bit per-task, which would also require an interface for tasks to request enabling and/or disabling. Instead, permanently set the bit for each hart which has the extension when bringing it online. This patch also introduces riscv_cpu_has_extension_[un]likely() functions to check a specific hart's ISA bitmap for extensions. Prior to checking the specific hart's bitmap in these functions we try the bitmap which represents the LCD of extensions, but only when we know it will use its optimized, alternatives path by gating its call on CONFIG_RISCV_ALTERNATIVE. When alternatives are used, the compiler ensures that the invocation of the LCD search becomes a constant true or false. When it's true, even the new functions will completely vanish from their callsites. OTOH, when the LCD check is false, we need to do a search of the hart's ISA bitmap. Had we also checked the LCD bitmap without the use of alternatives, then we would have ended up with two bitmap searches instead of one. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Link: https://lore.kernel.org/r/20230918131518.56803-10-ajones@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 181f2a2 commit 43c16d5

6 files changed

Lines changed: 32 additions & 0 deletions

File tree

arch/riscv/include/asm/cpufeature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ DECLARE_PER_CPU(long, misaligned_access_speed);
3131
extern struct riscv_isainfo hart_isa[NR_CPUS];
3232

3333
void check_unaligned_access(int cpu);
34+
void riscv_user_isa_enable(void);
3435

3536
#endif

arch/riscv/include/asm/csr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
#define CSR_SIE 0x104
276276
#define CSR_STVEC 0x105
277277
#define CSR_SCOUNTEREN 0x106
278+
#define CSR_SENVCFG 0x10a
278279
#define CSR_SSCRATCH 0x140
279280
#define CSR_SEPC 0x141
280281
#define CSR_SCAUSE 0x142

arch/riscv/include/asm/hwcap.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#ifndef __ASSEMBLY__
7171

7272
#include <linux/jump_label.h>
73+
#include <asm/cpufeature.h>
7374

7475
unsigned long riscv_get_elf_hwcap(void);
7576

@@ -137,6 +138,21 @@ riscv_has_extension_unlikely(const unsigned long ext)
137138
return true;
138139
}
139140

141+
static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext)
142+
{
143+
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_likely(ext))
144+
return true;
145+
146+
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
147+
}
148+
149+
static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext)
150+
{
151+
if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_unlikely(ext))
152+
return true;
153+
154+
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
155+
}
140156
#endif
141157

142158
#endif /* _ASM_RISCV_HWCAP_H */

arch/riscv/kernel/cpufeature.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,12 @@ static int check_unaligned_access_boot_cpu(void)
653653

654654
arch_initcall(check_unaligned_access_boot_cpu);
655655

656+
void riscv_user_isa_enable(void)
657+
{
658+
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
659+
csr_set(CSR_SENVCFG, ENVCFG_CBZE);
660+
}
661+
656662
#ifdef CONFIG_RISCV_ALTERNATIVE
657663
/*
658664
* Alternative patch sites consider 48 bits when determining when to patch

arch/riscv/kernel/setup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <asm/acpi.h>
2727
#include <asm/alternative.h>
2828
#include <asm/cacheflush.h>
29+
#include <asm/cpufeature.h>
2930
#include <asm/cpu_ops.h>
3031
#include <asm/early_ioremap.h>
3132
#include <asm/pgtable.h>
@@ -314,10 +315,13 @@ void __init setup_arch(char **cmdline_p)
314315
riscv_fill_hwcap();
315316
init_rt_signal_env();
316317
apply_boot_alternatives();
318+
317319
if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
318320
riscv_isa_extension_available(NULL, ZICBOM))
319321
riscv_noncoherent_supported();
320322
riscv_set_dma_cache_alignment();
323+
324+
riscv_user_isa_enable();
321325
}
322326

323327
static int __init topology_init(void)

arch/riscv/kernel/smpboot.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <linux/of.h>
2626
#include <linux/sched/task_stack.h>
2727
#include <linux/sched/mm.h>
28+
29+
#include <asm/cpufeature.h>
2830
#include <asm/cpu_ops.h>
2931
#include <asm/cpufeature.h>
3032
#include <asm/irq.h>
@@ -253,6 +255,8 @@ asmlinkage __visible void smp_callin(void)
253255
elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
254256
}
255257

258+
riscv_user_isa_enable();
259+
256260
/*
257261
* Remote TLB flushes are ignored while the CPU is offline, so emit
258262
* a local TLB flush right now just in case.

0 commit comments

Comments
 (0)