Skip to content

Commit 1540def

Browse files
Merge patch series "riscv: Per-thread envcfg CSR support"
Samuel Holland <samuel.holland@sifive.com> says: This series (or equivalent) is a prerequisite for both user-mode pointer masking and CFI support, as both of those are per-thread features and are controlled by fields in the envcfg CSR. These patches are based on v1 of the pointer masking series[1], with significant input from both Deepak and Andrew. [1]: https://lore.kernel.org/linux-riscv/20240319215915.832127-6-samuel.holland@sifive.com/ * b4-shazam-merge: riscv: Call riscv_user_isa_enable() only on the boot hart riscv: Add support for per-thread envcfg CSR values riscv: Enable cbo.zero only when all harts support Zicboz ink: https://lore.kernel.org/r/20240814081126.956287-1-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2 parents 9852d85 + 368546e commit 1540def

File tree

6 files changed

+20
-8
lines changed

6 files changed

+20
-8
lines changed

arch/riscv/include/asm/cpufeature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
3131
/* Per-cpu ISA extensions. */
3232
extern struct riscv_isainfo hart_isa[NR_CPUS];
3333

34-
void riscv_user_isa_enable(void);
34+
void __init riscv_user_isa_enable(void);
3535

3636
#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
3737
.name = #_name, \

arch/riscv/include/asm/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct thread_struct {
102102
unsigned long s[12]; /* s[0]: frame pointer */
103103
struct __riscv_d_ext_state fstate;
104104
unsigned long bad_cause;
105+
unsigned long envcfg;
105106
u32 riscv_v_flags;
106107
u32 vstate_ctrl;
107108
struct __riscv_v_ext_state vstate;

arch/riscv/include/asm/switch_to.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ static __always_inline bool has_fpu(void) { return false; }
7070
#define __switch_to_fpu(__prev, __next) do { } while (0)
7171
#endif
7272

73+
static inline void __switch_to_envcfg(struct task_struct *next)
74+
{
75+
asm volatile (ALTERNATIVE("nop", "csrw " __stringify(CSR_ENVCFG) ", %0",
76+
0, RISCV_ISA_EXT_XLINUXENVCFG, 1)
77+
:: "r" (next->thread.envcfg) : "memory");
78+
}
79+
7380
extern struct task_struct *__switch_to(struct task_struct *,
7481
struct task_struct *);
7582

@@ -103,6 +110,7 @@ do { \
103110
__switch_to_vector(__prev, __next); \
104111
if (switch_to_should_flush_icache(__next)) \
105112
local_flush_icache_all(); \
113+
__switch_to_envcfg(__next); \
106114
((last) = __switch_to(__prev, __next)); \
107115
} while (0)
108116

arch/riscv/kernel/cpufeature.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
3030

31+
static bool any_cpu_has_zicboz;
32+
3133
unsigned long elf_hwcap __read_mostly;
3234

3335
/* Host ISA bitmap */
@@ -98,6 +100,7 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
98100
pr_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n");
99101
return -EINVAL;
100102
}
103+
any_cpu_has_zicboz = true;
101104
return 0;
102105
}
103106

@@ -917,10 +920,12 @@ unsigned long riscv_get_elf_hwcap(void)
917920
return hwcap;
918921
}
919922

920-
void riscv_user_isa_enable(void)
923+
void __init riscv_user_isa_enable(void)
921924
{
922-
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
923-
csr_set(CSR_ENVCFG, ENVCFG_CBZE);
925+
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ))
926+
current->thread.envcfg |= ENVCFG_CBZE;
927+
else if (any_cpu_has_zicboz)
928+
pr_warn("Zicboz disabled as it is unavailable on some harts\n");
924929
}
925930

926931
#ifdef CONFIG_RISCV_ALTERNATIVE

arch/riscv/kernel/smpboot.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,6 @@ asmlinkage __visible void smp_callin(void)
233233
numa_add_cpu(curr_cpuid);
234234
set_cpu_online(curr_cpuid, true);
235235

236-
riscv_user_isa_enable();
237-
238236
/*
239237
* Remote cache and TLB flushes are ignored while the CPU is offline,
240238
* so flush them both right now just in case.

arch/riscv/kernel/suspend.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
void suspend_save_csrs(struct suspend_context *context)
1616
{
17-
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
17+
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG))
1818
context->envcfg = csr_read(CSR_ENVCFG);
1919
context->tvec = csr_read(CSR_TVEC);
2020
context->ie = csr_read(CSR_IE);
@@ -37,7 +37,7 @@ void suspend_save_csrs(struct suspend_context *context)
3737
void suspend_restore_csrs(struct suspend_context *context)
3838
{
3939
csr_write(CSR_SCRATCH, 0);
40-
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
40+
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG))
4141
csr_write(CSR_ENVCFG, context->envcfg);
4242
csr_write(CSR_TVEC, context->tvec);
4343
csr_write(CSR_IE, context->ie);

0 commit comments

Comments
 (0)