Skip to content

Commit d5e45e8

Browse files
Merge patch series "riscv: Add vector ISA support"
Andy Chiu <[email protected]> says: This is the v21 patch series for adding Vector extension support in Linux. Please refer to [1] for the introduction of the patchset. The v21 patch series was aimed to solve build issues from v19, provide usage guideline for the prctl interface, and address review comments on v20. Thank every one who has been reviewing, suggesting on the topic. Hope this get a step closer to the final merge. * b4-shazam-merge: (27 commits) selftests: add .gitignore file for RISC-V hwprobe selftests: Test RISC-V Vector prctl interface riscv: Add documentation for Vector riscv: Enable Vector code to be built riscv: detect assembler support for .option arch riscv: Add sysctl to set the default vector rule for new processes riscv: Add prctl controls for userspace vector management riscv: hwcap: change ELF_HWCAP to a function riscv: KVM: Add vector lazy save/restore support riscv: kvm: Add V extension to KVM ISA riscv: prevent stack corruption by reserving task_pt_regs(p) early riscv: signal: validate altstack to reflect Vector riscv: signal: Report signal frame size to userspace via auxv riscv: signal: Add sigcontext save/restore for vector riscv: signal: check fp-reserved words unconditionally riscv: Add ptrace vector support riscv: Allocate user's vector context in the first-use trap riscv: Add task switch support for vector riscv: Introduce struct/helpers to save/restore per-task Vector state riscv: Introduce riscv_v_vsize to record size of Vector context ... Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents 748462b + 1e72695 commit d5e45e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1805
-51
lines changed

Documentation/riscv/hwprobe.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ The following keys are defined:
6464
* :c:macro:`RISCV_HWPROBE_IMA_C`: The C extension is supported, as defined
6565
by version 2.2 of the RISC-V ISA manual.
6666

67+
* :c:macro:`RISCV_HWPROBE_IMA_V`: The V extension is supported, as defined by
68+
version 1.0 of the RISC-V Vector extension manual.
69+
6770
* :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: A bitmask that contains performance
6871
information about the selected set of processors.
6972

Documentation/riscv/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ RISC-V architecture
1010
hwprobe
1111
patch-acceptance
1212
uabi
13+
vector
1314

1415
features
1516

