Skip to content

Commit

Permalink
Merge patch series "riscv: Per-thread envcfg CSR support"
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
palmer-dabbelt committed Oct 5, 2024
2 parents 9852d85 + 368546e commit 1540def
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 8 deletions.
2 changes: 1 addition & 1 deletion arch/riscv/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
/* Per-cpu ISA extensions. */
extern struct riscv_isainfo hart_isa[NR_CPUS];

void riscv_user_isa_enable(void);
void __init riscv_user_isa_enable(void);

#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
.name = #_name, \
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ struct thread_struct {
unsigned long s[12]; /* s[0]: frame pointer */
struct __riscv_d_ext_state fstate;
unsigned long bad_cause;
unsigned long envcfg;
u32 riscv_v_flags;
u32 vstate_ctrl;
struct __riscv_v_ext_state vstate;
Expand Down
8 changes: 8 additions & 0 deletions arch/riscv/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ static __always_inline bool has_fpu(void) { return false; }
#define __switch_to_fpu(__prev, __next) do { } while (0)
#endif

static inline void __switch_to_envcfg(struct task_struct *next)
{
asm volatile (ALTERNATIVE("nop", "csrw " __stringify(CSR_ENVCFG) ", %0",
0, RISCV_ISA_EXT_XLINUXENVCFG, 1)
:: "r" (next->thread.envcfg) : "memory");
}

extern struct task_struct *__switch_to(struct task_struct *,
struct task_struct *);

Expand Down Expand Up @@ -103,6 +110,7 @@ do { \
__switch_to_vector(__prev, __next); \
if (switch_to_should_flush_icache(__next)) \
local_flush_icache_all(); \
__switch_to_envcfg(__next); \
((last) = __switch_to(__prev, __next)); \
} while (0)

Expand Down
11 changes: 8 additions & 3 deletions arch/riscv/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

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

static bool any_cpu_has_zicboz;

unsigned long elf_hwcap __read_mostly;

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

Expand Down Expand Up @@ -917,10 +920,12 @@ unsigned long riscv_get_elf_hwcap(void)
return hwcap;
}

void riscv_user_isa_enable(void)
void __init riscv_user_isa_enable(void)
{
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
csr_set(CSR_ENVCFG, ENVCFG_CBZE);
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ))
current->thread.envcfg |= ENVCFG_CBZE;
else if (any_cpu_has_zicboz)
pr_warn("Zicboz disabled as it is unavailable on some harts\n");
}

#ifdef CONFIG_RISCV_ALTERNATIVE
Expand Down
2 changes: 0 additions & 2 deletions arch/riscv/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,6 @@ asmlinkage __visible void smp_callin(void)
numa_add_cpu(curr_cpuid);
set_cpu_online(curr_cpuid, true);

riscv_user_isa_enable();

/*
* Remote cache and TLB flushes are ignored while the CPU is offline,
* so flush them both right now just in case.
Expand Down
4 changes: 2 additions & 2 deletions arch/riscv/kernel/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

void suspend_save_csrs(struct suspend_context *context)
{
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG))
context->envcfg = csr_read(CSR_ENVCFG);
context->tvec = csr_read(CSR_TVEC);
context->ie = csr_read(CSR_IE);
Expand All @@ -37,7 +37,7 @@ void suspend_save_csrs(struct suspend_context *context)
void suspend_restore_csrs(struct suspend_context *context)
{
csr_write(CSR_SCRATCH, 0);
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG))
csr_write(CSR_ENVCFG, context->envcfg);
csr_write(CSR_TVEC, context->tvec);
csr_write(CSR_IE, context->ie);
Expand Down

0 comments on commit 1540def

Please sign in to comment.