Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv: Support XUANTIE extended CSR save/restore during task switching #206

Merged
merged 1 commit into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,18 @@ config XUANTIE_ISA

If unsure, say N.

config XUANTIE_CSR_EXT
bool "XUANTIE_CSR_EXT (FXCR, UTNMODE)"
default y
depends on FPU
help
This config enable XUANTIE U-mode Extended Control and Status Register.
These CSRs may be set to different values ​​by the user in different processes, and
can be saved and restored when switching tasks in combination with dts.
Please refer to the XUANTIE processor user manual for CSR definitions.

If you don't know what to do here, say Y.

menu "Kernel features"

source "kernel/Kconfig.hz"
Expand Down
6 changes: 6 additions & 0 deletions arch/riscv/include/asm/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@
#define CSR_XRLENB 0xcc1
#define CSR_XMISA 0xcc2

/* XUANTIE Extended Control and Status Register */
#ifdef CONFIG_XUANTIE_CSR_EXT
#define CSR_FXCR 0x800
#define CSR_UTNMODE 0x8da
#endif

#ifdef CONFIG_RISCV_M_MODE
# define CSR_STATUS CSR_MSTATUS
# define CSR_IE CSR_MIE
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/include/asm/hwcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
#define RISCV_ISA_EXT_ZIHPM 42
#define RISCV_ISA_EXT_ZAWRS 85

#define RISCV_ISA_EXT_XTHEADFXCR 123
#define RISCV_ISA_EXT_XTHEADUTNMODE 124
#define RISCV_ISA_EXT_XTHEADVECTOR 125
#define RISCV_ISA_EXT_XTHEADMATRIX 126

Expand Down
4 changes: 4 additions & 0 deletions arch/riscv/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ struct thread_struct {
unsigned long vstate_ctrl;
struct __riscv_v_ext_state vstate;
struct __riscv_m_ext_state mstate;
#ifdef CONFIG_XUANTIE_CSR_EXT
u32 fxcr;
u32 utnmode;
#endif
} __attribute__((__aligned__(sizeof(xlen_t))));

/* Whitelist the fstate from the task_struct for hardened usercopy */
Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/csr.h>
#include <asm/xuantie_csr_ext.h>

#ifdef CONFIG_FPU
extern void __fstate_save(struct task_struct *save_to);
Expand Down Expand Up @@ -83,6 +84,8 @@ do { \
__switch_to_vector(__prev, __next); \
if (has_matrix()) \
__switch_to_matrix(__prev, __next); \
if (has_xuantie_csr_ext()) \
__switch_to_xuantie_csr_ext(__prev, __next); \
((last) = __switch_to(__prev, __next)); \
} while (0)

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

#ifdef CONFIG_XUANTIE_CSR_EXT

#include <asm/csr.h>
#include <asm/hwcap.h>
#include <linux/sched.h>

static __always_inline bool has_xuantie_csr_ext(void)
{
return riscv_has_extension_unlikely(RISCV_ISA_EXT_XTHEADFXCR) |
riscv_has_extension_unlikely(RISCV_ISA_EXT_XTHEADUTNMODE);
}

static inline void __switch_to_xuantie_csr_ext(struct task_struct *prev,
struct task_struct *next)
{
if (riscv_has_extension_likely(RISCV_ISA_EXT_XTHEADFXCR)) {
csr_set(CSR_STATUS, SR_FS);
prev->thread.fxcr = csr_read(CSR_FXCR);
csr_write(CSR_FXCR, next->thread.fxcr);
csr_clear(CSR_STATUS, SR_FS);
}

if (riscv_has_extension_likely(RISCV_ISA_EXT_XTHEADUTNMODE)) {
prev->thread.utnmode = csr_read(CSR_UTNMODE);
csr_write(CSR_UTNMODE, next->thread.utnmode);
}
}
#else

static __always_inline bool has_xuantie_csr_ext(void) { return false; }
#define __switch_to_xuantie_csr_ext(__prev, __next) do {} while (0)

#endif /* CONFIG_XUANTIE_CSR_EXT */
#endif /* _ASM_XUANTIE_CSR_EXT_H */
2 changes: 2 additions & 0 deletions arch/riscv/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
__RISCV_ISA_EXT_DATA(xtheadmatrix, RISCV_ISA_EXT_XTHEADMATRIX),
__RISCV_ISA_EXT_DATA(xtheadvector, RISCV_ISA_EXT_XTHEADVECTOR),
__RISCV_ISA_EXT_DATA(xtheadfxcr, RISCV_ISA_EXT_XTHEADFXCR),
__RISCV_ISA_EXT_DATA(xtheadutnmode, RISCV_ISA_EXT_XTHEADUTNMODE),
};

const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
Expand Down
Loading