Documentation/riscv/vector.rst

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
=========================================
4+
Vector Extension Support for RISC-V Linux
5+
=========================================
6+
7+
This document briefly outlines the interface provided to userspace by Linux in
8+
order to support the use of the RISC-V Vector Extension.
9+
10+
1. prctl() Interface
11+
---------------------
12+
13+
Two new prctl() calls are added to allow programs to manage the enablement
14+
status for the use of Vector in userspace. The intended usage guideline for
15+
these interfaces is to give init systems a way to modify the availability of V
16+
for processes running under its domain. Calling thess interfaces is not
17+
recommended in libraries routines because libraries should not override policies
18+
configured from the parant process. Also, users must noted that these interfaces
19+
are not portable to non-Linux, nor non-RISC-V environments, so it is discourage
20+
to use in a portable code. To get the availability of V in an ELF program,
21+
please read :c:macro:`COMPAT_HWCAP_ISA_V` bit of :c:macro:`ELF_HWCAP` in the
22+
auxiliary vector.
23+
24+
* prctl(PR_RISCV_V_SET_CONTROL, unsigned long arg)
25+
26+
Sets the Vector enablement status of the calling thread, where the control
27+
argument consists of two 2-bit enablement statuses and a bit for inheritance
28+
mode. Other threads of the calling process are unaffected.
29+
30+
Enablement status is a tri-state value each occupying 2-bit of space in
31+
the control argument:
32+
33+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_DEFAULT`: Use the system-wide default
34+
enablement status on execve(). The system-wide default setting can be
35+
controlled via sysctl interface (see sysctl section below).
36+
37+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_ON`: Allow Vector to be run for the
38+
thread.
39+
40+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_OFF`: Disallow Vector. Executing Vector
41+
instructions under such condition will trap and casuse the termination of the thread.
42+
43+
arg: The control argument is a 5-bit value consisting of 3 parts, and
44+
accessed by 3 masks respectively.
45+
46+
The 3 masks, PR_RISCV_V_VSTATE_CTRL_CUR_MASK,
47+
PR_RISCV_V_VSTATE_CTRL_NEXT_MASK, and PR_RISCV_V_VSTATE_CTRL_INHERIT
48+
represents bit[1:0], bit[3:2], and bit[4]. bit[1:0] accounts for the
49+
enablement status of current thread, and the setting at bit[3:2] takes place
50+
at next execve(). bit[4] defines the inheritance mode of the setting in
51+
bit[3:2].
52+
53+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_CUR_MASK`: bit[1:0]: Account for the
54+
Vector enablement status for the calling thread. The calling thread is
55+
not able to turn off Vector once it has been enabled. The prctl() call
56+
fails with EPERM if the value in this mask is PR_RISCV_V_VSTATE_CTRL_OFF
57+
but the current enablement status is not off. Setting
58+
PR_RISCV_V_VSTATE_CTRL_DEFAULT here takes no effect but to set back
59+
the original enablement status.
60+
61+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_NEXT_MASK`: bit[3:2]: Account for the
62+
Vector enablement setting for the calling thread at the next execve()
63+
system call. If PR_RISCV_V_VSTATE_CTRL_DEFAULT is used in this mask,
64+
then the enablement status will be decided by the system-wide
65+
enablement status when execve() happen.
66+
67+
* :c:macro:`PR_RISCV_V_VSTATE_CTRL_INHERIT`: bit[4]: the inheritance
68+
mode for the setting at PR_RISCV_V_VSTATE_CTRL_NEXT_MASK. If the bit
69+
is set then the following execve() will not clear the setting in both
70+
PR_RISCV_V_VSTATE_CTRL_NEXT_MASK and PR_RISCV_V_VSTATE_CTRL_INHERIT.
71+
This setting persists across changes in the system-wide default value.
72+
73+
Return value:
74+
* 0 on success;
75+
* EINVAL: Vector not supported, invalid enablement status for current or
76+
next mask;
77+
* EPERM: Turning off Vector in PR_RISCV_V_VSTATE_CTRL_CUR_MASK if Vector
78+
was enabled for the calling thread.
79+
80+
On success:
81+
* A valid setting for PR_RISCV_V_VSTATE_CTRL_CUR_MASK takes place
82+
immediately. The enablement status specified in
83+
PR_RISCV_V_VSTATE_CTRL_NEXT_MASK happens at the next execve() call, or
84+
all following execve() calls if PR_RISCV_V_VSTATE_CTRL_INHERIT bit is
85+
set.
86+
* Every successful call overwrites a previous setting for the calling
87+
thread.
88+
89+
* prctl(PR_RISCV_V_GET_CONTROL)
90+
91+
Gets the same Vector enablement status for the calling thread. Setting for
92+
next execve() call and the inheritance bit are all OR-ed together.
93+
94+
Note that ELF programs are able to get the availability of V for itself by
95+
reading :c:macro:`COMPAT_HWCAP_ISA_V` bit of :c:macro:`ELF_HWCAP` in the
96+
auxiliary vector.
97+
98+
Return value:
99+
* a nonnegative value on success;
100+
* EINVAL: Vector not supported.
101+
102+
2. System runtime configuration (sysctl)
103+
-----------------------------------------
104+
105+
To mitigate the ABI impact of expansion of the signal stack, a
106+
policy mechanism is provided to the administrators, distro maintainers, and
107+
developers to control the default Vector enablement status for userspace
108+
processes in form of sysctl knob:
109+
110+
* /proc/sys/abi/riscv_v_default_allow
111+
112+
Writing the text representation of 0 or 1 to this file sets the default
113+
system enablement status for new starting userspace programs. Valid values
114+
are:
115+
116+
* 0: Do not allow Vector code to be executed as the default for new processes.
117+
* 1: Allow Vector code to be executed as the default for new processes.
118+
119+
Reading this file returns the current system default enablement status.
120+
121+
At every execve() call, a new enablement status of the new process is set to
122+
the system default, unless:
123+
124+
* PR_RISCV_V_VSTATE_CTRL_INHERIT is set for the calling process, and the
125+
setting in PR_RISCV_V_VSTATE_CTRL_NEXT_MASK is not
126+
PR_RISCV_V_VSTATE_CTRL_DEFAULT. Or,
127+
128+
* The setting in PR_RISCV_V_VSTATE_CTRL_NEXT_MASK is not
129+
PR_RISCV_V_VSTATE_CTRL_DEFAULT.
130+
131+
Modifying the system default enablement status does not affect the enablement
132+
status of any existing process of thread that do not make an execve() call.

arch/riscv/Kconfig

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,12 @@ config RISCV_DMA_NONCOHERENT
264264
config AS_HAS_INSN
265265
def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
266266

267+
config AS_HAS_OPTION_ARCH
268+
# https://reviews.llvm.org/D123515
269+
def_bool y
270+
depends on $(as-instr, .option arch$(comma) +m)
271+
depends on !$(as-instr, .option arch$(comma) -i)
272+
267273
source "arch/riscv/Kconfig.socs"
268274
source "arch/riscv/Kconfig.errata"
269275

@@ -462,13 +468,44 @@ config RISCV_ISA_SVPBMT
462468

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

471+
config TOOLCHAIN_HAS_V
472+
bool
473+
default y
474+
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
475+
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
476+
depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
477+
depends on AS_HAS_OPTION_ARCH
478+
479+
config RISCV_ISA_V
480+
bool "VECTOR extension support"
481+
depends on TOOLCHAIN_HAS_V
482+
depends on FPU
483+
select DYNAMIC_SIGFRAME
484+
default y
485+
help
486+
Say N here if you want to disable all vector related procedure
487+
in the kernel.
488+
489+
If you don't know what to do here, say Y.
490+
491+
config RISCV_ISA_V_DEFAULT_ENABLE
492+
bool "Enable userspace Vector by default"
493+
depends on RISCV_ISA_V
494+
default y
495+
help
496+
Say Y here if you want to enable Vector in userspace by default.
497+
Otherwise, userspace has to make explicit prctl() call to enable
498+
Vector, or enable it via the sysctl interface.
499+
500+
If you don't know what to do here, say Y.
501+
465502
config TOOLCHAIN_HAS_ZBB
466503
bool
467504
default y
468505
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zbb)
469506
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zbb)
470507
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
471-
depends on AS_IS_GNU
508+
depends on AS_HAS_OPTION_ARCH
472509

473510
config RISCV_ISA_ZBB
474511
bool "Zbb extension support for bit manipulation instructions"

arch/riscv/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
6060
riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
6161
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
6262
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
63+
riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
6364

6465
ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
6566
KBUILD_CFLAGS += -Wa,-misa-spec=2.2
@@ -71,7 +72,10 @@ endif
7172
# Check if the toolchain supports Zihintpause extension
7273
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
7374

74-
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
75+
# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
76+
# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
77+
KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
78+
7579
KBUILD_AFLAGS += -march=$(riscv-march-y)
7680

7781
KBUILD_CFLAGS += -mno-save-restore

arch/riscv/include/asm/csr.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,24 @@
2424
#define SR_FS_CLEAN _AC(0x00004000, UL)
2525
#define SR_FS_DIRTY _AC(0x00006000, UL)
2626

27+
#define SR_VS _AC(0x00000600, UL) /* Vector Status */
28+
#define SR_VS_OFF _AC(0x00000000, UL)
29+
#define SR_VS_INITIAL _AC(0x00000200, UL)
30+
#define SR_VS_CLEAN _AC(0x00000400, UL)
31+
#define SR_VS_DIRTY _AC(0x00000600, UL)
32+
2733
#define SR_XS _AC(0x00018000, UL) /* Extension Status */
2834
#define SR_XS_OFF _AC(0x00000000, UL)
2935
#define SR_XS_INITIAL _AC(0x00008000, UL)
3036
#define SR_XS_CLEAN _AC(0x00010000, UL)
3137
#define SR_XS_DIRTY _AC(0x00018000, UL)
3238

39+
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
40+
3341
#ifndef CONFIG_64BIT
34-
#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */
42+
#define SR_SD _AC(0x80000000, UL) /* FS/VS/XS dirty */
3543
#else
36-
#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
44+
#define SR_SD _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
3745
#endif
3846

3947
#ifdef CONFIG_64BIT
@@ -375,6 +383,12 @@
375383
#define CSR_MVIPH 0x319
376384
#define CSR_MIPH 0x354
377385

386+
#define CSR_VSTART 0x8
387+
#define CSR_VCSR 0xf
388+
#define CSR_VL 0xc20
389+
#define CSR_VTYPE 0xc21
390+
#define CSR_VLENB 0xc22
391+
378392
#ifdef CONFIG_RISCV_M_MODE
379393
# define CSR_STATUS CSR_MSTATUS
380394
# define CSR_IE CSR_MIE

arch/riscv/include/asm/elf.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
6666
* via a bitmap that coorespends to each single-letter ISA extension. This is
6767
* essentially defunct, but will remain for compatibility with userspace.
6868
*/
69-
#define ELF_HWCAP (elf_hwcap & ((1UL << RISCV_ISA_EXT_BASE) - 1))
69+
#define ELF_HWCAP riscv_get_elf_hwcap()
7070
extern unsigned long elf_hwcap;
7171

7272
/*
@@ -105,6 +105,15 @@ do { \
105105
get_cache_size(3, CACHE_TYPE_UNIFIED)); \
106106
NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, \
107107
get_cache_geometry(3, CACHE_TYPE_UNIFIED)); \
108+
/* \
109+
* Should always be nonzero unless there's a kernel bug. \
110+
* If we haven't determined a sensible value to give to \
111+
* userspace, omit the entry: \
112+
*/ \
113+
if (likely(signal_minsigstksz)) \
114+
NEW_AUX_ENT(AT_MINSIGSTKSZ, signal_minsigstksz); \
115+
else \
116+
NEW_AUX_ENT(AT_IGNORE, 0); \
108117
} while (0)
109118
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
110119
struct linux_binprm;

arch/riscv/include/asm/hwcap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#define RISCV_ISA_EXT_m ('m' - 'a')
2323
#define RISCV_ISA_EXT_s ('s' - 'a')
2424
#define RISCV_ISA_EXT_u ('u' - 'a')
25+
#define RISCV_ISA_EXT_v ('v' - 'a')
2526

2627
/*
2728
* These macros represent the logical IDs of each multi-letter RISC-V ISA
@@ -60,6 +61,8 @@
6061

6162
#include <linux/jump_label.h>
6263

64+
unsigned long riscv_get_elf_hwcap(void);
65+
6366
struct riscv_isa_ext_data {
6467
/* Name of the extension displayed to userspace via /proc/cpuinfo */
6568
char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];

arch/riscv/include/asm/insn.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,26 @@
137137
#define RVG_OPCODE_JALR 0x67
138138
#define RVG_OPCODE_JAL 0x6f
139139
#define RVG_OPCODE_SYSTEM 0x73
140+
#define RVG_SYSTEM_CSR_OFF 20
141+
#define RVG_SYSTEM_CSR_MASK GENMASK(12, 0)
142+
143+
/* parts of opcode for RVF, RVD and RVQ */
144+
#define RVFDQ_FL_FS_WIDTH_OFF 12
145+
#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0)
146+
#define RVFDQ_FL_FS_WIDTH_W 2
147+
#define RVFDQ_FL_FS_WIDTH_D 3
148+
#define RVFDQ_LS_FS_WIDTH_Q 4
149+
#define RVFDQ_OPCODE_FL 0x07
150+
#define RVFDQ_OPCODE_FS 0x27
151+
152+
/* parts of opcode for RVV */
153+
#define RVV_OPCODE_VECTOR 0x57
154+
#define RVV_VL_VS_WIDTH_8 0
155+
#define RVV_VL_VS_WIDTH_16 5
156+
#define RVV_VL_VS_WIDTH_32 6
157+
#define RVV_VL_VS_WIDTH_64 7
158+
#define RVV_OPCODE_VL RVFDQ_OPCODE_FL
159+
#define RVV_OPCODE_VS RVFDQ_OPCODE_FS
140160

141161
/* parts of opcode for RVC*/
142162
#define RVC_OPCODE_C0 0x0
@@ -304,6 +324,15 @@ static __always_inline bool riscv_insn_is_branch(u32 code)
304324
(RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \
305325
(RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); })
306326

327+
#define RVG_EXTRACT_SYSTEM_CSR(x) \
328+
({typeof(x) x_ = (x); RV_X(x_, RVG_SYSTEM_CSR_OFF, RVG_SYSTEM_CSR_MASK); })
329+
330+
#define RVFDQ_EXTRACT_FL_FS_WIDTH(x) \
331+
({typeof(x) x_ = (x); RV_X(x_, RVFDQ_FL_FS_WIDTH_OFF, \
332+
RVFDQ_FL_FS_WIDTH_MASK); })
333+
334+
#define RVV_EXRACT_VL_VS_WIDTH(x) RVFDQ_EXTRACT_FL_FS_WIDTH(x)
335+
307336
/*
308337
* Get the immediate from a J-type instruction.
309338
*

arch/riscv/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/spinlock.h>
1616
#include <asm/hwcap.h>
1717
#include <asm/kvm_aia.h>
18+
#include <asm/ptrace.h>
1819
#include <asm/kvm_vcpu_fp.h>
1920
#include <asm/kvm_vcpu_insn.h>
2021
#include <asm/kvm_vcpu_sbi.h>
@@ -145,6 +146,7 @@ struct kvm_cpu_context {
145146
unsigned long sstatus;
146147
unsigned long hstatus;
147148
union __riscv_fp_state fp;
149+
struct __riscv_v_ext_state vector;
148150
};
149151

150152
struct kvm_vcpu_csr {

0 commit comments

Comments
 (0)