All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v4 00/13] riscv: Add vector ISA support
@ 2020-05-26  7:02 Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size Greentime Hu
                   ` (13 more replies)
  0 siblings, 14 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

This patchset is based on Guo Ren's v3 patchset to add dynamic vlen vector
support for all different kinds of vector length in riscv. To make this
happened we defined a new __riscv_v_state in sigcontext to save the vector
related registers. The datap pointer will be allocated dynamically in
kernel space and it will be put right after the __riscv_v_state data
structure to save all the vector registers in signal handler stack for user
space. So does the implementation in ptrace, they will be saved in ubuf
in which we put the __riscv_v_state data structure and datap pointer right
after it for vector registers. This patchset also fixes several bugs for
vector lazy save/restore and vtype not saving issue. It also adds new CSR
support for vector based on the 0.9 vector spec and clean up some unused
macros.

This patchset is rebased to v5.7-rc4 and it is tested by running several
vector programs simultaneously. It also can get the correct ucontext_t in
signal handler and restore correct context after sigreturn. It is also
tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
virt machine of qemu-system-riscv32 and qemu-system-riscv64 provided by
Zhiwei Lui.

Since the vector spec is under developing, there might still need some
changes. For example the vle.v/vse.v instructions will be replaced with
proper instructions. The reason that I don't replace the instruction in
this patchset is because that the Qemu doesn't fully support 0.9 spec yet.
I have no simulator to test. We also like to discuss the default setting of
MINSIGSTKSZ and SIGSTKSZ. They might also need to set a proper number. They
are 2048 and 8096 now. Since the stack in signal will be reserved for
ucontext and the vector registers might be larger and larger someday, these
two macros will need to be defined as a proper value or maybe we should
provide a better mechanism to provide user to get a better default signal
stack size.


 [1] https://github.com/romanheros/qemu/tree/linux-vector-dev
 [2] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
 [3] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc

---
Changelog V4
 - Support dynamic vlen
 - Fix bugs: lazy save/resotre, not saving vtype
 - Update VS bit offset based on latest vector spec
 - Add new vector csr based on latest vector spec
 - Code refine and removed unused macros

Changelog V3
 - Rebase linux-5.6-rc3 and tested with qemu
 - Seperate patches with Anup's advice
 - Give out a ABI puzzle with unlimited vlen

Changelog V2
 - Fixup typo "vecotr, fstate_save->vstate_save".
 - Fixup wrong saved registers' length in vector.S.
 - Seperate unrelated patches from this one.

Greentime Hu (1):
  ptrace: Use regset_size() for dynamic regset size.

Guo Ren (11):
  riscv: Separate patch for cflags and aflags
  riscv: Rename __switch_to_aux -> fpu
  riscv: Extending cpufeature.c to detect V-extension
  riscv: Add new csr defines related to vector extension
  riscv: Add vector feature to compile
  riscv: Add has_vector/riscv_vsize to save vector features.
  riscv: Reset vector register
  riscv: Add vector struct and assembler definitions
  riscv: Add task switch support for vector
  riscv: Add ptrace vector support
  riscv: Add sigcontext save/restore for vector

Vincent Chen (1):
  riscv: signal: Report signal frame size to userspace via auxv

 arch/riscv/Kconfig                       |   9 ++
 arch/riscv/Makefile                      |  19 ++--
 arch/riscv/include/asm/csr.h             |  16 +++-
 arch/riscv/include/asm/elf.h             |  17 +++-
 arch/riscv/include/asm/processor.h       |   3 +
 arch/riscv/include/asm/switch_to.h       |  77 ++++++++++++++-
 arch/riscv/include/uapi/asm/auxvec.h     |   2 +
 arch/riscv/include/uapi/asm/elf.h        |   1 +
 arch/riscv/include/uapi/asm/hwcap.h      |   1 +
 arch/riscv/include/uapi/asm/ptrace.h     |  13 +++
 arch/riscv/include/uapi/asm/sigcontext.h |   2 +
 arch/riscv/kernel/Makefile               |   1 +
 arch/riscv/kernel/asm-offsets.c          |   8 ++
 arch/riscv/kernel/cpufeature.c           |  15 ++-
 arch/riscv/kernel/entry.S                |   2 +-
 arch/riscv/kernel/head.S                 |  49 +++++++++-
 arch/riscv/kernel/process.c              |  40 ++++++++
 arch/riscv/kernel/ptrace.c               | 114 +++++++++++++++++++++++
 arch/riscv/kernel/setup.c                |   5 +
 arch/riscv/kernel/signal.c               | 108 ++++++++++++++++++++-
 arch/riscv/kernel/vector.S               |  84 +++++++++++++++++
 include/uapi/linux/elf.h                 |   1 +
 kernel/ptrace.c                          |  11 ++-
 23 files changed, 573 insertions(+), 25 deletions(-)
 create mode 100644 arch/riscv/kernel/vector.S

-- 
2.26.2


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26 14:00     ` Oleg Nesterov
  2020-05-26  7:02 ` [RFC PATCH v4 02/13] riscv: Separate patch for cflags and aflags Greentime Hu
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

It uses regset_size() instead of using regset->n and regset->size directly.
In this case, it will call the get_size() ported by arch dynamically to
support dynamic regset size case.

Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
---
 kernel/ptrace.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 43d6179508d6..6877105e1b1e 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
 	const struct user_regset_view *view = task_user_regset_view(task);
 	const struct user_regset *regset = find_regset(view, type);
 	int regset_no;
+	unsigned int size;
 
-	if (!regset || (kiov->iov_len % regset->size) != 0)
+	if (!regset)
 		return -EINVAL;
 
 	regset_no = regset - view->regsets;
-	kiov->iov_len = min(kiov->iov_len,
-			    (__kernel_size_t) (regset->n * regset->size));
+	size = regset_size(task, regset);
+
+	if ((kiov->iov_len % size) != 0)
+		return -EINVAL;
+
+	kiov->iov_len = min(kiov->iov_len, (__kernel_size_t) size);
 
 	if (req == PTRACE_GETREGSET)
 		return copy_regset_to_user(task, view, regset_no, 0,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 02/13] riscv: Separate patch for cflags and aflags
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 03/13] riscv: Rename __switch_to_aux -> fpu Greentime Hu
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

From: Guo Ren <ren_guo@c-sky.com>

Use "subst fd" in Makefile is a hack way and it's not convenient
to add new ISA feature. Just separate them into riscv-march-cflags
and riscv-march-aflags.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/Makefile | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index fb6e37db836d..957d064bead0 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -37,12 +37,18 @@ else
 endif
 
 # ISA string setting
-riscv-march-$(CONFIG_ARCH_RV32I)	:= rv32ima
-riscv-march-$(CONFIG_ARCH_RV64I)	:= rv64ima
-riscv-march-$(CONFIG_FPU)		:= $(riscv-march-y)fd
-riscv-march-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-y)c
-KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
-KBUILD_AFLAGS += -march=$(riscv-march-y)
+riscv-march-cflags-$(CONFIG_ARCH_RV32I)		:= rv32ima
+riscv-march-cflags-$(CONFIG_ARCH_RV64I)		:= rv64ima
+riscv-march-$(CONFIG_FPU)			:= $(riscv-march-y)fd
+riscv-march-cflags-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-cflags-y)c
+
+riscv-march-aflags-$(CONFIG_ARCH_RV32I)		:= rv32ima
+riscv-march-aflags-$(CONFIG_ARCH_RV64I)		:= rv64ima
+riscv-march-aflags-$(CONFIG_FPU)		:= $(riscv-march-aflags-y)fd
+riscv-march-aflags-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-aflags-y)c
+
+KBUILD_CFLAGS += -march=$(riscv-march-cflags-y)
+KBUILD_AFLAGS += -march=$(riscv-march-aflags-y)
 
 KBUILD_CFLAGS += -mno-save-restore
 KBUILD_CFLAGS += -DCONFIG_PAGE_OFFSET=$(CONFIG_PAGE_OFFSET)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 03/13] riscv: Rename __switch_to_aux -> fpu
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 02/13] riscv: Separate patch for cflags and aflags Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 04/13] riscv: Extending cpufeature.c to detect V-extension Greentime Hu
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg
  Cc: Anup Patel

From: Guo Ren <guoren@linux.alibaba.com>

From: Guo Ren <ren_guo@c-sky.com>

The name of __switch_to_aux is not clear and rename it with the
determine function: __switch_to_fpu. Next we could add other regs'
switch.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
 arch/riscv/include/asm/switch_to.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index 407bcc96a710..b9234e7178d0 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -44,7 +44,7 @@ static inline void fstate_restore(struct task_struct *task,
 	}
 }
 
-static inline void __switch_to_aux(struct task_struct *prev,
+static inline void __switch_to_fpu(struct task_struct *prev,
 				   struct task_struct *next)
 {
 	struct pt_regs *regs;
@@ -60,7 +60,7 @@ extern bool has_fpu;
 #define has_fpu false
 #define fstate_save(task, regs) do { } while (0)
 #define fstate_restore(task, regs) do { } while (0)
-#define __switch_to_aux(__prev, __next) do { } while (0)
+#define __switch_to_fpu(__prev, __next) do { } while (0)
 #endif
 
 extern struct task_struct *__switch_to(struct task_struct *,
@@ -71,7 +71,7 @@ do {							\
 	struct task_struct *__prev = (prev);		\
 	struct task_struct *__next = (next);		\
 	if (has_fpu)					\
-		__switch_to_aux(__prev, __next);	\
+		__switch_to_fpu(__prev, __next);	\
 	((last) = __switch_to(__prev, __next));		\
 } while (0)
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 04/13] riscv: Extending cpufeature.c to detect V-extension
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (2 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 03/13] riscv: Rename __switch_to_aux -> fpu Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension Greentime Hu
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg
  Cc: Anup Patel

From: Guo Ren <guoren@linux.alibaba.com>

From: Guo Ren <ren_guo@c-sky.com>

Current cpufeature.c doesn't support detecting V-extension, because
"rv64" also contain a 'v' letter and we need to skip it.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
 arch/riscv/include/uapi/asm/hwcap.h | 1 +
 arch/riscv/kernel/cpufeature.c      | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/uapi/asm/hwcap.h b/arch/riscv/include/uapi/asm/hwcap.h
index dee98ee28318..a913e9a38819 100644
--- a/arch/riscv/include/uapi/asm/hwcap.h
+++ b/arch/riscv/include/uapi/asm/hwcap.h
@@ -21,5 +21,6 @@
 #define COMPAT_HWCAP_ISA_F	(1 << ('F' - 'A'))
 #define COMPAT_HWCAP_ISA_D	(1 << ('D' - 'A'))
 #define COMPAT_HWCAP_ISA_C	(1 << ('C' - 'A'))
+#define COMPAT_HWCAP_ISA_V	(1 << ('V' - 'A'))
 
 #endif /* _UAPI_ASM_RISCV_HWCAP_H */
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index a5ad00043104..c8527d770c98 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -30,6 +30,7 @@ void riscv_fill_hwcap(void)
 	isa2hwcap['f'] = isa2hwcap['F'] = COMPAT_HWCAP_ISA_F;
 	isa2hwcap['d'] = isa2hwcap['D'] = COMPAT_HWCAP_ISA_D;
 	isa2hwcap['c'] = isa2hwcap['C'] = COMPAT_HWCAP_ISA_C;
+	isa2hwcap['v'] = isa2hwcap['V'] = COMPAT_HWCAP_ISA_V;
 
 	elf_hwcap = 0;
 
@@ -44,7 +45,8 @@ void riscv_fill_hwcap(void)
 			continue;
 		}
 
-		for (i = 0; i < strlen(isa); ++i)
+		/* Skip rv64/rv32 to support v/V:vector */
+		for (i = 4; i < strlen(isa); ++i)
 			this_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
 
 		/*
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (3 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 04/13] riscv: Extending cpufeature.c to detect V-extension Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-31  1:56     ` Guo Ren
  2020-06-01  9:03     ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 06/13] riscv: Add vector feature to compile Greentime Hu
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

Follow the riscv vector spec to add new csr number.

[greentime.hu@sifive.com: update the defined value based on new spec and
remove unused ones]
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 8e18d2c64399..cc13626c4bbe 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -24,6 +24,12 @@
 #define SR_FS_CLEAN	_AC(0x00004000, UL)
 #define SR_FS_DIRTY	_AC(0x00006000, UL)
 
+#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
+#define SR_VS_OFF       _AC(0x00000000, UL)
+#define SR_VS_INITIAL   _AC(0x00000200, UL)
+#define SR_VS_CLEAN     _AC(0x00000400, UL)
+#define SR_VS_DIRTY     _AC(0x00000600, UL)
+
 #define SR_XS		_AC(0x00018000, UL) /* Extension Status */
 #define SR_XS_OFF	_AC(0x00000000, UL)
 #define SR_XS_INITIAL	_AC(0x00008000, UL)
@@ -31,9 +37,9 @@
 #define SR_XS_DIRTY	_AC(0x00018000, UL)
 
 #ifndef CONFIG_64BIT
-#define SR_SD		_AC(0x80000000, UL) /* FS/XS dirty */
+#define SR_SD		_AC(0x80000000, UL) /* FS/VS/XS dirty */
 #else
-#define SR_SD		_AC(0x8000000000000000, UL) /* FS/XS dirty */
+#define SR_SD		_AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
 #endif
 
 /* SATP flags */
@@ -114,6 +120,12 @@
 #define CSR_PMPADDR0		0x3b0
 #define CSR_MHARTID		0xf14
 
+#define CSR_VSTART		0x8
+#define CSR_VCSR		0xf
+#define CSR_VL			0xc20
+#define CSR_VTYPE		0xc21
+#define CSR_VLENB		0xc22
+
 #ifdef CONFIG_RISCV_M_MODE
 # define CSR_STATUS	CSR_MSTATUS
 # define CSR_IE		CSR_MIE
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 06/13] riscv: Add vector feature to compile
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (4 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features Greentime Hu
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

This patch adds a new config option which could enable assembler's
vector feature.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/Kconfig  | 9 +++++++++
 arch/riscv/Makefile | 1 +
 2 files changed, 10 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 74f82cf4f781..3b742d949a09 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -305,6 +305,15 @@ config FPU
 
 	  If you don't know what to do here, say Y.
 
+config VECTOR
+	bool "VECTOR support"
+	default n
+	help
+	  Say N here if you want to disable all vector related procedure
+	  in the kernel.
+
+	  If you don't know what to do here, say Y.
+
 endmenu
 
 menu "Kernel features"
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 957d064bead0..7c80c95582e3 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -46,6 +46,7 @@ riscv-march-aflags-$(CONFIG_ARCH_RV32I)		:= rv32ima
 riscv-march-aflags-$(CONFIG_ARCH_RV64I)		:= rv64ima
 riscv-march-aflags-$(CONFIG_FPU)		:= $(riscv-march-aflags-y)fd
 riscv-march-aflags-$(CONFIG_RISCV_ISA_C)	:= $(riscv-march-aflags-y)c
+riscv-march-aflags-$(CONFIG_VECTOR)		:= $(riscv-march-aflags-y)v
 
 KBUILD_CFLAGS += -march=$(riscv-march-cflags-y)
 KBUILD_AFLAGS += -march=$(riscv-march-aflags-y)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (5 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 06/13] riscv: Add vector feature to compile Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-31  0:58     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 08/13] riscv: Reset vector register Greentime Hu
                   ` (6 subsequent siblings)
  13 siblings, 2 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

This patch is used to detect vector support status of CPU and use
riscv_vsize to save the size of all the vector registers. It assumes
all harts has the same capabilities in SMP system.

[greentime.hu@sifive.com: add support for dynamic vlen]
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/kernel/cpufeature.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index c8527d770c98..5a68a926da68 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
 #ifdef CONFIG_FPU
 bool has_fpu __read_mostly;
 #endif
+#ifdef CONFIG_VECTOR
+bool has_vector __read_mostly;
+unsigned long riscv_vsize __read_mostly;
+#endif
 
 void riscv_fill_hwcap(void)
 {
@@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
 	if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
 		has_fpu = true;
 #endif
+
+#ifdef CONFIG_VECTOR
+	if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
+		has_vector = true;
+		riscv_vsize = csr_read(CSR_VLENB) * 32;
+	}
+#endif
 }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 08/13] riscv: Reset vector register
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (6 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-26  7:02 ` [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions Greentime Hu
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

Reset vector registers at boot-time and disable vector instructions
execution for kernel mode.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/kernel/entry.S |  2 +-
 arch/riscv/kernel/head.S  | 49 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 56d071b2c0a1..4e32770c19c8 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -70,7 +70,7 @@ _save_context:
 	 * Disable the FPU to detect illegal usage of floating point in kernel
 	 * space.
 	 */
-	li t0, SR_SUM | SR_FS
+	li t0, SR_SUM | SR_FS | SR_VS
 
 	REG_L s0, TASK_TI_USER_SP(tp)
 	csrrc s1, CSR_STATUS, t0
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 98a406474e7d..1290ef680125 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -181,10 +181,10 @@ ENTRY(_start_kernel)
 .option pop
 
 	/*
-	 * Disable FPU to detect illegal usage of
+	 * Disable FPU & VECTOR to detect illegal usage of
 	 * floating point in kernel space
 	 */
-	li t0, SR_FS
+	li t0, SR_FS | SR_VS
 	csrc CSR_STATUS, t0
 
 #ifdef CONFIG_SMP
@@ -341,6 +341,51 @@ ENTRY(reset_regs)
 	csrw	fcsr, 0
 	/* note that the caller must clear SR_FS */
 #endif /* CONFIG_FPU */
+
+#ifdef CONFIG_VECTOR
+	csrr	t0, CSR_MISA
+	li	t1, (COMPAT_HWCAP_ISA_V >> 16)
+	slli	t1, t1, 16
+	and	t0, t0, t1
+	beqz	t0, .Lreset_regs_done
+
+	li	t1, SR_VS
+	csrs	CSR_STATUS, t1
+	vmv.v.i v0, 0
+	vmv.v.i v1, 0
+	vmv.v.i v2, 0
+	vmv.v.i v3, 0
+	vmv.v.i v4, 0
+	vmv.v.i v5, 0
+	vmv.v.i v6, 0
+	vmv.v.i v7, 0
+	vmv.v.i v8, 0
+	vmv.v.i v9, 0
+	vmv.v.i v10, 0
+	vmv.v.i v11, 0
+	vmv.v.i v12, 0
+	vmv.v.i v13, 0
+	vmv.v.i v14, 0
+	vmv.v.i v15, 0
+	vmv.v.i v16, 0
+	vmv.v.i v17, 0
+	vmv.v.i v18, 0
+	vmv.v.i v19, 0
+	vmv.v.i v20, 0
+	vmv.v.i v21, 0
+	vmv.v.i v22, 0
+	vmv.v.i v23, 0
+	vmv.v.i v24, 0
+	vmv.v.i v25, 0
+	vmv.v.i v26, 0
+	vmv.v.i v27, 0
+	vmv.v.i v28, 0
+	vmv.v.i v29, 0
+	vmv.v.i v30, 0
+	vmv.v.i v31, 0
+	/* note that the caller must clear SR_VS */
+#endif /* CONFIG_VECTOR */
+
 .Lreset_regs_done:
 	ret
 END(reset_regs)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (7 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 08/13] riscv: Reset vector register Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-06-01  9:12     ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

Add vector state context struct in struct thread and asm-offsets.c
definitions.

The vector registers will be saved in datap pointer of __riscv_v_state. It
will be dynamically allocated in kernel space. It will be put right after
the __riscv_v_state data structure in user space.

[greentime.hu@sifive.com: add support for dynamic vlen, add vcsr and remove
vxsat, vxrm because these data can be get in vcsr, add new macros for
_riscv_v_state elements offset and remove unused ones]
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/include/asm/processor.h   |  1 +
 arch/riscv/include/uapi/asm/ptrace.h | 13 +++++++++++++
 arch/riscv/kernel/asm-offsets.c      |  8 ++++++++
 3 files changed, 22 insertions(+)

diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 3ddb798264f1..217273375cfb 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -32,6 +32,7 @@ struct thread_struct {
 	unsigned long sp;	/* Kernel mode stack */
 	unsigned long s[12];	/* s[0]: frame pointer */
 	struct __riscv_d_ext_state fstate;
+	struct __riscv_v_state vstate;
 };
 
 #define INIT_THREAD {					\
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index 882547f6bd5c..661b0466b850 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -77,6 +77,19 @@ union __riscv_fp_state {
 	struct __riscv_q_ext_state q;
 };
 
+struct __riscv_v_state {
+	__u32 magic;
+	__u32 size;
+	unsigned long vstart;
+	unsigned long vl;
+	unsigned long vtype;
+	unsigned long vcsr;
+	void *datap;
+#if __riscv_xlen == 32
+	__u32 __padding;
+#endif
+} __attribute__((aligned(16)));
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 07cb9c10de4e..6627fde230b2 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -70,6 +70,14 @@ void asm_offsets(void)
 	OFFSET(TASK_THREAD_F31, task_struct, thread.fstate.f[31]);
 	OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
 
+	OFFSET(RISCV_V_STATE_MAGIC, __riscv_v_state, magic);
+	OFFSET(RISCV_V_STATE_SIZE, __riscv_v_state, size);
+	OFFSET(RISCV_V_STATE_VSTART, __riscv_v_state, vstart);
+	OFFSET(RISCV_V_STATE_VL, __riscv_v_state, vl);
+	OFFSET(RISCV_V_STATE_VTYPE, __riscv_v_state, vtype);
+	OFFSET(RISCV_V_STATE_VCSR, __riscv_v_state, vcsr);
+	OFFSET(RISCV_V_STATE_DATAP, __riscv_v_state, datap);
+
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
 	OFFSET(PT_EPC, pt_regs, epc);
 	OFFSET(PT_RA, pt_regs, ra);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 10/13] riscv: Add task switch support for vector
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (8 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-31 15:29     ` Guo Ren
                     ` (2 more replies)
  2020-05-26  7:02 ` [RFC PATCH v4 11/13] riscv: Add ptrace vector support Greentime Hu
                   ` (3 subsequent siblings)
  13 siblings, 3 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg
  Cc: Nick Knight

From: Guo Ren <guoren@linux.alibaba.com>

This patch adds task switch support for vector. It supports lazy
save and restore mechanism. It also supports all lengths of vlen.

[greentime.hu@sifive.com: add support for dynamic vlen, fix
__vstate_clean() and lazy save/restore bug]
[nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
code refine]
Signed-off-by: Nick Knight <nick.knight@sifive.com>
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
 arch/riscv/kernel/Makefile         |  1 +
 arch/riscv/kernel/process.c        | 40 ++++++++++++++
 arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
 4 files changed, 196 insertions(+)
 create mode 100644 arch/riscv/kernel/vector.S

diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index b9234e7178d0..a047dd75e09d 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -6,10 +6,12 @@
 #ifndef _ASM_RISCV_SWITCH_TO_H
 #define _ASM_RISCV_SWITCH_TO_H
 
+#include <linux/slab.h>
 #include <linux/sched/task_stack.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/csr.h>
+#include <asm/asm-offsets.h>
 
 #ifdef CONFIG_FPU
 extern void __fstate_save(struct task_struct *save_to);
@@ -63,6 +65,73 @@ extern bool has_fpu;
 #define __switch_to_fpu(__prev, __next) do { } while (0)
 #endif
 
+#ifdef CONFIG_VECTOR
+extern bool has_vector;
+extern unsigned long riscv_vsize;
+extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
+extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
+
+static inline void __vstate_clean(struct pt_regs *regs)
+{
+	regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
+}
+
+static inline void vstate_off(struct task_struct *task,
+			      struct pt_regs *regs)
+{
+	regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
+}
+
+static inline void vstate_save(struct task_struct *task,
+			       struct pt_regs *regs)
+{
+	if ((regs->status & SR_VS) == SR_VS_DIRTY) {
+		struct __riscv_v_state *vstate = &(task->thread.vstate);
+
+		/* Allocate space for vector registers. */
+		if (!vstate->datap) {
+			vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
+			vstate->size = riscv_vsize;
+		}
+		__vstate_save(vstate, vstate->datap);
+		__vstate_clean(regs);
+	}
+}
+
+static inline void vstate_restore(struct task_struct *task,
+				  struct pt_regs *regs)
+{
+	if ((regs->status & SR_VS) != SR_VS_OFF) {
+		struct __riscv_v_state *vstate = &(task->thread.vstate);
+
+		/* Allocate space for vector registers. */
+		if (!vstate->datap) {
+			vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
+			vstate->size = riscv_vsize;
+		}
+		__vstate_restore(vstate, vstate->datap);
+		__vstate_clean(regs);
+	}
+}
+
+static inline void __switch_to_vector(struct task_struct *prev,
+				   struct task_struct *next)
+{
+	struct pt_regs *regs;
+
+	regs = task_pt_regs(prev);
+	if (unlikely(regs->status & SR_SD))
+		vstate_save(prev, regs);
+	vstate_restore(next, task_pt_regs(next));
+}
+
+#else
+#define has_vector false
+#define vstate_save(task, regs) do { } while (0)
+#define vstate_restore(task, regs) do { } while (0)
+#define __switch_to_vector(__prev, __next) do { } while (0)
+#endif
+
 extern struct task_struct *__switch_to(struct task_struct *,
 				       struct task_struct *);
 
@@ -72,6 +141,8 @@ do {							\
 	struct task_struct *__next = (next);		\
 	if (has_fpu)					\
 		__switch_to_fpu(__prev, __next);	\
+	if (has_vector)					\
+		__switch_to_vector(__prev, __next);	\
 	((last) = __switch_to(__prev, __next));		\
 } while (0)
 
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 86c83081044f..dee489a1a526 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE)	+= clint.o traps_misaligned.o
 obj-$(CONFIG_FPU)		+= fpu.o
+obj-$(CONFIG_VECTOR)		+= vector.o
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP)		+= cpu_ops.o
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 610c11e91606..fc8761c04e9f 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 		 */
 		fstate_restore(current, regs);
 	}
+
+	if (has_vector) {
+		regs->status |= SR_VS_INITIAL;
+		/*
+		 * Restore the initial value to the vector register
+		 * before starting the user program.
+		 */
+		vstate_restore(current, regs);
+	}
+
 	regs->epc = pc;
 	regs->sp = sp;
 	set_fs(USER_DS);
@@ -92,15 +102,45 @@ void flush_thread(void)
 	fstate_off(current, task_pt_regs(current));
 	memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
 #endif
+#ifdef CONFIG_VECTOR
+	/* Reset vector state */
+	vstate_off(current, task_pt_regs(current));
+	memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
+#endif
 }
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
 	fstate_save(src, task_pt_regs(src));
+	if (has_vector)
+		/* To make sure every dirty vector context is saved. */
+		vstate_save(src, task_pt_regs(src));
 	*dst = *src;
+	if (has_vector) {
+		/* Copy vector context to the forked task from parent. */
+		if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
+			unsigned long size = src->thread.vstate.size;
+
+			dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
+			/* Failed to allocate memory. */
+			if (!dst->thread.vstate.datap)
+				return -ENOMEM;
+			/* Copy the src vector context to dst. */
+			memcpy(dst->thread.vstate.datap,
+			       src->thread.vstate.datap, size);
+		}
+	}
+
 	return 0;
 }
 
+void arch_release_task_struct(struct task_struct *tsk)
+{
+	/* Free the vector context of datap. */
+	if (has_vector)
+		kfree(tsk->thread.vstate.datap);
+}
+
 int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
 	unsigned long arg, struct task_struct *p, unsigned long tls)
 {
diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
new file mode 100644
index 000000000000..91d5dd29cd0f
--- /dev/null
+++ b/arch/riscv/kernel/vector.S
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ * Copyright (C) 2019 Alibaba Group Holding Limited
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/asm.h>
+#include <asm/csr.h>
+#include <asm/asm-offsets.h>
+
+#define vstatep  a0
+#define datap    a1
+#define x_vstart t0
+#define x_vtype  t1
+#define x_vl     t2
+#define x_vcsr   t3
+#define incr     t4
+#define m_one    t5
+#define status   t6
+
+ENTRY(__vstate_save)
+	li      status, SR_VS
+	csrs    sstatus, status
+
+	csrr    x_vstart, CSR_VSTART
+	csrr    x_vtype, CSR_VTYPE
+	csrr    x_vl, CSR_VL
+	csrr    x_vcsr, CSR_VCSR
+	li      m_one, -1
+	vsetvli incr, m_one, e8, m8
+	vse.v   v0, (datap)
+	add     datap, datap, incr
+	vse.v   v8, (datap)
+	add     datap, datap, incr
+	vse.v   v16, (datap)
+	add     datap, datap, incr
+	vse.v   v24, (datap)
+
+	REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
+	REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
+	REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
+	REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
+
+	csrc	sstatus, status
+	ret
+ENDPROC(__vstate_save)
+
+ENTRY(__vstate_restore)
+	li      status, SR_VS
+	csrs    sstatus, status
+
+	li      m_one, -1
+	vsetvli incr, m_one, e8, m8
+	vle.v   v0, (datap)
+	add     datap, datap, incr
+	vle.v   v8, (datap)
+	add     datap, datap, incr
+	vle.v   v16, (datap)
+	add     datap, datap, incr
+	vle.v   v24, (datap)
+
+	REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
+	REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
+	REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
+	REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
+	vsetvl  x0, x_vl, x_vtype
+	csrw    CSR_VSTART, x_vstart
+	csrw    CSR_VCSR, x_vcsr
+
+	csrc	sstatus, status
+	ret
+ENDPROC(__vstate_restore)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 11/13] riscv: Add ptrace vector support
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (9 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-06-01  9:14     ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector Greentime Hu
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

This patch adds ptrace support for riscv vector. The vector registers will
be saved in datap pointer of __riscv_v_state. This pointer will be set
right after the __riscv_v_state data structure then it will be put in ubuf
for ptrace system call to get or set. It will check if the datap got from
ubuf is set to the correct address or not when the ptrace system call is
trying to set the vector registers.

[greentime.hu@sifive.com: add support for dynamic vlen, fix vtype not
saved bug]
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/include/uapi/asm/elf.h |   1 +
 arch/riscv/kernel/ptrace.c        | 114 ++++++++++++++++++++++++++++++
 include/uapi/linux/elf.h          |   1 +
 3 files changed, 116 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/elf.h b/arch/riscv/include/uapi/asm/elf.h
index d696d6610231..099434d075a7 100644
--- a/arch/riscv/include/uapi/asm/elf.h
+++ b/arch/riscv/include/uapi/asm/elf.h
@@ -23,6 +23,7 @@ typedef struct user_regs_struct elf_gregset_t;
 typedef __u64 elf_fpreg_t;
 typedef union __riscv_fp_state elf_fpregset_t;
 #define ELF_NFPREG (sizeof(struct __riscv_d_ext_state) / sizeof(elf_fpreg_t))
+#define ELF_NVREG  (sizeof(struct __riscv_v_state) / sizeof(elf_greg_t))
 
 #if __riscv_xlen == 64
 #define ELF_RISCV_R_SYM(r_info)		ELF64_R_SYM(r_info)
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 444dc7b0fd78..9b9bd1c02362 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -10,6 +10,7 @@
 #include <asm/ptrace.h>
 #include <asm/syscall.h>
 #include <asm/thread_info.h>
+#include <asm/switch_to.h>
 #include <linux/audit.h>
 #include <linux/ptrace.h>
 #include <linux/elf.h>
@@ -26,6 +27,9 @@ enum riscv_regset {
 #ifdef CONFIG_FPU
 	REGSET_F,
 #endif
+#ifdef CONFIG_VECTOR
+	REGSET_V,
+#endif
 };
 
 static int riscv_gpr_get(struct task_struct *target,
@@ -92,6 +96,107 @@ static int riscv_fpr_set(struct task_struct *target,
 }
 #endif
 
+#ifdef CONFIG_VECTOR
+static int riscv_vr_get(struct task_struct *target,
+			 const struct user_regset *regset,
+			 unsigned int pos, unsigned int count,
+			 void *kbuf, void __user *ubuf)
+{
+	int ret, size;
+	struct __riscv_v_state *vstate = &target->thread.vstate;
+	/* Set the datap right after the address of vstate. */
+	void *datap = ubuf + sizeof(struct __riscv_v_state);
+	u32 magic = RVV_MAGIC;
+
+	/* Copy the magic number. */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &magic, 0,
+				  sizeof(u32));
+	if (unlikely(ret))
+		return ret;
+
+	/* Copy rest of vstate except datap. */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, vstate, 0,
+				  RISCV_V_STATE_DATAP);
+	if (unlikely(ret))
+		return ret;
+
+	/* Copy the pointer datap itself. */
+	pos = 0;
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &datap, 0,
+				  sizeof(vstate->datap));
+	if (unlikely(ret))
+		return ret;
+
+#if __riscv_xlen == 32
+	/* Skip copy _padding. */
+	size = sizeof(vstate->__padding);
+	count -= size;
+	ubuf += size;
+#endif
+
+	/* Copy all the vector registers. */
+	pos = 0;
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  vstate->datap, 0, vstate->size);
+	return ret;
+}
+
+static int riscv_vr_set(struct task_struct *target,
+			 const struct user_regset *regset,
+			 unsigned int pos, unsigned int count,
+			 const void *kbuf, const void __user *ubuf)
+{
+	int ret, size;
+	struct __riscv_v_state *vstate = &target->thread.vstate;
+	const void *datap = ubuf + sizeof(struct __riscv_v_state);
+	const void *datap_addr = ubuf + RISCV_V_STATE_DATAP;
+	long val_datap;
+
+	/* Skip copy magic because kernel doesn't need to use it. */
+	size = sizeof(vstate->magic);
+	pos += size;
+	count -= size;
+	ubuf += size;
+
+	/* Copy rest of the vstate except datap and __padding. */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate, 0,
+				 RISCV_V_STATE_DATAP);
+	if (unlikely(ret))
+		return ret;
+
+	/* Check if the datap is correct address of ubuf. */
+	__get_user(val_datap, (long *)datap_addr);
+	if (val_datap != (long)datap)
+		return -EFAULT;
+
+	/* Skip copy datap. */
+	size = sizeof(vstate->datap);
+	count -= size;
+	ubuf += size;
+
+#if __riscv_xlen == 32
+	/* Skip copy _padding. */
+	size = sizeof(vstate->__padding);
+	count -= size;
+	ubuf += size;
+#endif
+
+	/* Copy all the vector registers. */
+	pos = 0;
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate->datap,
+				 0, vstate->size);
+	return ret;
+}
+static unsigned int riscv_vr_get_size(struct task_struct *target,
+				      const struct user_regset *regset)
+{
+	if (!has_vector)
+		return 0;
+
+	return sizeof(struct __riscv_v_state) + riscv_vsize;
+}
+#endif
+
 static const struct user_regset riscv_user_regset[] = {
 	[REGSET_X] = {
 		.core_note_type = NT_PRSTATUS,
@@ -111,6 +216,15 @@ static const struct user_regset riscv_user_regset[] = {
 		.set = &riscv_fpr_set,
 	},
 #endif
+#ifdef CONFIG_VECTOR
+	[REGSET_V] = {
+		.core_note_type = NT_RISCV_VECTOR,
+		.align = 16,
+		.get = riscv_vr_get,
+		.set = riscv_vr_set,
+		.get_size = riscv_vr_get_size,
+	},
+#endif
 };
 
 static const struct user_regset_view riscv_user_native_view = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 34c02e4290fe..e428f9e8710a 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -428,6 +428,7 @@ typedef struct elf64_shdr {
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
 #define NT_MIPS_FP_MODE	0x801		/* MIPS floating-point mode */
 #define NT_MIPS_MSA	0x802		/* MIPS SIMD registers */
+#define NT_RISCV_VECTOR	0x900		/* RISC-V vector registers */
 
 /* Note header in a PT_NOTE section */
 typedef struct elf32_note {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (10 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 11/13] riscv: Add ptrace vector support Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-31 15:28     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 13/13] riscv: signal: Report signal frame size to userspace via auxv Greentime Hu
  2020-05-31 15:52   ` Guo Ren
  13 siblings, 2 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Guo Ren <guoren@linux.alibaba.com>

This patch adds sigcontext save/restore for vector. The vector registers
will be saved in datap pointer. The datap pointer will be allocaed
dynamically when the task needs in kernel space. The datap pointer will
be set right after the __riscv_v_state data structure to save all the
vector registers in the signal handler stack.

[greentime.hu@sifive.com: add support for dynamic vlen]
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/include/uapi/asm/sigcontext.h |  2 +
 arch/riscv/kernel/signal.c               | 92 +++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
index 84f2dfcfdbce..4217f3f1c8ba 100644
--- a/arch/riscv/include/uapi/asm/sigcontext.h
+++ b/arch/riscv/include/uapi/asm/sigcontext.h
@@ -8,6 +8,7 @@
 
 #include <asm/ptrace.h>
 
+#define RVV_MAGIC	0x53465457
 /*
  * Signal context structure
  *
@@ -17,6 +18,7 @@
 struct sigcontext {
 	struct user_regs_struct sc_regs;
 	union __riscv_fp_state sc_fpregs;
+	struct __riscv_v_state sc_vregs;
 };
 
 #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 17ba190e84a5..9ada6f74bb95 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
 #define restore_fp_state(task, regs) (0)
 #endif
 
+#ifdef CONFIG_VECTOR
+static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
+{
+	long err;
+	struct __riscv_v_state __user *state = &sc->sc_vregs;
+	void *datap;
+	__u32 magic;
+
+	/* Get magic number and check it. */
+	err = __get_user(magic, &state->magic);
+	if (unlikely(err))
+		return err;
+
+	if (magic != RVV_MAGIC)
+		return -EINVAL;
+
+	/* Copy everything of __riscv_v_state except datap. */
+	err = __copy_from_user(&current->thread.vstate, state,
+			       RISCV_V_STATE_DATAP);
+	if (unlikely(err))
+		return err;
+
+	/* Copy the pointer datap itself. */
+	err = __get_user(datap, &state->datap);
+	if (unlikely(err))
+		return err;
+
+
+	/* Copy the whole vector content from user space datap. */
+	err = __copy_from_user(current->thread.vstate.datap, datap,
+			       current->thread.vstate.size);
+	if (unlikely(err))
+		return err;
+
+	vstate_restore(current, regs);
+
+	return err;
+}
+
+static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
+{
+	long err;
+	struct __riscv_v_state __user *state = &sc->sc_vregs;
+	/* Set the datap right after the sigcntext structure. */
+	void *datap = sc + 1;
+
+	vstate_save(current, regs);
+	/* Copy everything of vstate but datap. */
+	err = __copy_to_user(state, &current->thread.vstate,
+			     RISCV_V_STATE_DATAP);
+	if (unlikely(err))
+		return err;
+
+	/* Copy the magic number. */
+	err = __put_user(RVV_MAGIC, &state->magic);
+	if (unlikely(err))
+		return err;
+
+	/* Copy the pointer datap itself. */
+	err = __put_user(datap, &state->datap);
+	if (unlikely(err))
+		return err;
+
+	/* Copy the whole vector content to user space datap. */
+	err = __copy_to_user(datap, current->thread.vstate.datap,
+			     current->thread.vstate.size);
+
+	return err;
+}
+#else
+#define save_v_state(task, regs) (0)
+#define restore_v_state(task, regs) (0)
+#endif
+
 static long restore_sigcontext(struct pt_regs *regs,
 	struct sigcontext __user *sc)
 {
@@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
 	/* Restore the floating-point state. */
 	if (has_fpu)
 		err |= restore_fp_state(regs, &sc->sc_fpregs);
+	/* Restore the vector state. */
+	if (has_vector)
+		err |= restore_v_state(regs, sc);
 	return err;
 }
 
@@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
 	struct rt_sigframe __user *frame;
 	struct task_struct *task;
 	sigset_t set;
+	size_t frame_size = sizeof(*frame);
 
 	/* Always make any pending restarted system calls return -EINTR */
 	current->restart_block.fn = do_no_restart_syscall;
 
 	frame = (struct rt_sigframe __user *)regs->sp;
 
-	if (!access_ok(frame, sizeof(*frame)))
+	if (has_vector)
+		frame_size += current->thread.vstate.size;
+	if (!access_ok(frame, frame_size))
 		goto badframe;
 
 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
@@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 	/* Save the floating-point state. */
 	if (has_fpu)
 		err |= save_fp_state(regs, &sc->sc_fpregs);
+	/* Save the vector state. */
+	if (has_vector)
+		err |= save_v_state(regs, sc);
 	return err;
 }
 
@@ -176,9 +259,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 {
 	struct rt_sigframe __user *frame;
 	long err = 0;
+	size_t frame_size = sizeof(*frame);
 
-	frame = get_sigframe(ksig, regs, sizeof(*frame));
-	if (!access_ok(frame, sizeof(*frame)))
+	if (has_vector)
+		frame_size += current->thread.vstate.size;
+	frame = get_sigframe(ksig, regs, frame_size);
+	if (!access_ok(frame, frame_size))
 		return -EFAULT;
 
 	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH v4 13/13] riscv: signal: Report signal frame size to userspace via auxv
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
                   ` (11 preceding siblings ...)
  2020-05-26  7:02 ` [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector Greentime Hu
@ 2020-05-26  7:02 ` Greentime Hu
  2020-05-31 15:52   ` Guo Ren
  13 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-26  7:02 UTC (permalink / raw)
  To: greentime.hu, guoren, vincent.chen, paul.walmsley, palmerdabbelt,
	linux-riscv, linux-kernel, oleg

From: Vincent Chen <vincent.chen@sifive.com>

The vector register belongs to the signal context. They need to be stored
and restored as entering and leaving the signal handler. According to the
V-extension specification, the maximum length of the vector registers can
be 2^(XLEN-1). Hence, if userspace refers to the MINSIGSTKSZ #define
(2KB) to create a sigframe, it may not be enough. To resolve this problem,
this patch refers to the commit 94b07c1f8c39c
("arm64: signal: Report signal frame size to userspace via auxv") to enable
userspace to know the minimum required sigframe size through the auxiliary
vector and use it to allocate enough memory for signal context.

Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
---
 arch/riscv/include/asm/elf.h         | 17 +++++++++++++----
 arch/riscv/include/asm/processor.h   |  2 ++
 arch/riscv/include/uapi/asm/auxvec.h |  2 ++
 arch/riscv/kernel/setup.c            |  5 +++++
 arch/riscv/kernel/signal.c           | 16 ++++++++++++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..b6b15fc5f784 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -57,10 +57,19 @@ extern unsigned long elf_hwcap;
 #define ELF_PLATFORM	(NULL)
 
 #ifdef CONFIG_MMU
-#define ARCH_DLINFO						\
-do {								\
-	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
-		(elf_addr_t)current->mm->context.vdso);		\
+#define ARCH_DLINFO						 \
+do {								 \
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,				 \
+		(elf_addr_t)current->mm->context.vdso);		 \
+	/*							 \
+	 * Should always be nonzero unless there's a kernel bug. \
+	 * If we haven't determined a sensible value to give to	 \
+	 * userspace, omit the entry:				 \
+	 */							 \
+	if (likely(signal_minsigstksz))				 \
+		NEW_AUX_ENT(AT_MINSIGSTKSZ, signal_minsigstksz); \
+	else							 \
+		NEW_AUX_ENT(AT_IGNORE, 0);			 \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 217273375cfb..5be2da702897 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -7,6 +7,7 @@
 #define _ASM_RISCV_PROCESSOR_H
 
 #include <linux/const.h>
+#include <linux/cache.h>
 
 #include <asm/ptrace.h>
 
@@ -79,6 +80,7 @@ int riscv_of_processor_hartid(struct device_node *node);
 
 extern void riscv_fill_hwcap(void);
 
+extern unsigned long signal_minsigstksz __ro_after_init;
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_RISCV_PROCESSOR_H */
diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..9745a01e5e61 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,6 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+#define AT_MINSIGSTKSZ 51
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 145128a7e560..6220e25ea9b0 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -17,6 +17,7 @@
 #include <linux/sched/task.h>
 #include <linux/swiotlb.h>
 #include <linux/smp.h>
+#include <linux/processor.h>
 
 #include <asm/clint.h>
 #include <asm/cpu_ops.h>
@@ -62,6 +63,8 @@ void __init parse_dtb(void)
 #endif
 }
 
+extern void __init minsigstksz_setup(void);
+
 void __init setup_arch(char **cmdline_p)
 {
 	init_mm.start_code = (unsigned long) _stext;
@@ -95,6 +98,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 	riscv_fill_hwcap();
+
+	minsigstksz_setup();
 }
 
 static int __init topology_init(void)
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 9ada6f74bb95..4f81251867e6 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -404,3 +404,19 @@ asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
 		tracehook_notify_resume(regs);
 	}
 }
+
+unsigned long __ro_after_init signal_minsigstksz;
+
+/*
+ * Determine the stack space required for guaranteed signal devliery.
+ * This function is used to populate AT_MINSIGSTKSZ at process startup.
+ * cpufeatures setup is assumed to be complete.
+ */
+void __init minsigstksz_setup(void)
+{
+	signal_minsigstksz = sizeof(struct rt_sigframe);
+#ifdef CONFIG_VECTOR
+	if (has_vector)
+		signal_minsigstksz += riscv_vsize;
+#endif
+}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
  2020-05-26  7:02 ` [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size Greentime Hu
@ 2020-05-26 14:00     ` Oleg Nesterov
  0 siblings, 0 replies; 54+ messages in thread
From: Oleg Nesterov @ 2020-05-26 14:00 UTC (permalink / raw)
  To: Greentime Hu
  Cc: guoren, vincent.chen, paul.walmsley, palmerdabbelt, linux-riscv,
	linux-kernel

On 05/26, Greentime Hu wrote:
>
> @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
>  	const struct user_regset_view *view = task_user_regset_view(task);
>  	const struct user_regset *regset = find_regset(view, type);
>  	int regset_no;
> +	unsigned int size;
>
> -	if (!regset || (kiov->iov_len % regset->size) != 0)
> +	if (!regset)
>  		return -EINVAL;
>
>  	regset_no = regset - view->regsets;
> -	kiov->iov_len = min(kiov->iov_len,
> -			    (__kernel_size_t) (regset->n * regset->size));
> +	size = regset_size(task, regset);
> +
> +	if ((kiov->iov_len % size) != 0)
> +		return -EINVAL;

Hmm. this doesn't look right.

Before this patch we check "iov_len % regset->size", this is not the same
as "iov_len % regset_size()".

IOW, currently you can read/write, say, only the 1st register, you patch
breaks this?

Oleg.


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
@ 2020-05-26 14:00     ` Oleg Nesterov
  0 siblings, 0 replies; 54+ messages in thread
From: Oleg Nesterov @ 2020-05-26 14:00 UTC (permalink / raw)
  To: Greentime Hu
  Cc: guoren, palmerdabbelt, linux-kernel, vincent.chen, paul.walmsley,
	linux-riscv

On 05/26, Greentime Hu wrote:
>
> @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
>  	const struct user_regset_view *view = task_user_regset_view(task);
>  	const struct user_regset *regset = find_regset(view, type);
>  	int regset_no;
> +	unsigned int size;
>
> -	if (!regset || (kiov->iov_len % regset->size) != 0)
> +	if (!regset)
>  		return -EINVAL;
>
>  	regset_no = regset - view->regsets;
> -	kiov->iov_len = min(kiov->iov_len,
> -			    (__kernel_size_t) (regset->n * regset->size));
> +	size = regset_size(task, regset);
> +
> +	if ((kiov->iov_len % size) != 0)
> +		return -EINVAL;

Hmm. this doesn't look right.

Before this patch we check "iov_len % regset->size", this is not the same
as "iov_len % regset_size()".

IOW, currently you can read/write, say, only the 1st register, you patch
breaks this?

Oleg.



^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
  2020-05-26 14:00     ` Oleg Nesterov
@ 2020-05-27  6:34       ` Greentime Hu
  -1 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-27  6:34 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List

Oleg Nesterov <oleg@redhat.com> 於 2020年5月26日 週二 下午10:00寫道:
>
> On 05/26, Greentime Hu wrote:
> >
> > @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
> >       const struct user_regset_view *view = task_user_regset_view(task);
> >       const struct user_regset *regset = find_regset(view, type);
> >       int regset_no;
> > +     unsigned int size;
> >
> > -     if (!regset || (kiov->iov_len % regset->size) != 0)
> > +     if (!regset)
> >               return -EINVAL;
> >
> >       regset_no = regset - view->regsets;
> > -     kiov->iov_len = min(kiov->iov_len,
> > -                         (__kernel_size_t) (regset->n * regset->size));
> > +     size = regset_size(task, regset);
> > +
> > +     if ((kiov->iov_len % size) != 0)
> > +             return -EINVAL;
>
> Hmm. this doesn't look right.
>
> Before this patch we check "iov_len % regset->size", this is not the same
> as "iov_len % regset_size()".
>
> IOW, currently you can read/write, say, only the 1st register, you patch
> breaks this?
>

Hi Oleg,

Thank you. I misunderstood the meaning of regset->size
It seems I only needs to update this line, right?
- kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
regset->size));
+ kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
regset_size(task, regset));

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
@ 2020-05-27  6:34       ` Greentime Hu
  0 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-05-27  6:34 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List, Vincent Chen,
	Paul Walmsley, linux-riscv

Oleg Nesterov <oleg@redhat.com> 於 2020年5月26日 週二 下午10:00寫道:
>
> On 05/26, Greentime Hu wrote:
> >
> > @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
> >       const struct user_regset_view *view = task_user_regset_view(task);
> >       const struct user_regset *regset = find_regset(view, type);
> >       int regset_no;
> > +     unsigned int size;
> >
> > -     if (!regset || (kiov->iov_len % regset->size) != 0)
> > +     if (!regset)
> >               return -EINVAL;
> >
> >       regset_no = regset - view->regsets;
> > -     kiov->iov_len = min(kiov->iov_len,
> > -                         (__kernel_size_t) (regset->n * regset->size));
> > +     size = regset_size(task, regset);
> > +
> > +     if ((kiov->iov_len % size) != 0)
> > +             return -EINVAL;
>
> Hmm. this doesn't look right.
>
> Before this patch we check "iov_len % regset->size", this is not the same
> as "iov_len % regset_size()".
>
> IOW, currently you can read/write, say, only the 1st register, you patch
> breaks this?
>

Hi Oleg,

Thank you. I misunderstood the meaning of regset->size
It seems I only needs to update this line, right?
- kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
regset->size));
+ kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
regset_size(task, regset));


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
  2020-05-27  6:34       ` Greentime Hu
@ 2020-05-27 11:31         ` Oleg Nesterov
  -1 siblings, 0 replies; 54+ messages in thread
From: Oleg Nesterov @ 2020-05-27 11:31 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List

On 05/27, Greentime Hu wrote:
>
> It seems I only needs to update this line, right?
> - kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
> regset->size));
> + kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
> regset_size(task, regset));

Yes, agreed.

Oleg.


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size.
@ 2020-05-27 11:31         ` Oleg Nesterov
  0 siblings, 0 replies; 54+ messages in thread
From: Oleg Nesterov @ 2020-05-27 11:31 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List, Vincent Chen,
	Paul Walmsley, linux-riscv

On 05/27, Greentime Hu wrote:
>
> It seems I only needs to update this line, right?
> - kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
> regset->size));
> + kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
> regset_size(task, regset));

Yes, agreed.

Oleg.



^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
  2020-05-26  7:02 ` [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features Greentime Hu
@ 2020-05-31  0:58     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31  0:58 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg

Reviewed-by: Guo Ren <guoren@kernel.org>

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch is used to detect vector support status of CPU and use
> riscv_vsize to save the size of all the vector registers. It assumes
> all harts has the same capabilities in SMP system.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index c8527d770c98..5a68a926da68 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
>  #ifdef CONFIG_FPU
>  bool has_fpu __read_mostly;
>  #endif
> +#ifdef CONFIG_VECTOR
> +bool has_vector __read_mostly;
> +unsigned long riscv_vsize __read_mostly;
> +#endif
>
>  void riscv_fill_hwcap(void)
>  {
> @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
>         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
>                 has_fpu = true;
>  #endif
> +
> +#ifdef CONFIG_VECTOR
> +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> +               has_vector = true;
> +               riscv_vsize = csr_read(CSR_VLENB) * 32;
No magic number 32.
eg:
#define VECTOR_REGS_NUM 32

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
@ 2020-05-31  0:58     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31  0:58 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, palmerdabbelt, Linux Kernel Mailing List, oleg,
	Vincent Chen, Paul Walmsley, linux-riscv

Reviewed-by: Guo Ren <guoren@kernel.org>

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch is used to detect vector support status of CPU and use
> riscv_vsize to save the size of all the vector registers. It assumes
> all harts has the same capabilities in SMP system.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index c8527d770c98..5a68a926da68 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
>  #ifdef CONFIG_FPU
>  bool has_fpu __read_mostly;
>  #endif
> +#ifdef CONFIG_VECTOR
> +bool has_vector __read_mostly;
> +unsigned long riscv_vsize __read_mostly;
> +#endif
>
>  void riscv_fill_hwcap(void)
>  {
> @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
>         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
>                 has_fpu = true;
>  #endif
> +
> +#ifdef CONFIG_VECTOR
> +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> +               has_vector = true;
> +               riscv_vsize = csr_read(CSR_VLENB) * 32;
No magic number 32.
eg:
#define VECTOR_REGS_NUM 32

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
  2020-05-26  7:02 ` [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension Greentime Hu
@ 2020-05-31  1:56     ` Guo Ren
  2020-06-01  9:03     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31  1:56 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg

Hi Greentime,

Why remove vxrm and xstat ?

> Appendix B: Calling Convention
> In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> The vxrm and vxsat fields have thread storage duration.

As spec 0.9 mentioned above, vxrm and vxsat are thread storage duration.

When timer 's interrupt coming, we still need to save them in context_switch.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Follow the riscv vector spec to add new csr number.
>
> [greentime.hu@sifive.com: update the defined value based on new spec and
> remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index 8e18d2c64399..cc13626c4bbe 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -24,6 +24,12 @@
>  #define SR_FS_CLEAN    _AC(0x00004000, UL)
>  #define SR_FS_DIRTY    _AC(0x00006000, UL)
>
> +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> +#define SR_VS_OFF       _AC(0x00000000, UL)
> +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> +
>  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
>  #define SR_XS_OFF      _AC(0x00000000, UL)
>  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> @@ -31,9 +37,9 @@
>  #define SR_XS_DIRTY    _AC(0x00018000, UL)
>
>  #ifndef CONFIG_64BIT
> -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
>  #else
> -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
>  #endif
>
>  /* SATP flags */
> @@ -114,6 +120,12 @@
>  #define CSR_PMPADDR0           0x3b0
>  #define CSR_MHARTID            0xf14
>
> +#define CSR_VSTART             0x8
> +#define CSR_VCSR               0xf
> +#define CSR_VL                 0xc20
> +#define CSR_VTYPE              0xc21
> +#define CSR_VLENB              0xc22
> +
>  #ifdef CONFIG_RISCV_M_MODE
>  # define CSR_STATUS    CSR_MSTATUS
>  # define CSR_IE                CSR_MIE
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
@ 2020-05-31  1:56     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31  1:56 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, palmerdabbelt, Linux Kernel Mailing List, oleg,
	Vincent Chen, Paul Walmsley, linux-riscv

Hi Greentime,

Why remove vxrm and xstat ?

> Appendix B: Calling Convention
> In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> The vxrm and vxsat fields have thread storage duration.

As spec 0.9 mentioned above, vxrm and vxsat are thread storage duration.

When timer 's interrupt coming, we still need to save them in context_switch.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Follow the riscv vector spec to add new csr number.
>
> [greentime.hu@sifive.com: update the defined value based on new spec and
> remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index 8e18d2c64399..cc13626c4bbe 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -24,6 +24,12 @@
>  #define SR_FS_CLEAN    _AC(0x00004000, UL)
>  #define SR_FS_DIRTY    _AC(0x00006000, UL)
>
> +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> +#define SR_VS_OFF       _AC(0x00000000, UL)
> +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> +
>  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
>  #define SR_XS_OFF      _AC(0x00000000, UL)
>  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> @@ -31,9 +37,9 @@
>  #define SR_XS_DIRTY    _AC(0x00018000, UL)
>
>  #ifndef CONFIG_64BIT
> -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
>  #else
> -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
>  #endif
>
>  /* SATP flags */
> @@ -114,6 +120,12 @@
>  #define CSR_PMPADDR0           0x3b0
>  #define CSR_MHARTID            0xf14
>
> +#define CSR_VSTART             0x8
> +#define CSR_VCSR               0xf
> +#define CSR_VL                 0xc20
> +#define CSR_VTYPE              0xc21
> +#define CSR_VLENB              0xc22
> +
>  #ifdef CONFIG_RISCV_M_MODE
>  # define CSR_STATUS    CSR_MSTATUS
>  # define CSR_IE                CSR_MIE
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector
  2020-05-26  7:02 ` [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector Greentime Hu
@ 2020-05-31 15:28     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:28 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg

Hi Greentime,

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds sigcontext save/restore for vector. The vector registers
> will be saved in datap pointer. The datap pointer will be allocaed
> dynamically when the task needs in kernel space. The datap pointer will
> be set right after the __riscv_v_state data structure to save all the
> vector registers in the signal handler stack.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/sigcontext.h |  2 +
>  arch/riscv/kernel/signal.c               | 92 +++++++++++++++++++++++-
>  2 files changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
> index 84f2dfcfdbce..4217f3f1c8ba 100644
> --- a/arch/riscv/include/uapi/asm/sigcontext.h
> +++ b/arch/riscv/include/uapi/asm/sigcontext.h
> @@ -8,6 +8,7 @@
>
>  #include <asm/ptrace.h>
>
> +#define RVV_MAGIC      0x53465457
>  /*
>   * Signal context structure
>   *
> @@ -17,6 +18,7 @@
>  struct sigcontext {
>         struct user_regs_struct sc_regs;
>         union __riscv_fp_state sc_fpregs;
> +       struct __riscv_v_state sc_vregs;
>  };
>
>  #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index 17ba190e84a5..9ada6f74bb95 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
>  #define restore_fp_state(task, regs) (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       void *datap;
> +       __u32 magic;
> +
> +       /* Get magic number and check it. */
> +       err = __get_user(magic, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       if (magic != RVV_MAGIC)
> +               return -EINVAL;
> +
> +       /* Copy everything of __riscv_v_state except datap. */
> +       err = __copy_from_user(&current->thread.vstate, state,
> +                              RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __get_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +
> +       /* Copy the whole vector content from user space datap. */
> +       err = __copy_from_user(current->thread.vstate.datap, datap,
> +                              current->thread.vstate.size);
> +       if (unlikely(err))
> +               return err;
> +
> +       vstate_restore(current, regs);
> +
> +       return err;
> +}
> +
> +static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       /* Set the datap right after the sigcntext structure. */
> +       void *datap = sc + 1;
> +
> +       vstate_save(current, regs);
> +       /* Copy everything of vstate but datap. */
> +       err = __copy_to_user(state, &current->thread.vstate,
> +                            RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the magic number. */
> +       err = __put_user(RVV_MAGIC, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __put_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the whole vector content to user space datap. */
> +       err = __copy_to_user(datap, current->thread.vstate.datap,
> +                            current->thread.vstate.size);
> +
> +       return err;
> +}
> +#else
> +#define save_v_state(task, regs) (0)
> +#define restore_v_state(task, regs) (0)
> +#endif
> +
>  static long restore_sigcontext(struct pt_regs *regs,
>         struct sigcontext __user *sc)
>  {
> @@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
>         /* Restore the floating-point state. */
>         if (has_fpu)
>                 err |= restore_fp_state(regs, &sc->sc_fpregs);
> +       /* Restore the vector state. */
> +       if (has_vector)
> +               err |= restore_v_state(regs, sc);
>         return err;
>  }
>
> @@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
>         struct rt_sigframe __user *frame;
>         struct task_struct *task;
>         sigset_t set;
> +       size_t frame_size = sizeof(*frame);
>
>         /* Always make any pending restarted system calls return -EINTR */
>         current->restart_block.fn = do_no_restart_syscall;
>
>         frame = (struct rt_sigframe __user *)regs->sp;
>
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
Shall we force all applications save & restore vr regs ?  Maybe we can
utilize vs dirty bit

> +       if (!access_ok(frame, frame_size))
>                 goto badframe;
>
>         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
> @@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
>         /* Save the floating-point state. */
>         if (has_fpu)
>                 err |= save_fp_state(regs, &sc->sc_fpregs);
> +       /* Save the vector state. */
> +       if (has_vector)
> +               err |= save_v_state(regs, sc);
>         return err;
>  }
>
> @@ -176,9 +259,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>  {
>         struct rt_sigframe __user *frame;
>         long err = 0;
> +       size_t frame_size = sizeof(*frame);
>
> -       frame = get_sigframe(ksig, regs, sizeof(*frame));
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       frame = get_sigframe(ksig, regs, frame_size);
> +       if (!access_ok(frame, frame_size))
>                 return -EFAULT;
>
>         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector
@ 2020-05-31 15:28     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:28 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, palmerdabbelt, Linux Kernel Mailing List, oleg,
	Vincent Chen, Paul Walmsley, linux-riscv

Hi Greentime,

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds sigcontext save/restore for vector. The vector registers
> will be saved in datap pointer. The datap pointer will be allocaed
> dynamically when the task needs in kernel space. The datap pointer will
> be set right after the __riscv_v_state data structure to save all the
> vector registers in the signal handler stack.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/sigcontext.h |  2 +
>  arch/riscv/kernel/signal.c               | 92 +++++++++++++++++++++++-
>  2 files changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
> index 84f2dfcfdbce..4217f3f1c8ba 100644
> --- a/arch/riscv/include/uapi/asm/sigcontext.h
> +++ b/arch/riscv/include/uapi/asm/sigcontext.h
> @@ -8,6 +8,7 @@
>
>  #include <asm/ptrace.h>
>
> +#define RVV_MAGIC      0x53465457
>  /*
>   * Signal context structure
>   *
> @@ -17,6 +18,7 @@
>  struct sigcontext {
>         struct user_regs_struct sc_regs;
>         union __riscv_fp_state sc_fpregs;
> +       struct __riscv_v_state sc_vregs;
>  };
>
>  #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index 17ba190e84a5..9ada6f74bb95 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
>  #define restore_fp_state(task, regs) (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       void *datap;
> +       __u32 magic;
> +
> +       /* Get magic number and check it. */
> +       err = __get_user(magic, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       if (magic != RVV_MAGIC)
> +               return -EINVAL;
> +
> +       /* Copy everything of __riscv_v_state except datap. */
> +       err = __copy_from_user(&current->thread.vstate, state,
> +                              RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __get_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +
> +       /* Copy the whole vector content from user space datap. */
> +       err = __copy_from_user(current->thread.vstate.datap, datap,
> +                              current->thread.vstate.size);
> +       if (unlikely(err))
> +               return err;
> +
> +       vstate_restore(current, regs);
> +
> +       return err;
> +}
> +
> +static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       /* Set the datap right after the sigcntext structure. */
> +       void *datap = sc + 1;
> +
> +       vstate_save(current, regs);
> +       /* Copy everything of vstate but datap. */
> +       err = __copy_to_user(state, &current->thread.vstate,
> +                            RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the magic number. */
> +       err = __put_user(RVV_MAGIC, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __put_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the whole vector content to user space datap. */
> +       err = __copy_to_user(datap, current->thread.vstate.datap,
> +                            current->thread.vstate.size);
> +
> +       return err;
> +}
> +#else
> +#define save_v_state(task, regs) (0)
> +#define restore_v_state(task, regs) (0)
> +#endif
> +
>  static long restore_sigcontext(struct pt_regs *regs,
>         struct sigcontext __user *sc)
>  {
> @@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
>         /* Restore the floating-point state. */
>         if (has_fpu)
>                 err |= restore_fp_state(regs, &sc->sc_fpregs);
> +       /* Restore the vector state. */
> +       if (has_vector)
> +               err |= restore_v_state(regs, sc);
>         return err;
>  }
>
> @@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
>         struct rt_sigframe __user *frame;
>         struct task_struct *task;
>         sigset_t set;
> +       size_t frame_size = sizeof(*frame);
>
>         /* Always make any pending restarted system calls return -EINTR */
>         current->restart_block.fn = do_no_restart_syscall;
>
>         frame = (struct rt_sigframe __user *)regs->sp;
>
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
Shall we force all applications save & restore vr regs ?  Maybe we can
utilize vs dirty bit

> +       if (!access_ok(frame, frame_size))
>                 goto badframe;
>
>         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
> @@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
>         /* Save the floating-point state. */
>         if (has_fpu)
>                 err |= save_fp_state(regs, &sc->sc_fpregs);
> +       /* Save the vector state. */
> +       if (has_vector)
> +               err |= save_v_state(regs, sc);
>         return err;
>  }
>
> @@ -176,9 +259,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>  {
>         struct rt_sigframe __user *frame;
>         long err = 0;
> +       size_t frame_size = sizeof(*frame);
>
> -       frame = get_sigframe(ksig, regs, sizeof(*frame));
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       frame = get_sigframe(ksig, regs, frame_size);
> +       if (!access_ok(frame, frame_size))
>                 return -EFAULT;
>
>         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
  2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
@ 2020-05-31 15:29     ` Guo Ren
  2020-05-31 16:08     ` Guo Ren
  2020-06-01  9:12     ` Guo Ren
  2 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:29 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg, Nick Knight

Hi Greentime,

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
Is this necessary, I mean in start_thread() we force SR_VS_INITIAL
when has_vector = 1.

Maybe you want to distinguish different processes with/without vector?


> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
@ 2020-05-31 15:29     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:29 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Nick Knight, palmerdabbelt, Linux Kernel Mailing List,
	oleg, Vincent Chen, Paul Walmsley, linux-riscv

Hi Greentime,

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
Is this necessary, I mean in start_thread() we force SR_VS_INITIAL
when has_vector = 1.

Maybe you want to distinguish different processes with/without vector?


> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
  2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
@ 2020-05-31 15:52   ` Guo Ren
  2020-05-26  7:02 ` [RFC PATCH v4 02/13] riscv: Separate patch for cflags and aflags Greentime Hu
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:52 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg

Hi Greentime & Vincent,

Thx for the dynamic vlen implementation. I've two suggestions:
 - Please give out glibc patches mail URL, we need to review them together.
 - We need to consider that not all processes need vectors. Most
system processes do not have vector features, and we should not force
save/restore vector for every process.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> This patchset is based on Guo Ren's v3 patchset to add dynamic vlen vector
> support for all different kinds of vector length in riscv. To make this
> happened we defined a new __riscv_v_state in sigcontext to save the vector
> related registers. The datap pointer will be allocated dynamically in
> kernel space and it will be put right after the __riscv_v_state data
> structure to save all the vector registers in signal handler stack for user
> space. So does the implementation in ptrace, they will be saved in ubuf
> in which we put the __riscv_v_state data structure and datap pointer right
> after it for vector registers. This patchset also fixes several bugs for
> vector lazy save/restore and vtype not saving issue. It also adds new CSR
> support for vector based on the 0.9 vector spec and clean up some unused
> macros.
>
> This patchset is rebased to v5.7-rc4 and it is tested by running several
> vector programs simultaneously. It also can get the correct ucontext_t in
> signal handler and restore correct context after sigreturn. It is also
> tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
> get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
> virt machine of qemu-system-riscv32 and qemu-system-riscv64 provided by
> Zhiwei Lui.
>
> Since the vector spec is under developing, there might still need some
> changes. For example the vle.v/vse.v instructions will be replaced with
> proper instructions. The reason that I don't replace the instruction in
> this patchset is because that the Qemu doesn't fully support 0.9 spec yet.
> I have no simulator to test. We also like to discuss the default setting of
> MINSIGSTKSZ and SIGSTKSZ. They might also need to set a proper number. They
> are 2048 and 8096 now. Since the stack in signal will be reserved for
> ucontext and the vector registers might be larger and larger someday, these
> two macros will need to be defined as a proper value or maybe we should
> provide a better mechanism to provide user to get a better default signal
> stack size.
>
>
>  [1] https://github.com/romanheros/qemu/tree/linux-vector-dev
>  [2] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
>  [3] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
>
> ---
> Changelog V4
>  - Support dynamic vlen
>  - Fix bugs: lazy save/resotre, not saving vtype
>  - Update VS bit offset based on latest vector spec
>  - Add new vector csr based on latest vector spec
>  - Code refine and removed unused macros
>
> Changelog V3
>  - Rebase linux-5.6-rc3 and tested with qemu
>  - Seperate patches with Anup's advice
>  - Give out a ABI puzzle with unlimited vlen
>
> Changelog V2
>  - Fixup typo "vecotr, fstate_save->vstate_save".
>  - Fixup wrong saved registers' length in vector.S.
>  - Seperate unrelated patches from this one.
>
> Greentime Hu (1):
>   ptrace: Use regset_size() for dynamic regset size.
>
> Guo Ren (11):
>   riscv: Separate patch for cflags and aflags
>   riscv: Rename __switch_to_aux -> fpu
>   riscv: Extending cpufeature.c to detect V-extension
>   riscv: Add new csr defines related to vector extension
>   riscv: Add vector feature to compile
>   riscv: Add has_vector/riscv_vsize to save vector features.
>   riscv: Reset vector register
>   riscv: Add vector struct and assembler definitions
>   riscv: Add task switch support for vector
>   riscv: Add ptrace vector support
>   riscv: Add sigcontext save/restore for vector
>
> Vincent Chen (1):
>   riscv: signal: Report signal frame size to userspace via auxv
>
>  arch/riscv/Kconfig                       |   9 ++
>  arch/riscv/Makefile                      |  19 ++--
>  arch/riscv/include/asm/csr.h             |  16 +++-
>  arch/riscv/include/asm/elf.h             |  17 +++-
>  arch/riscv/include/asm/processor.h       |   3 +
>  arch/riscv/include/asm/switch_to.h       |  77 ++++++++++++++-
>  arch/riscv/include/uapi/asm/auxvec.h     |   2 +
>  arch/riscv/include/uapi/asm/elf.h        |   1 +
>  arch/riscv/include/uapi/asm/hwcap.h      |   1 +
>  arch/riscv/include/uapi/asm/ptrace.h     |  13 +++
>  arch/riscv/include/uapi/asm/sigcontext.h |   2 +
>  arch/riscv/kernel/Makefile               |   1 +
>  arch/riscv/kernel/asm-offsets.c          |   8 ++
>  arch/riscv/kernel/cpufeature.c           |  15 ++-
>  arch/riscv/kernel/entry.S                |   2 +-
>  arch/riscv/kernel/head.S                 |  49 +++++++++-
>  arch/riscv/kernel/process.c              |  40 ++++++++
>  arch/riscv/kernel/ptrace.c               | 114 +++++++++++++++++++++++
>  arch/riscv/kernel/setup.c                |   5 +
>  arch/riscv/kernel/signal.c               | 108 ++++++++++++++++++++-
>  arch/riscv/kernel/vector.S               |  84 +++++++++++++++++
>  include/uapi/linux/elf.h                 |   1 +
>  kernel/ptrace.c                          |  11 ++-
>  23 files changed, 573 insertions(+), 25 deletions(-)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
@ 2020-05-31 15:52   ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 15:52 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, palmerdabbelt, Linux Kernel Mailing List, oleg,
	Vincent Chen, Paul Walmsley, linux-riscv

Hi Greentime & Vincent,

Thx for the dynamic vlen implementation. I've two suggestions:
 - Please give out glibc patches mail URL, we need to review them together.
 - We need to consider that not all processes need vectors. Most
system processes do not have vector features, and we should not force
save/restore vector for every process.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> This patchset is based on Guo Ren's v3 patchset to add dynamic vlen vector
> support for all different kinds of vector length in riscv. To make this
> happened we defined a new __riscv_v_state in sigcontext to save the vector
> related registers. The datap pointer will be allocated dynamically in
> kernel space and it will be put right after the __riscv_v_state data
> structure to save all the vector registers in signal handler stack for user
> space. So does the implementation in ptrace, they will be saved in ubuf
> in which we put the __riscv_v_state data structure and datap pointer right
> after it for vector registers. This patchset also fixes several bugs for
> vector lazy save/restore and vtype not saving issue. It also adds new CSR
> support for vector based on the 0.9 vector spec and clean up some unused
> macros.
>
> This patchset is rebased to v5.7-rc4 and it is tested by running several
> vector programs simultaneously. It also can get the correct ucontext_t in
> signal handler and restore correct context after sigreturn. It is also
> tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
> get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
> virt machine of qemu-system-riscv32 and qemu-system-riscv64 provided by
> Zhiwei Lui.
>
> Since the vector spec is under developing, there might still need some
> changes. For example the vle.v/vse.v instructions will be replaced with
> proper instructions. The reason that I don't replace the instruction in
> this patchset is because that the Qemu doesn't fully support 0.9 spec yet.
> I have no simulator to test. We also like to discuss the default setting of
> MINSIGSTKSZ and SIGSTKSZ. They might also need to set a proper number. They
> are 2048 and 8096 now. Since the stack in signal will be reserved for
> ucontext and the vector registers might be larger and larger someday, these
> two macros will need to be defined as a proper value or maybe we should
> provide a better mechanism to provide user to get a better default signal
> stack size.
>
>
>  [1] https://github.com/romanheros/qemu/tree/linux-vector-dev
>  [2] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
>  [3] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
>
> ---
> Changelog V4
>  - Support dynamic vlen
>  - Fix bugs: lazy save/resotre, not saving vtype
>  - Update VS bit offset based on latest vector spec
>  - Add new vector csr based on latest vector spec
>  - Code refine and removed unused macros
>
> Changelog V3
>  - Rebase linux-5.6-rc3 and tested with qemu
>  - Seperate patches with Anup's advice
>  - Give out a ABI puzzle with unlimited vlen
>
> Changelog V2
>  - Fixup typo "vecotr, fstate_save->vstate_save".
>  - Fixup wrong saved registers' length in vector.S.
>  - Seperate unrelated patches from this one.
>
> Greentime Hu (1):
>   ptrace: Use regset_size() for dynamic regset size.
>
> Guo Ren (11):
>   riscv: Separate patch for cflags and aflags
>   riscv: Rename __switch_to_aux -> fpu
>   riscv: Extending cpufeature.c to detect V-extension
>   riscv: Add new csr defines related to vector extension
>   riscv: Add vector feature to compile
>   riscv: Add has_vector/riscv_vsize to save vector features.
>   riscv: Reset vector register
>   riscv: Add vector struct and assembler definitions
>   riscv: Add task switch support for vector
>   riscv: Add ptrace vector support
>   riscv: Add sigcontext save/restore for vector
>
> Vincent Chen (1):
>   riscv: signal: Report signal frame size to userspace via auxv
>
>  arch/riscv/Kconfig                       |   9 ++
>  arch/riscv/Makefile                      |  19 ++--
>  arch/riscv/include/asm/csr.h             |  16 +++-
>  arch/riscv/include/asm/elf.h             |  17 +++-
>  arch/riscv/include/asm/processor.h       |   3 +
>  arch/riscv/include/asm/switch_to.h       |  77 ++++++++++++++-
>  arch/riscv/include/uapi/asm/auxvec.h     |   2 +
>  arch/riscv/include/uapi/asm/elf.h        |   1 +
>  arch/riscv/include/uapi/asm/hwcap.h      |   1 +
>  arch/riscv/include/uapi/asm/ptrace.h     |  13 +++
>  arch/riscv/include/uapi/asm/sigcontext.h |   2 +
>  arch/riscv/kernel/Makefile               |   1 +
>  arch/riscv/kernel/asm-offsets.c          |   8 ++
>  arch/riscv/kernel/cpufeature.c           |  15 ++-
>  arch/riscv/kernel/entry.S                |   2 +-
>  arch/riscv/kernel/head.S                 |  49 +++++++++-
>  arch/riscv/kernel/process.c              |  40 ++++++++
>  arch/riscv/kernel/ptrace.c               | 114 +++++++++++++++++++++++
>  arch/riscv/kernel/setup.c                |   5 +
>  arch/riscv/kernel/signal.c               | 108 ++++++++++++++++++++-
>  arch/riscv/kernel/vector.S               |  84 +++++++++++++++++
>  include/uapi/linux/elf.h                 |   1 +
>  kernel/ptrace.c                          |  11 ++-
>  23 files changed, 573 insertions(+), 25 deletions(-)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
  2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
@ 2020-05-31 16:08     ` Guo Ren
  2020-05-31 16:08     ` Guo Ren
  2020-06-01  9:12     ` Guo Ren
  2 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 16:08 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, palmerdabbelt, linux-riscv,
	Linux Kernel Mailing List, oleg, Nick Knight

Hi Greentime,

Here, we could detect the task has used vector or not with VS_DIRTY:

We could define another flag in struct vs state of thread to
illustrate the task have vector or not.
When we found VS_DIRTY is set in pt_regs in swith_context or
rt_sigreturn syscall, we will set the flag.

We only need switch_context or sigcontext vector when the flag is set.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
@ 2020-05-31 16:08     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-05-31 16:08 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Nick Knight, palmerdabbelt, Linux Kernel Mailing List,
	oleg, Vincent Chen, Paul Walmsley, linux-riscv

Hi Greentime,

Here, we could detect the task has used vector or not with VS_DIRTY:

We could define another flag in struct vs state of thread to
illustrate the task have vector or not.
When we found VS_DIRTY is set in pt_regs in swith_context or
rt_sigreturn syscall, we will set the flag.

We only need switch_context or sigcontext vector when the flag is set.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
  2020-05-31  0:58     ` Guo Ren
@ 2020-06-01  8:07       ` Greentime Hu
  -1 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-01  8:07 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午8:58寫道:
>
> Reviewed-by: Guo Ren <guoren@kernel.org>
>
> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > This patch is used to detect vector support status of CPU and use
> > riscv_vsize to save the size of all the vector registers. It assumes
> > all harts has the same capabilities in SMP system.
> >
> > [greentime.hu@sifive.com: add support for dynamic vlen]
> > Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > ---
> >  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > index c8527d770c98..5a68a926da68 100644
> > --- a/arch/riscv/kernel/cpufeature.c
> > +++ b/arch/riscv/kernel/cpufeature.c
> > @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
> >  #ifdef CONFIG_FPU
> >  bool has_fpu __read_mostly;
> >  #endif
> > +#ifdef CONFIG_VECTOR
> > +bool has_vector __read_mostly;
> > +unsigned long riscv_vsize __read_mostly;
> > +#endif
> >
> >  void riscv_fill_hwcap(void)
> >  {
> > @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
> >         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
> >                 has_fpu = true;
> >  #endif
> > +
> > +#ifdef CONFIG_VECTOR
> > +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> > +               has_vector = true;
> > +               riscv_vsize = csr_read(CSR_VLENB) * 32;
> No magic number 32.
> eg:
> #define VECTOR_REGS_NUM 32
>

Hi Guo,

Thanks.
I'll replace it with a defined macro or adding comments since it is
used only once.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
@ 2020-06-01  8:07       ` Greentime Hu
  0 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-01  8:07 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午8:58寫道:
>
> Reviewed-by: Guo Ren <guoren@kernel.org>
>
> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > This patch is used to detect vector support status of CPU and use
> > riscv_vsize to save the size of all the vector registers. It assumes
> > all harts has the same capabilities in SMP system.
> >
> > [greentime.hu@sifive.com: add support for dynamic vlen]
> > Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > ---
> >  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > index c8527d770c98..5a68a926da68 100644
> > --- a/arch/riscv/kernel/cpufeature.c
> > +++ b/arch/riscv/kernel/cpufeature.c
> > @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
> >  #ifdef CONFIG_FPU
> >  bool has_fpu __read_mostly;
> >  #endif
> > +#ifdef CONFIG_VECTOR
> > +bool has_vector __read_mostly;
> > +unsigned long riscv_vsize __read_mostly;
> > +#endif
> >
> >  void riscv_fill_hwcap(void)
> >  {
> > @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
> >         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
> >                 has_fpu = true;
> >  #endif
> > +
> > +#ifdef CONFIG_VECTOR
> > +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> > +               has_vector = true;
> > +               riscv_vsize = csr_read(CSR_VLENB) * 32;
> No magic number 32.
> eg:
> #define VECTOR_REGS_NUM 32
>

Hi Guo,

Thanks.
I'll replace it with a defined macro or adding comments since it is
used only once.


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
  2020-05-31  1:56     ` Guo Ren
@ 2020-06-01  8:15       ` Greentime Hu
  -1 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-01  8:15 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午9:56寫道:
>
> Hi Greentime,
>
> Why remove vxrm and xstat ?
>
> > Appendix B: Calling Convention
> > In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> > The vxrm and vxsat fields have thread storage duration.
>
Hi Guo,

https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-control-and-status-register-vcsr
"The vxrm and vxsat separate CSRs can also be accessed via fields in
the vector control and status CSR, vcsr."

Since vcsr will save all these information, I think it should be ok to
save vcsr only.

> As spec 0.9 mentioned above, vxrm and vxsat are thread storage duration.
>
> When timer 's interrupt coming, we still need to save them in context_switch.
>
> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > Follow the riscv vector spec to add new csr number.
> >
> > [greentime.hu@sifive.com: update the defined value based on new spec and
> > remove unused ones]
> > Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > ---
> >  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
> >  1 file changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> > index 8e18d2c64399..cc13626c4bbe 100644
> > --- a/arch/riscv/include/asm/csr.h
> > +++ b/arch/riscv/include/asm/csr.h
> > @@ -24,6 +24,12 @@
> >  #define SR_FS_CLEAN    _AC(0x00004000, UL)
> >  #define SR_FS_DIRTY    _AC(0x00006000, UL)
> >
> > +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> > +#define SR_VS_OFF       _AC(0x00000000, UL)
> > +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> > +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> > +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> > +
> >  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
> >  #define SR_XS_OFF      _AC(0x00000000, UL)
> >  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> > @@ -31,9 +37,9 @@
> >  #define SR_XS_DIRTY    _AC(0x00018000, UL)
> >
> >  #ifndef CONFIG_64BIT
> > -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> > +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
> >  #else
> > -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> > +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
> >  #endif
> >
> >  /* SATP flags */
> > @@ -114,6 +120,12 @@
> >  #define CSR_PMPADDR0           0x3b0
> >  #define CSR_MHARTID            0xf14
> >
> > +#define CSR_VSTART             0x8
> > +#define CSR_VCSR               0xf
> > +#define CSR_VL                 0xc20
> > +#define CSR_VTYPE              0xc21
> > +#define CSR_VLENB              0xc22
> > +
> >  #ifdef CONFIG_RISCV_M_MODE
> >  # define CSR_STATUS    CSR_MSTATUS
> >  # define CSR_IE                CSR_MIE
> > --
> > 2.26.2
> >
> >
>
>
> --
> Best Regards
>  Guo Ren
>
> ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
@ 2020-06-01  8:15       ` Greentime Hu
  0 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-01  8:15 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午9:56寫道:
>
> Hi Greentime,
>
> Why remove vxrm and xstat ?
>
> > Appendix B: Calling Convention
> > In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> > The vxrm and vxsat fields have thread storage duration.
>
Hi Guo,

https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-control-and-status-register-vcsr
"The vxrm and vxsat separate CSRs can also be accessed via fields in
the vector control and status CSR, vcsr."

Since vcsr will save all these information, I think it should be ok to
save vcsr only.

> As spec 0.9 mentioned above, vxrm and vxsat are thread storage duration.
>
> When timer 's interrupt coming, we still need to save them in context_switch.
>
> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > Follow the riscv vector spec to add new csr number.
> >
> > [greentime.hu@sifive.com: update the defined value based on new spec and
> > remove unused ones]
> > Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > ---
> >  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
> >  1 file changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> > index 8e18d2c64399..cc13626c4bbe 100644
> > --- a/arch/riscv/include/asm/csr.h
> > +++ b/arch/riscv/include/asm/csr.h
> > @@ -24,6 +24,12 @@
> >  #define SR_FS_CLEAN    _AC(0x00004000, UL)
> >  #define SR_FS_DIRTY    _AC(0x00006000, UL)
> >
> > +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> > +#define SR_VS_OFF       _AC(0x00000000, UL)
> > +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> > +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> > +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> > +
> >  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
> >  #define SR_XS_OFF      _AC(0x00000000, UL)
> >  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> > @@ -31,9 +37,9 @@
> >  #define SR_XS_DIRTY    _AC(0x00018000, UL)
> >
> >  #ifndef CONFIG_64BIT
> > -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> > +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
> >  #else
> > -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> > +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
> >  #endif
> >
> >  /* SATP flags */
> > @@ -114,6 +120,12 @@
> >  #define CSR_PMPADDR0           0x3b0
> >  #define CSR_MHARTID            0xf14
> >
> > +#define CSR_VSTART             0x8
> > +#define CSR_VCSR               0xf
> > +#define CSR_VL                 0xc20
> > +#define CSR_VTYPE              0xc21
> > +#define CSR_VLENB              0xc22
> > +
> >  #ifdef CONFIG_RISCV_M_MODE
> >  # define CSR_STATUS    CSR_MSTATUS
> >  # define CSR_IE                CSR_MIE
> > --
> > 2.26.2
> >
> >
>
>
> --
> Best Regards
>  Guo Ren
>
> ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
  2020-06-01  8:15       ` Greentime Hu
@ 2020-06-01  8:59         ` Guo Ren
  -1 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  8:59 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

On Mon, Jun 1, 2020 at 4:15 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午9:56寫道:
> >
> > Hi Greentime,
> >
> > Why remove vxrm and xstat ?
> >
> > > Appendix B: Calling Convention
> > > In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> > > The vxrm and vxsat fields have thread storage duration.
> >
> Hi Guo,
>
> https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-control-and-status-register-vcsr
> "The vxrm and vxsat separate CSRs can also be accessed via fields in
> the vector control and status CSR, vcsr."
>
> Since vcsr will save all these information, I think it should be ok to
> save vcsr only.

Got it, it's similar with fcsr & frm & fflags.

Acked-by: Guo Ren <guoren@kernel.org>

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
@ 2020-06-01  8:59         ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  8:59 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

On Mon, Jun 1, 2020 at 4:15 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 上午9:56寫道:
> >
> > Hi Greentime,
> >
> > Why remove vxrm and xstat ?
> >
> > > Appendix B: Calling Convention
> > > In the RISC-V psABI, the vector registers v0-v31 are all caller-saved. The vstart, vl, and vtype CSRs are also caller-saved.
> > > The vxrm and vxsat fields have thread storage duration.
> >
> Hi Guo,
>
> https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-control-and-status-register-vcsr
> "The vxrm and vxsat separate CSRs can also be accessed via fields in
> the vector control and status CSR, vcsr."
>
> Since vcsr will save all these information, I think it should be ok to
> save vcsr only.

Got it, it's similar with fcsr & frm & fflags.

Acked-by: Guo Ren <guoren@kernel.org>

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
  2020-05-26  7:02 ` [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension Greentime Hu
@ 2020-06-01  9:03     ` Guo Ren
  2020-06-01  9:03     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:03 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Follow the riscv vector spec to add new csr number.
>
> [greentime.hu@sifive.com: update the defined value based on new spec and
> remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index 8e18d2c64399..cc13626c4bbe 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -24,6 +24,12 @@
>  #define SR_FS_CLEAN    _AC(0x00004000, UL)
>  #define SR_FS_DIRTY    _AC(0x00006000, UL)
>
> +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> +#define SR_VS_OFF       _AC(0x00000000, UL)
> +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> +
>  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
>  #define SR_XS_OFF      _AC(0x00000000, UL)
>  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> @@ -31,9 +37,9 @@
>  #define SR_XS_DIRTY    _AC(0x00018000, UL)
>
>  #ifndef CONFIG_64BIT
> -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
>  #else
> -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
>  #endif
>
>  /* SATP flags */
> @@ -114,6 +120,12 @@
>  #define CSR_PMPADDR0           0x3b0
>  #define CSR_MHARTID            0xf14
>
> +#define CSR_VSTART             0x8
> +#define CSR_VCSR               0xf
> +#define CSR_VL                 0xc20
> +#define CSR_VTYPE              0xc21
> +#define CSR_VLENB              0xc22
> +
>  #ifdef CONFIG_RISCV_M_MODE
>  # define CSR_STATUS    CSR_MSTATUS
>  # define CSR_IE                CSR_MIE
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension
@ 2020-06-01  9:03     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:03 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Follow the riscv vector spec to add new csr number.
>
> [greentime.hu@sifive.com: update the defined value based on new spec and
> remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/csr.h | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
> index 8e18d2c64399..cc13626c4bbe 100644
> --- a/arch/riscv/include/asm/csr.h
> +++ b/arch/riscv/include/asm/csr.h
> @@ -24,6 +24,12 @@
>  #define SR_FS_CLEAN    _AC(0x00004000, UL)
>  #define SR_FS_DIRTY    _AC(0x00006000, UL)
>
> +#define SR_VS           _AC(0x00000600, UL) /* Vector Status */
> +#define SR_VS_OFF       _AC(0x00000000, UL)
> +#define SR_VS_INITIAL   _AC(0x00000200, UL)
> +#define SR_VS_CLEAN     _AC(0x00000400, UL)
> +#define SR_VS_DIRTY     _AC(0x00000600, UL)
> +
>  #define SR_XS          _AC(0x00018000, UL) /* Extension Status */
>  #define SR_XS_OFF      _AC(0x00000000, UL)
>  #define SR_XS_INITIAL  _AC(0x00008000, UL)
> @@ -31,9 +37,9 @@
>  #define SR_XS_DIRTY    _AC(0x00018000, UL)
>
>  #ifndef CONFIG_64BIT
> -#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x80000000, UL) /* FS/VS/XS dirty */
>  #else
> -#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
> +#define SR_SD          _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
>  #endif
>
>  /* SATP flags */
> @@ -114,6 +120,12 @@
>  #define CSR_PMPADDR0           0x3b0
>  #define CSR_MHARTID            0xf14
>
> +#define CSR_VSTART             0x8
> +#define CSR_VCSR               0xf
> +#define CSR_VL                 0xc20
> +#define CSR_VTYPE              0xc21
> +#define CSR_VLENB              0xc22
> +
>  #ifdef CONFIG_RISCV_M_MODE
>  # define CSR_STATUS    CSR_MSTATUS
>  # define CSR_IE                CSR_MIE
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions
  2020-05-26  7:02 ` [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions Greentime Hu
@ 2020-06-01  9:12     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:12 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Add vector state context struct in struct thread and asm-offsets.c
> definitions.
>
> The vector registers will be saved in datap pointer of __riscv_v_state. It
> will be dynamically allocated in kernel space. It will be put right after
> the __riscv_v_state data structure in user space.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, add vcsr and remove
> vxsat, vxrm because these data can be get in vcsr, add new macros for
> _riscv_v_state elements offset and remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/processor.h   |  1 +
>  arch/riscv/include/uapi/asm/ptrace.h | 13 +++++++++++++
>  arch/riscv/kernel/asm-offsets.c      |  8 ++++++++
>  3 files changed, 22 insertions(+)
>
> diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
> index 3ddb798264f1..217273375cfb 100644
> --- a/arch/riscv/include/asm/processor.h
> +++ b/arch/riscv/include/asm/processor.h
> @@ -32,6 +32,7 @@ struct thread_struct {
>         unsigned long sp;       /* Kernel mode stack */
>         unsigned long s[12];    /* s[0]: frame pointer */
>         struct __riscv_d_ext_state fstate;
> +       struct __riscv_v_state vstate;
>  };
>
>  #define INIT_THREAD {                                  \
> diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
> index 882547f6bd5c..661b0466b850 100644
> --- a/arch/riscv/include/uapi/asm/ptrace.h
> +++ b/arch/riscv/include/uapi/asm/ptrace.h
> @@ -77,6 +77,19 @@ union __riscv_fp_state {
>         struct __riscv_q_ext_state q;
>  };
>
> +struct __riscv_v_state {
> +       __u32 magic;
> +       __u32 size;
> +       unsigned long vstart;
> +       unsigned long vl;
> +       unsigned long vtype;
> +       unsigned long vcsr;
> +       void *datap;
> +#if __riscv_xlen == 32
> +       __u32 __padding;
> +#endif
> +} __attribute__((aligned(16)));
> +
>  #endif /* __ASSEMBLY__ */
>
>  #endif /* _UAPI_ASM_RISCV_PTRACE_H */
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index 07cb9c10de4e..6627fde230b2 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -70,6 +70,14 @@ void asm_offsets(void)
>         OFFSET(TASK_THREAD_F31, task_struct, thread.fstate.f[31]);
>         OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
>
> +       OFFSET(RISCV_V_STATE_MAGIC, __riscv_v_state, magic);
> +       OFFSET(RISCV_V_STATE_SIZE, __riscv_v_state, size);
> +       OFFSET(RISCV_V_STATE_VSTART, __riscv_v_state, vstart);
> +       OFFSET(RISCV_V_STATE_VL, __riscv_v_state, vl);
> +       OFFSET(RISCV_V_STATE_VTYPE, __riscv_v_state, vtype);
> +       OFFSET(RISCV_V_STATE_VCSR, __riscv_v_state, vcsr);
> +       OFFSET(RISCV_V_STATE_DATAP, __riscv_v_state, datap);
> +
>         DEFINE(PT_SIZE, sizeof(struct pt_regs));
>         OFFSET(PT_EPC, pt_regs, epc);
>         OFFSET(PT_RA, pt_regs, ra);
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions
@ 2020-06-01  9:12     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:12 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> Add vector state context struct in struct thread and asm-offsets.c
> definitions.
>
> The vector registers will be saved in datap pointer of __riscv_v_state. It
> will be dynamically allocated in kernel space. It will be put right after
> the __riscv_v_state data structure in user space.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, add vcsr and remove
> vxsat, vxrm because these data can be get in vcsr, add new macros for
> _riscv_v_state elements offset and remove unused ones]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/processor.h   |  1 +
>  arch/riscv/include/uapi/asm/ptrace.h | 13 +++++++++++++
>  arch/riscv/kernel/asm-offsets.c      |  8 ++++++++
>  3 files changed, 22 insertions(+)
>
> diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
> index 3ddb798264f1..217273375cfb 100644
> --- a/arch/riscv/include/asm/processor.h
> +++ b/arch/riscv/include/asm/processor.h
> @@ -32,6 +32,7 @@ struct thread_struct {
>         unsigned long sp;       /* Kernel mode stack */
>         unsigned long s[12];    /* s[0]: frame pointer */
>         struct __riscv_d_ext_state fstate;
> +       struct __riscv_v_state vstate;
>  };
>
>  #define INIT_THREAD {                                  \
> diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
> index 882547f6bd5c..661b0466b850 100644
> --- a/arch/riscv/include/uapi/asm/ptrace.h
> +++ b/arch/riscv/include/uapi/asm/ptrace.h
> @@ -77,6 +77,19 @@ union __riscv_fp_state {
>         struct __riscv_q_ext_state q;
>  };
>
> +struct __riscv_v_state {
> +       __u32 magic;
> +       __u32 size;
> +       unsigned long vstart;
> +       unsigned long vl;
> +       unsigned long vtype;
> +       unsigned long vcsr;
> +       void *datap;
> +#if __riscv_xlen == 32
> +       __u32 __padding;
> +#endif
> +} __attribute__((aligned(16)));
> +
>  #endif /* __ASSEMBLY__ */
>
>  #endif /* _UAPI_ASM_RISCV_PTRACE_H */
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index 07cb9c10de4e..6627fde230b2 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -70,6 +70,14 @@ void asm_offsets(void)
>         OFFSET(TASK_THREAD_F31, task_struct, thread.fstate.f[31]);
>         OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
>
> +       OFFSET(RISCV_V_STATE_MAGIC, __riscv_v_state, magic);
> +       OFFSET(RISCV_V_STATE_SIZE, __riscv_v_state, size);
> +       OFFSET(RISCV_V_STATE_VSTART, __riscv_v_state, vstart);
> +       OFFSET(RISCV_V_STATE_VL, __riscv_v_state, vl);
> +       OFFSET(RISCV_V_STATE_VTYPE, __riscv_v_state, vtype);
> +       OFFSET(RISCV_V_STATE_VCSR, __riscv_v_state, vcsr);
> +       OFFSET(RISCV_V_STATE_DATAP, __riscv_v_state, datap);
> +
>         DEFINE(PT_SIZE, sizeof(struct pt_regs));
>         OFFSET(PT_EPC, pt_regs, epc);
>         OFFSET(PT_RA, pt_regs, ra);
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
  2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
@ 2020-06-01  9:12     ` Guo Ren
  2020-05-31 16:08     ` Guo Ren
  2020-06-01  9:12     ` Guo Ren
  2 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:12 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov,
	Nick Knight

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 10/13] riscv: Add task switch support for vector
@ 2020-06-01  9:12     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:12 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Nick Knight, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds task switch support for vector. It supports lazy
> save and restore mechanism. It also supports all lengths of vlen.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix
> __vstate_clean() and lazy save/restore bug]
> [nick.knight@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
> code refine]
> Signed-off-by: Nick Knight <nick.knight@sifive.com>
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/asm/switch_to.h | 71 +++++++++++++++++++++++++
>  arch/riscv/kernel/Makefile         |  1 +
>  arch/riscv/kernel/process.c        | 40 ++++++++++++++
>  arch/riscv/kernel/vector.S         | 84 ++++++++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 arch/riscv/kernel/vector.S
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index b9234e7178d0..a047dd75e09d 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -6,10 +6,12 @@
>  #ifndef _ASM_RISCV_SWITCH_TO_H
>  #define _ASM_RISCV_SWITCH_TO_H
>
> +#include <linux/slab.h>
>  #include <linux/sched/task_stack.h>
>  #include <asm/processor.h>
>  #include <asm/ptrace.h>
>  #include <asm/csr.h>
> +#include <asm/asm-offsets.h>
>
>  #ifdef CONFIG_FPU
>  extern void __fstate_save(struct task_struct *save_to);
> @@ -63,6 +65,73 @@ extern bool has_fpu;
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +extern bool has_vector;
> +extern unsigned long riscv_vsize;
> +extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
> +extern void __vstate_restore(struct __riscv_v_state *restore_from, void *datap);
> +
> +static inline void __vstate_clean(struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
> +}
> +
> +static inline void vstate_off(struct task_struct *task,
> +                             struct pt_regs *regs)
> +{
> +       regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
> +}
> +
> +static inline void vstate_save(struct task_struct *task,
> +                              struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) == SR_VS_DIRTY) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_save(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void vstate_restore(struct task_struct *task,
> +                                 struct pt_regs *regs)
> +{
> +       if ((regs->status & SR_VS) != SR_VS_OFF) {
> +               struct __riscv_v_state *vstate = &(task->thread.vstate);
> +
> +               /* Allocate space for vector registers. */
> +               if (!vstate->datap) {
> +                       vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
> +                       vstate->size = riscv_vsize;
> +               }
> +               __vstate_restore(vstate, vstate->datap);
> +               __vstate_clean(regs);
> +       }
> +}
> +
> +static inline void __switch_to_vector(struct task_struct *prev,
> +                                  struct task_struct *next)
> +{
> +       struct pt_regs *regs;
> +
> +       regs = task_pt_regs(prev);
> +       if (unlikely(regs->status & SR_SD))
> +               vstate_save(prev, regs);
> +       vstate_restore(next, task_pt_regs(next));
> +}
> +
> +#else
> +#define has_vector false
> +#define vstate_save(task, regs) do { } while (0)
> +#define vstate_restore(task, regs) do { } while (0)
> +#define __switch_to_vector(__prev, __next) do { } while (0)
> +#endif
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>                                        struct task_struct *);
>
> @@ -72,6 +141,8 @@ do {                                                 \
>         struct task_struct *__next = (next);            \
>         if (has_fpu)                                    \
>                 __switch_to_fpu(__prev, __next);        \
> +       if (has_vector)                                 \
> +               __switch_to_vector(__prev, __next);     \
>         ((last) = __switch_to(__prev, __next));         \
>  } while (0)
>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 86c83081044f..dee489a1a526 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
>
>  obj-$(CONFIG_RISCV_M_MODE)     += clint.o traps_misaligned.o
>  obj-$(CONFIG_FPU)              += fpu.o
> +obj-$(CONFIG_VECTOR)           += vector.o
>  obj-$(CONFIG_SMP)              += smpboot.o
>  obj-$(CONFIG_SMP)              += smp.o
>  obj-$(CONFIG_SMP)              += cpu_ops.o
> diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
> index 610c11e91606..fc8761c04e9f 100644
> --- a/arch/riscv/kernel/process.c
> +++ b/arch/riscv/kernel/process.c
> @@ -76,6 +76,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
>                  */
>                 fstate_restore(current, regs);
>         }
> +
> +       if (has_vector) {
> +               regs->status |= SR_VS_INITIAL;
> +               /*
> +                * Restore the initial value to the vector register
> +                * before starting the user program.
> +                */
> +               vstate_restore(current, regs);
> +       }
> +
>         regs->epc = pc;
>         regs->sp = sp;
>         set_fs(USER_DS);
> @@ -92,15 +102,45 @@ void flush_thread(void)
>         fstate_off(current, task_pt_regs(current));
>         memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
>  #endif
> +#ifdef CONFIG_VECTOR
> +       /* Reset vector state */
> +       vstate_off(current, task_pt_regs(current));
> +       memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
> +#endif
>  }
>
>  int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  {
>         fstate_save(src, task_pt_regs(src));
> +       if (has_vector)
> +               /* To make sure every dirty vector context is saved. */
> +               vstate_save(src, task_pt_regs(src));
>         *dst = *src;
> +       if (has_vector) {
> +               /* Copy vector context to the forked task from parent. */
> +               if ((task_pt_regs(src)->status & SR_VS) != SR_VS_OFF) {
> +                       unsigned long size = src->thread.vstate.size;
> +
> +                       dst->thread.vstate.datap = kzalloc(size, GFP_KERNEL);
> +                       /* Failed to allocate memory. */
> +                       if (!dst->thread.vstate.datap)
> +                               return -ENOMEM;
> +                       /* Copy the src vector context to dst. */
> +                       memcpy(dst->thread.vstate.datap,
> +                              src->thread.vstate.datap, size);
> +               }
> +       }
> +
>         return 0;
>  }
>
> +void arch_release_task_struct(struct task_struct *tsk)
> +{
> +       /* Free the vector context of datap. */
> +       if (has_vector)
> +               kfree(tsk->thread.vstate.datap);
> +}
> +
>  int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
>         unsigned long arg, struct task_struct *p, unsigned long tls)
>  {
> diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
> new file mode 100644
> index 000000000000..91d5dd29cd0f
> --- /dev/null
> +++ b/arch/riscv/kernel/vector.S
> @@ -0,0 +1,84 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2019 Alibaba Group Holding Limited
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include <linux/linkage.h>
> +
> +#include <asm/asm.h>
> +#include <asm/csr.h>
> +#include <asm/asm-offsets.h>
> +
> +#define vstatep  a0
> +#define datap    a1
> +#define x_vstart t0
> +#define x_vtype  t1
> +#define x_vl     t2
> +#define x_vcsr   t3
> +#define incr     t4
> +#define m_one    t5
> +#define status   t6
> +
> +ENTRY(__vstate_save)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       csrr    x_vstart, CSR_VSTART
> +       csrr    x_vtype, CSR_VTYPE
> +       csrr    x_vl, CSR_VL
> +       csrr    x_vcsr, CSR_VCSR
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vse.v   v0, (datap)
> +       add     datap, datap, incr
> +       vse.v   v8, (datap)
> +       add     datap, datap, incr
> +       vse.v   v16, (datap)
> +       add     datap, datap, incr
> +       vse.v   v24, (datap)
> +
> +       REG_S   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_S   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_save)
> +
> +ENTRY(__vstate_restore)
> +       li      status, SR_VS
> +       csrs    sstatus, status
> +
> +       li      m_one, -1
> +       vsetvli incr, m_one, e8, m8
> +       vle.v   v0, (datap)
> +       add     datap, datap, incr
> +       vle.v   v8, (datap)
> +       add     datap, datap, incr
> +       vle.v   v16, (datap)
> +       add     datap, datap, incr
> +       vle.v   v24, (datap)
> +
> +       REG_L   x_vstart, RISCV_V_STATE_VSTART(vstatep)
> +       REG_L   x_vtype, RISCV_V_STATE_VTYPE(vstatep)
> +       REG_L   x_vl, RISCV_V_STATE_VL(vstatep)
> +       REG_L   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
> +       vsetvl  x0, x_vl, x_vtype
> +       csrw    CSR_VSTART, x_vstart
> +       csrw    CSR_VCSR, x_vcsr
> +
> +       csrc    sstatus, status
> +       ret
> +ENDPROC(__vstate_restore)
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector
  2020-05-26  7:02 ` [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector Greentime Hu
@ 2020-06-01  9:13     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:13 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds sigcontext save/restore for vector. The vector registers
> will be saved in datap pointer. The datap pointer will be allocaed
> dynamically when the task needs in kernel space. The datap pointer will
> be set right after the __riscv_v_state data structure to save all the
> vector registers in the signal handler stack.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/sigcontext.h |  2 +
>  arch/riscv/kernel/signal.c               | 92 +++++++++++++++++++++++-
>  2 files changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
> index 84f2dfcfdbce..4217f3f1c8ba 100644
> --- a/arch/riscv/include/uapi/asm/sigcontext.h
> +++ b/arch/riscv/include/uapi/asm/sigcontext.h
> @@ -8,6 +8,7 @@
>
>  #include <asm/ptrace.h>
>
> +#define RVV_MAGIC      0x53465457
>  /*
>   * Signal context structure
>   *
> @@ -17,6 +18,7 @@
>  struct sigcontext {
>         struct user_regs_struct sc_regs;
>         union __riscv_fp_state sc_fpregs;
> +       struct __riscv_v_state sc_vregs;
>  };
>
>  #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index 17ba190e84a5..9ada6f74bb95 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
>  #define restore_fp_state(task, regs) (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       void *datap;
> +       __u32 magic;
> +
> +       /* Get magic number and check it. */
> +       err = __get_user(magic, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       if (magic != RVV_MAGIC)
> +               return -EINVAL;
> +
> +       /* Copy everything of __riscv_v_state except datap. */
> +       err = __copy_from_user(&current->thread.vstate, state,
> +                              RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __get_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +
> +       /* Copy the whole vector content from user space datap. */
> +       err = __copy_from_user(current->thread.vstate.datap, datap,
> +                              current->thread.vstate.size);
> +       if (unlikely(err))
> +               return err;
> +
> +       vstate_restore(current, regs);
> +
> +       return err;
> +}
> +
> +static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       /* Set the datap right after the sigcntext structure. */
> +       void *datap = sc + 1;
> +
> +       vstate_save(current, regs);
> +       /* Copy everything of vstate but datap. */
> +       err = __copy_to_user(state, &current->thread.vstate,
> +                            RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the magic number. */
> +       err = __put_user(RVV_MAGIC, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __put_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the whole vector content to user space datap. */
> +       err = __copy_to_user(datap, current->thread.vstate.datap,
> +                            current->thread.vstate.size);
> +
> +       return err;
> +}
> +#else
> +#define save_v_state(task, regs) (0)
> +#define restore_v_state(task, regs) (0)
> +#endif
> +
>  static long restore_sigcontext(struct pt_regs *regs,
>         struct sigcontext __user *sc)
>  {
> @@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
>         /* Restore the floating-point state. */
>         if (has_fpu)
>                 err |= restore_fp_state(regs, &sc->sc_fpregs);
> +       /* Restore the vector state. */
> +       if (has_vector)
> +               err |= restore_v_state(regs, sc);
>         return err;
>  }
>
> @@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
>         struct rt_sigframe __user *frame;
>         struct task_struct *task;
>         sigset_t set;
> +       size_t frame_size = sizeof(*frame);
>
>         /* Always make any pending restarted system calls return -EINTR */
>         current->restart_block.fn = do_no_restart_syscall;
>
>         frame = (struct rt_sigframe __user *)regs->sp;
>
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       if (!access_ok(frame, frame_size))
>                 goto badframe;
>
>         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
> @@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
>         /* Save the floating-point state. */
>         if (has_fpu)
>                 err |= save_fp_state(regs, &sc->sc_fpregs);
> +       /* Save the vector state. */
> +       if (has_vector)
> +               err |= save_v_state(regs, sc);
>         return err;
>  }
>
> @@ -176,9 +259,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>  {
>         struct rt_sigframe __user *frame;
>         long err = 0;
> +       size_t frame_size = sizeof(*frame);
>
> -       frame = get_sigframe(ksig, regs, sizeof(*frame));
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       frame = get_sigframe(ksig, regs, frame_size);
> +       if (!access_ok(frame, frame_size))
>                 return -EFAULT;
>
>         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector
@ 2020-06-01  9:13     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:13 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds sigcontext save/restore for vector. The vector registers
> will be saved in datap pointer. The datap pointer will be allocaed
> dynamically when the task needs in kernel space. The datap pointer will
> be set right after the __riscv_v_state data structure to save all the
> vector registers in the signal handler stack.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/sigcontext.h |  2 +
>  arch/riscv/kernel/signal.c               | 92 +++++++++++++++++++++++-
>  2 files changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
> index 84f2dfcfdbce..4217f3f1c8ba 100644
> --- a/arch/riscv/include/uapi/asm/sigcontext.h
> +++ b/arch/riscv/include/uapi/asm/sigcontext.h
> @@ -8,6 +8,7 @@
>
>  #include <asm/ptrace.h>
>
> +#define RVV_MAGIC      0x53465457
>  /*
>   * Signal context structure
>   *
> @@ -17,6 +18,7 @@
>  struct sigcontext {
>         struct user_regs_struct sc_regs;
>         union __riscv_fp_state sc_fpregs;
> +       struct __riscv_v_state sc_vregs;
>  };
>
>  #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
> index 17ba190e84a5..9ada6f74bb95 100644
> --- a/arch/riscv/kernel/signal.c
> +++ b/arch/riscv/kernel/signal.c
> @@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
>  #define restore_fp_state(task, regs) (0)
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       void *datap;
> +       __u32 magic;
> +
> +       /* Get magic number and check it. */
> +       err = __get_user(magic, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       if (magic != RVV_MAGIC)
> +               return -EINVAL;
> +
> +       /* Copy everything of __riscv_v_state except datap. */
> +       err = __copy_from_user(&current->thread.vstate, state,
> +                              RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __get_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +
> +       /* Copy the whole vector content from user space datap. */
> +       err = __copy_from_user(current->thread.vstate.datap, datap,
> +                              current->thread.vstate.size);
> +       if (unlikely(err))
> +               return err;
> +
> +       vstate_restore(current, regs);
> +
> +       return err;
> +}
> +
> +static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
> +{
> +       long err;
> +       struct __riscv_v_state __user *state = &sc->sc_vregs;
> +       /* Set the datap right after the sigcntext structure. */
> +       void *datap = sc + 1;
> +
> +       vstate_save(current, regs);
> +       /* Copy everything of vstate but datap. */
> +       err = __copy_to_user(state, &current->thread.vstate,
> +                            RISCV_V_STATE_DATAP);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the magic number. */
> +       err = __put_user(RVV_MAGIC, &state->magic);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the pointer datap itself. */
> +       err = __put_user(datap, &state->datap);
> +       if (unlikely(err))
> +               return err;
> +
> +       /* Copy the whole vector content to user space datap. */
> +       err = __copy_to_user(datap, current->thread.vstate.datap,
> +                            current->thread.vstate.size);
> +
> +       return err;
> +}
> +#else
> +#define save_v_state(task, regs) (0)
> +#define restore_v_state(task, regs) (0)
> +#endif
> +
>  static long restore_sigcontext(struct pt_regs *regs,
>         struct sigcontext __user *sc)
>  {
> @@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
>         /* Restore the floating-point state. */
>         if (has_fpu)
>                 err |= restore_fp_state(regs, &sc->sc_fpregs);
> +       /* Restore the vector state. */
> +       if (has_vector)
> +               err |= restore_v_state(regs, sc);
>         return err;
>  }
>
> @@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
>         struct rt_sigframe __user *frame;
>         struct task_struct *task;
>         sigset_t set;
> +       size_t frame_size = sizeof(*frame);
>
>         /* Always make any pending restarted system calls return -EINTR */
>         current->restart_block.fn = do_no_restart_syscall;
>
>         frame = (struct rt_sigframe __user *)regs->sp;
>
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       if (!access_ok(frame, frame_size))
>                 goto badframe;
>
>         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
> @@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
>         /* Save the floating-point state. */
>         if (has_fpu)
>                 err |= save_fp_state(regs, &sc->sc_fpregs);
> +       /* Save the vector state. */
> +       if (has_vector)
> +               err |= save_v_state(regs, sc);
>         return err;
>  }
>
> @@ -176,9 +259,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>  {
>         struct rt_sigframe __user *frame;
>         long err = 0;
> +       size_t frame_size = sizeof(*frame);
>
> -       frame = get_sigframe(ksig, regs, sizeof(*frame));
> -       if (!access_ok(frame, sizeof(*frame)))
> +       if (has_vector)
> +               frame_size += current->thread.vstate.size;
> +       frame = get_sigframe(ksig, regs, frame_size);
> +       if (!access_ok(frame, frame_size))
>                 return -EFAULT;
>
>         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
  2020-05-26  7:02 ` [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features Greentime Hu
@ 2020-06-01  9:13     ` Guo Ren
  2020-06-01  9:13     ` Guo Ren
  1 sibling, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:13 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch is used to detect vector support status of CPU and use
> riscv_vsize to save the size of all the vector registers. It assumes
> all harts has the same capabilities in SMP system.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index c8527d770c98..5a68a926da68 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
>  #ifdef CONFIG_FPU
>  bool has_fpu __read_mostly;
>  #endif
> +#ifdef CONFIG_VECTOR
> +bool has_vector __read_mostly;
> +unsigned long riscv_vsize __read_mostly;
> +#endif
>
>  void riscv_fill_hwcap(void)
>  {
> @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
>         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
>                 has_fpu = true;
>  #endif
> +
> +#ifdef CONFIG_VECTOR
> +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> +               has_vector = true;
> +               riscv_vsize = csr_read(CSR_VLENB) * 32;
> +       }
> +#endif
>  }
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features.
@ 2020-06-01  9:13     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:13 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch is used to detect vector support status of CPU and use
> riscv_vsize to save the size of all the vector registers. It assumes
> all harts has the same capabilities in SMP system.
>
> [greentime.hu@sifive.com: add support for dynamic vlen]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/kernel/cpufeature.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index c8527d770c98..5a68a926da68 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -16,6 +16,10 @@ unsigned long elf_hwcap __read_mostly;
>  #ifdef CONFIG_FPU
>  bool has_fpu __read_mostly;
>  #endif
> +#ifdef CONFIG_VECTOR
> +bool has_vector __read_mostly;
> +unsigned long riscv_vsize __read_mostly;
> +#endif
>
>  void riscv_fill_hwcap(void)
>  {
> @@ -73,4 +77,11 @@ void riscv_fill_hwcap(void)
>         if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
>                 has_fpu = true;
>  #endif
> +
> +#ifdef CONFIG_VECTOR
> +       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
> +               has_vector = true;
> +               riscv_vsize = csr_read(CSR_VLENB) * 32;
> +       }
> +#endif
>  }
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 11/13] riscv: Add ptrace vector support
  2020-05-26  7:02 ` [RFC PATCH v4 11/13] riscv: Add ptrace vector support Greentime Hu
@ 2020-06-01  9:14     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:14 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds ptrace support for riscv vector. The vector registers will
> be saved in datap pointer of __riscv_v_state. This pointer will be set
> right after the __riscv_v_state data structure then it will be put in ubuf
> for ptrace system call to get or set. It will check if the datap got from
> ubuf is set to the correct address or not when the ptrace system call is
> trying to set the vector registers.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix vtype not
> saved bug]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/elf.h |   1 +
>  arch/riscv/kernel/ptrace.c        | 114 ++++++++++++++++++++++++++++++
>  include/uapi/linux/elf.h          |   1 +
>  3 files changed, 116 insertions(+)
>
> diff --git a/arch/riscv/include/uapi/asm/elf.h b/arch/riscv/include/uapi/asm/elf.h
> index d696d6610231..099434d075a7 100644
> --- a/arch/riscv/include/uapi/asm/elf.h
> +++ b/arch/riscv/include/uapi/asm/elf.h
> @@ -23,6 +23,7 @@ typedef struct user_regs_struct elf_gregset_t;
>  typedef __u64 elf_fpreg_t;
>  typedef union __riscv_fp_state elf_fpregset_t;
>  #define ELF_NFPREG (sizeof(struct __riscv_d_ext_state) / sizeof(elf_fpreg_t))
> +#define ELF_NVREG  (sizeof(struct __riscv_v_state) / sizeof(elf_greg_t))
>
>  #if __riscv_xlen == 64
>  #define ELF_RISCV_R_SYM(r_info)                ELF64_R_SYM(r_info)
> diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
> index 444dc7b0fd78..9b9bd1c02362 100644
> --- a/arch/riscv/kernel/ptrace.c
> +++ b/arch/riscv/kernel/ptrace.c
> @@ -10,6 +10,7 @@
>  #include <asm/ptrace.h>
>  #include <asm/syscall.h>
>  #include <asm/thread_info.h>
> +#include <asm/switch_to.h>
>  #include <linux/audit.h>
>  #include <linux/ptrace.h>
>  #include <linux/elf.h>
> @@ -26,6 +27,9 @@ enum riscv_regset {
>  #ifdef CONFIG_FPU
>         REGSET_F,
>  #endif
> +#ifdef CONFIG_VECTOR
> +       REGSET_V,
> +#endif
>  };
>
>  static int riscv_gpr_get(struct task_struct *target,
> @@ -92,6 +96,107 @@ static int riscv_fpr_set(struct task_struct *target,
>  }
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static int riscv_vr_get(struct task_struct *target,
> +                        const struct user_regset *regset,
> +                        unsigned int pos, unsigned int count,
> +                        void *kbuf, void __user *ubuf)
> +{
> +       int ret, size;
> +       struct __riscv_v_state *vstate = &target->thread.vstate;
> +       /* Set the datap right after the address of vstate. */
> +       void *datap = ubuf + sizeof(struct __riscv_v_state);
> +       u32 magic = RVV_MAGIC;
> +
> +       /* Copy the magic number. */
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &magic, 0,
> +                                 sizeof(u32));
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Copy rest of vstate except datap. */
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, vstate, 0,
> +                                 RISCV_V_STATE_DATAP);
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Copy the pointer datap itself. */
> +       pos = 0;
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &datap, 0,
> +                                 sizeof(vstate->datap));
> +       if (unlikely(ret))
> +               return ret;
> +
> +#if __riscv_xlen == 32
> +       /* Skip copy _padding. */
> +       size = sizeof(vstate->__padding);
> +       count -= size;
> +       ubuf += size;
> +#endif
> +
> +       /* Copy all the vector registers. */
> +       pos = 0;
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> +                                 vstate->datap, 0, vstate->size);
> +       return ret;
> +}
> +
> +static int riscv_vr_set(struct task_struct *target,
> +                        const struct user_regset *regset,
> +                        unsigned int pos, unsigned int count,
> +                        const void *kbuf, const void __user *ubuf)
> +{
> +       int ret, size;
> +       struct __riscv_v_state *vstate = &target->thread.vstate;
> +       const void *datap = ubuf + sizeof(struct __riscv_v_state);
> +       const void *datap_addr = ubuf + RISCV_V_STATE_DATAP;
> +       long val_datap;
> +
> +       /* Skip copy magic because kernel doesn't need to use it. */
> +       size = sizeof(vstate->magic);
> +       pos += size;
> +       count -= size;
> +       ubuf += size;
> +
> +       /* Copy rest of the vstate except datap and __padding. */
> +       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate, 0,
> +                                RISCV_V_STATE_DATAP);
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Check if the datap is correct address of ubuf. */
> +       __get_user(val_datap, (long *)datap_addr);
> +       if (val_datap != (long)datap)
> +               return -EFAULT;
> +
> +       /* Skip copy datap. */
> +       size = sizeof(vstate->datap);
> +       count -= size;
> +       ubuf += size;
> +
> +#if __riscv_xlen == 32
> +       /* Skip copy _padding. */
> +       size = sizeof(vstate->__padding);
> +       count -= size;
> +       ubuf += size;
> +#endif
> +
> +       /* Copy all the vector registers. */
> +       pos = 0;
> +       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate->datap,
> +                                0, vstate->size);
> +       return ret;
> +}
> +static unsigned int riscv_vr_get_size(struct task_struct *target,
> +                                     const struct user_regset *regset)
> +{
> +       if (!has_vector)
> +               return 0;
> +
> +       return sizeof(struct __riscv_v_state) + riscv_vsize;
> +}
> +#endif
> +
>  static const struct user_regset riscv_user_regset[] = {
>         [REGSET_X] = {
>                 .core_note_type = NT_PRSTATUS,
> @@ -111,6 +216,15 @@ static const struct user_regset riscv_user_regset[] = {
>                 .set = &riscv_fpr_set,
>         },
>  #endif
> +#ifdef CONFIG_VECTOR
> +       [REGSET_V] = {
> +               .core_note_type = NT_RISCV_VECTOR,
> +               .align = 16,
> +               .get = riscv_vr_get,
> +               .set = riscv_vr_set,
> +               .get_size = riscv_vr_get_size,
> +       },
> +#endif
>  };
>
>  static const struct user_regset_view riscv_user_native_view = {
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index 34c02e4290fe..e428f9e8710a 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -428,6 +428,7 @@ typedef struct elf64_shdr {
>  #define NT_MIPS_DSP    0x800           /* MIPS DSP ASE registers */
>  #define NT_MIPS_FP_MODE        0x801           /* MIPS floating-point mode */
>  #define NT_MIPS_MSA    0x802           /* MIPS SIMD registers */
> +#define NT_RISCV_VECTOR        0x900           /* RISC-V vector registers */
>
>  /* Note header in a PT_NOTE section */
>  typedef struct elf32_note {
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 11/13] riscv: Add ptrace vector support
@ 2020-06-01  9:14     ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-01  9:14 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Since it has been redesigned with new version spec, please change the
first-author :)

And add me as Co-developed.

On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch adds ptrace support for riscv vector. The vector registers will
> be saved in datap pointer of __riscv_v_state. This pointer will be set
> right after the __riscv_v_state data structure then it will be put in ubuf
> for ptrace system call to get or set. It will check if the datap got from
> ubuf is set to the correct address or not when the ptrace system call is
> trying to set the vector registers.
>
> [greentime.hu@sifive.com: add support for dynamic vlen, fix vtype not
> saved bug]
> Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> ---
>  arch/riscv/include/uapi/asm/elf.h |   1 +
>  arch/riscv/kernel/ptrace.c        | 114 ++++++++++++++++++++++++++++++
>  include/uapi/linux/elf.h          |   1 +
>  3 files changed, 116 insertions(+)
>
> diff --git a/arch/riscv/include/uapi/asm/elf.h b/arch/riscv/include/uapi/asm/elf.h
> index d696d6610231..099434d075a7 100644
> --- a/arch/riscv/include/uapi/asm/elf.h
> +++ b/arch/riscv/include/uapi/asm/elf.h
> @@ -23,6 +23,7 @@ typedef struct user_regs_struct elf_gregset_t;
>  typedef __u64 elf_fpreg_t;
>  typedef union __riscv_fp_state elf_fpregset_t;
>  #define ELF_NFPREG (sizeof(struct __riscv_d_ext_state) / sizeof(elf_fpreg_t))
> +#define ELF_NVREG  (sizeof(struct __riscv_v_state) / sizeof(elf_greg_t))
>
>  #if __riscv_xlen == 64
>  #define ELF_RISCV_R_SYM(r_info)                ELF64_R_SYM(r_info)
> diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
> index 444dc7b0fd78..9b9bd1c02362 100644
> --- a/arch/riscv/kernel/ptrace.c
> +++ b/arch/riscv/kernel/ptrace.c
> @@ -10,6 +10,7 @@
>  #include <asm/ptrace.h>
>  #include <asm/syscall.h>
>  #include <asm/thread_info.h>
> +#include <asm/switch_to.h>
>  #include <linux/audit.h>
>  #include <linux/ptrace.h>
>  #include <linux/elf.h>
> @@ -26,6 +27,9 @@ enum riscv_regset {
>  #ifdef CONFIG_FPU
>         REGSET_F,
>  #endif
> +#ifdef CONFIG_VECTOR
> +       REGSET_V,
> +#endif
>  };
>
>  static int riscv_gpr_get(struct task_struct *target,
> @@ -92,6 +96,107 @@ static int riscv_fpr_set(struct task_struct *target,
>  }
>  #endif
>
> +#ifdef CONFIG_VECTOR
> +static int riscv_vr_get(struct task_struct *target,
> +                        const struct user_regset *regset,
> +                        unsigned int pos, unsigned int count,
> +                        void *kbuf, void __user *ubuf)
> +{
> +       int ret, size;
> +       struct __riscv_v_state *vstate = &target->thread.vstate;
> +       /* Set the datap right after the address of vstate. */
> +       void *datap = ubuf + sizeof(struct __riscv_v_state);
> +       u32 magic = RVV_MAGIC;
> +
> +       /* Copy the magic number. */
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &magic, 0,
> +                                 sizeof(u32));
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Copy rest of vstate except datap. */
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, vstate, 0,
> +                                 RISCV_V_STATE_DATAP);
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Copy the pointer datap itself. */
> +       pos = 0;
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &datap, 0,
> +                                 sizeof(vstate->datap));
> +       if (unlikely(ret))
> +               return ret;
> +
> +#if __riscv_xlen == 32
> +       /* Skip copy _padding. */
> +       size = sizeof(vstate->__padding);
> +       count -= size;
> +       ubuf += size;
> +#endif
> +
> +       /* Copy all the vector registers. */
> +       pos = 0;
> +       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> +                                 vstate->datap, 0, vstate->size);
> +       return ret;
> +}
> +
> +static int riscv_vr_set(struct task_struct *target,
> +                        const struct user_regset *regset,
> +                        unsigned int pos, unsigned int count,
> +                        const void *kbuf, const void __user *ubuf)
> +{
> +       int ret, size;
> +       struct __riscv_v_state *vstate = &target->thread.vstate;
> +       const void *datap = ubuf + sizeof(struct __riscv_v_state);
> +       const void *datap_addr = ubuf + RISCV_V_STATE_DATAP;
> +       long val_datap;
> +
> +       /* Skip copy magic because kernel doesn't need to use it. */
> +       size = sizeof(vstate->magic);
> +       pos += size;
> +       count -= size;
> +       ubuf += size;
> +
> +       /* Copy rest of the vstate except datap and __padding. */
> +       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate, 0,
> +                                RISCV_V_STATE_DATAP);
> +       if (unlikely(ret))
> +               return ret;
> +
> +       /* Check if the datap is correct address of ubuf. */
> +       __get_user(val_datap, (long *)datap_addr);
> +       if (val_datap != (long)datap)
> +               return -EFAULT;
> +
> +       /* Skip copy datap. */
> +       size = sizeof(vstate->datap);
> +       count -= size;
> +       ubuf += size;
> +
> +#if __riscv_xlen == 32
> +       /* Skip copy _padding. */
> +       size = sizeof(vstate->__padding);
> +       count -= size;
> +       ubuf += size;
> +#endif
> +
> +       /* Copy all the vector registers. */
> +       pos = 0;
> +       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vstate->datap,
> +                                0, vstate->size);
> +       return ret;
> +}
> +static unsigned int riscv_vr_get_size(struct task_struct *target,
> +                                     const struct user_regset *regset)
> +{
> +       if (!has_vector)
> +               return 0;
> +
> +       return sizeof(struct __riscv_v_state) + riscv_vsize;
> +}
> +#endif
> +
>  static const struct user_regset riscv_user_regset[] = {
>         [REGSET_X] = {
>                 .core_note_type = NT_PRSTATUS,
> @@ -111,6 +216,15 @@ static const struct user_regset riscv_user_regset[] = {
>                 .set = &riscv_fpr_set,
>         },
>  #endif
> +#ifdef CONFIG_VECTOR
> +       [REGSET_V] = {
> +               .core_note_type = NT_RISCV_VECTOR,
> +               .align = 16,
> +               .get = riscv_vr_get,
> +               .set = riscv_vr_set,
> +               .get_size = riscv_vr_get_size,
> +       },
> +#endif
>  };
>
>  static const struct user_regset_view riscv_user_native_view = {
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index 34c02e4290fe..e428f9e8710a 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -428,6 +428,7 @@ typedef struct elf64_shdr {
>  #define NT_MIPS_DSP    0x800           /* MIPS DSP ASE registers */
>  #define NT_MIPS_FP_MODE        0x801           /* MIPS floating-point mode */
>  #define NT_MIPS_MSA    0x802           /* MIPS SIMD registers */
> +#define NT_RISCV_VECTOR        0x900           /* RISC-V vector registers */
>
>  /* Note header in a PT_NOTE section */
>  typedef struct elf32_note {
> --
> 2.26.2
>
>


-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
  2020-05-31 15:52   ` Guo Ren
@ 2020-06-02  2:21     ` Greentime Hu
  -1 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-02  2:21 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 下午11:52寫道:
>
> Hi Greentime & Vincent,
>
> Thx for the dynamic vlen implementation. I've two suggestions:
>  - Please give out glibc patches mail URL, we need to review them together.
>  - We need to consider that not all processes need vectors. Most
> system processes do not have vector features, and we should not force
> save/restore vector for every process.
>

Hi Guo,

Thanks for reviewing the patch. We are still cooking the glibc patch,
we will add the glibc link address once we post it.
For the save/restore mechanism in signal, it is basically the same
with FPU porting, we can optimize it when setup_sigcontext() for both
FPU and VECTOR in the future.

/* Save the floating-point state. */
if (has_fpu)
        err |= save_fp_state(regs, &sc->sc_fpregs);
/* Save the vector state. */
if (has_vector)
        err |= save_v_state(regs, sc);

There should be a better way to detect whether this task use
fpu/vector or not. Might be elf attributes or something else.

> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > This patchset is based on Guo Ren's v3 patchset to add dynamic vlen vector
> > support for all different kinds of vector length in riscv. To make this
> > happened we defined a new __riscv_v_state in sigcontext to save the vector
> > related registers. The datap pointer will be allocated dynamically in
> > kernel space and it will be put right after the __riscv_v_state data
> > structure to save all the vector registers in signal handler stack for user
> > space. So does the implementation in ptrace, they will be saved in ubuf
> > in which we put the __riscv_v_state data structure and datap pointer right
> > after it for vector registers. This patchset also fixes several bugs for
> > vector lazy save/restore and vtype not saving issue. It also adds new CSR
> > support for vector based on the 0.9 vector spec and clean up some unused
> > macros.
> >
> > This patchset is rebased to v5.7-rc4 and it is tested by running several
> > vector programs simultaneously. It also can get the correct ucontext_t in
> > signal handler and restore correct context after sigreturn. It is also
> > tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
> > get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
> > virt machine of qemu-system-riscv32 and qemu-system-riscv64 provided by
> > Zhiwei Lui.
> >
> > Since the vector spec is under developing, there might still need some
> > changes. For example the vle.v/vse.v instructions will be replaced with
> > proper instructions. The reason that I don't replace the instruction in
> > this patchset is because that the Qemu doesn't fully support 0.9 spec yet.
> > I have no simulator to test. We also like to discuss the default setting of
> > MINSIGSTKSZ and SIGSTKSZ. They might also need to set a proper number. They
> > are 2048 and 8096 now. Since the stack in signal will be reserved for
> > ucontext and the vector registers might be larger and larger someday, these
> > two macros will need to be defined as a proper value or maybe we should
> > provide a better mechanism to provide user to get a better default signal
> > stack size.
> >
> >
> >  [1] https://github.com/romanheros/qemu/tree/linux-vector-dev
> >  [2] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
> >  [3] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
> >
> > ---
> > Changelog V4
> >  - Support dynamic vlen
> >  - Fix bugs: lazy save/resotre, not saving vtype
> >  - Update VS bit offset based on latest vector spec
> >  - Add new vector csr based on latest vector spec
> >  - Code refine and removed unused macros
> >
> > Changelog V3
> >  - Rebase linux-5.6-rc3 and tested with qemu
> >  - Seperate patches with Anup's advice
> >  - Give out a ABI puzzle with unlimited vlen
> >
> > Changelog V2
> >  - Fixup typo "vecotr, fstate_save->vstate_save".
> >  - Fixup wrong saved registers' length in vector.S.
> >  - Seperate unrelated patches from this one.
> >
> > Greentime Hu (1):
> >   ptrace: Use regset_size() for dynamic regset size.
> >
> > Guo Ren (11):
> >   riscv: Separate patch for cflags and aflags
> >   riscv: Rename __switch_to_aux -> fpu
> >   riscv: Extending cpufeature.c to detect V-extension
> >   riscv: Add new csr defines related to vector extension
> >   riscv: Add vector feature to compile
> >   riscv: Add has_vector/riscv_vsize to save vector features.
> >   riscv: Reset vector register
> >   riscv: Add vector struct and assembler definitions
> >   riscv: Add task switch support for vector
> >   riscv: Add ptrace vector support
> >   riscv: Add sigcontext save/restore for vector
> >
> > Vincent Chen (1):
> >   riscv: signal: Report signal frame size to userspace via auxv
> >
> >  arch/riscv/Kconfig                       |   9 ++
> >  arch/riscv/Makefile                      |  19 ++--
> >  arch/riscv/include/asm/csr.h             |  16 +++-
> >  arch/riscv/include/asm/elf.h             |  17 +++-
> >  arch/riscv/include/asm/processor.h       |   3 +
> >  arch/riscv/include/asm/switch_to.h       |  77 ++++++++++++++-
> >  arch/riscv/include/uapi/asm/auxvec.h     |   2 +
> >  arch/riscv/include/uapi/asm/elf.h        |   1 +
> >  arch/riscv/include/uapi/asm/hwcap.h      |   1 +
> >  arch/riscv/include/uapi/asm/ptrace.h     |  13 +++
> >  arch/riscv/include/uapi/asm/sigcontext.h |   2 +
> >  arch/riscv/kernel/Makefile               |   1 +
> >  arch/riscv/kernel/asm-offsets.c          |   8 ++
> >  arch/riscv/kernel/cpufeature.c           |  15 ++-
> >  arch/riscv/kernel/entry.S                |   2 +-
> >  arch/riscv/kernel/head.S                 |  49 +++++++++-
> >  arch/riscv/kernel/process.c              |  40 ++++++++
> >  arch/riscv/kernel/ptrace.c               | 114 +++++++++++++++++++++++
> >  arch/riscv/kernel/setup.c                |   5 +
> >  arch/riscv/kernel/signal.c               | 108 ++++++++++++++++++++-
> >  arch/riscv/kernel/vector.S               |  84 +++++++++++++++++
> >  include/uapi/linux/elf.h                 |   1 +
> >  kernel/ptrace.c                          |  11 ++-
> >  23 files changed, 573 insertions(+), 25 deletions(-)
> >  create mode 100644 arch/riscv/kernel/vector.S
> >
> > --
> > 2.26.2
> >
> >
>
>
> --
> Best Regards
>  Guo Ren
>
> ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
@ 2020-06-02  2:21     ` Greentime Hu
  0 siblings, 0 replies; 54+ messages in thread
From: Greentime Hu @ 2020-06-02  2:21 UTC (permalink / raw)
  To: Guo Ren
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 下午11:52寫道:
>
> Hi Greentime & Vincent,
>
> Thx for the dynamic vlen implementation. I've two suggestions:
>  - Please give out glibc patches mail URL, we need to review them together.
>  - We need to consider that not all processes need vectors. Most
> system processes do not have vector features, and we should not force
> save/restore vector for every process.
>

Hi Guo,

Thanks for reviewing the patch. We are still cooking the glibc patch,
we will add the glibc link address once we post it.
For the save/restore mechanism in signal, it is basically the same
with FPU porting, we can optimize it when setup_sigcontext() for both
FPU and VECTOR in the future.

/* Save the floating-point state. */
if (has_fpu)
        err |= save_fp_state(regs, &sc->sc_fpregs);
/* Save the vector state. */
if (has_vector)
        err |= save_v_state(regs, sc);

There should be a better way to detect whether this task use
fpu/vector or not. Might be elf attributes or something else.

> On Tue, May 26, 2020 at 3:03 PM Greentime Hu <greentime.hu@sifive.com> wrote:
> >
> > This patchset is based on Guo Ren's v3 patchset to add dynamic vlen vector
> > support for all different kinds of vector length in riscv. To make this
> > happened we defined a new __riscv_v_state in sigcontext to save the vector
> > related registers. The datap pointer will be allocated dynamically in
> > kernel space and it will be put right after the __riscv_v_state data
> > structure to save all the vector registers in signal handler stack for user
> > space. So does the implementation in ptrace, they will be saved in ubuf
> > in which we put the __riscv_v_state data structure and datap pointer right
> > after it for vector registers. This patchset also fixes several bugs for
> > vector lazy save/restore and vtype not saving issue. It also adds new CSR
> > support for vector based on the 0.9 vector spec and clean up some unused
> > macros.
> >
> > This patchset is rebased to v5.7-rc4 and it is tested by running several
> > vector programs simultaneously. It also can get the correct ucontext_t in
> > signal handler and restore correct context after sigreturn. It is also
> > tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
> > get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
> > virt machine of qemu-system-riscv32 and qemu-system-riscv64 provided by
> > Zhiwei Lui.
> >
> > Since the vector spec is under developing, there might still need some
> > changes. For example the vle.v/vse.v instructions will be replaced with
> > proper instructions. The reason that I don't replace the instruction in
> > this patchset is because that the Qemu doesn't fully support 0.9 spec yet.
> > I have no simulator to test. We also like to discuss the default setting of
> > MINSIGSTKSZ and SIGSTKSZ. They might also need to set a proper number. They
> > are 2048 and 8096 now. Since the stack in signal will be reserved for
> > ucontext and the vector registers might be larger and larger someday, these
> > two macros will need to be defined as a proper value or maybe we should
> > provide a better mechanism to provide user to get a better default signal
> > stack size.
> >
> >
> >  [1] https://github.com/romanheros/qemu/tree/linux-vector-dev
> >  [2] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
> >  [3] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
> >
> > ---
> > Changelog V4
> >  - Support dynamic vlen
> >  - Fix bugs: lazy save/resotre, not saving vtype
> >  - Update VS bit offset based on latest vector spec
> >  - Add new vector csr based on latest vector spec
> >  - Code refine and removed unused macros
> >
> > Changelog V3
> >  - Rebase linux-5.6-rc3 and tested with qemu
> >  - Seperate patches with Anup's advice
> >  - Give out a ABI puzzle with unlimited vlen
> >
> > Changelog V2
> >  - Fixup typo "vecotr, fstate_save->vstate_save".
> >  - Fixup wrong saved registers' length in vector.S.
> >  - Seperate unrelated patches from this one.
> >
> > Greentime Hu (1):
> >   ptrace: Use regset_size() for dynamic regset size.
> >
> > Guo Ren (11):
> >   riscv: Separate patch for cflags and aflags
> >   riscv: Rename __switch_to_aux -> fpu
> >   riscv: Extending cpufeature.c to detect V-extension
> >   riscv: Add new csr defines related to vector extension
> >   riscv: Add vector feature to compile
> >   riscv: Add has_vector/riscv_vsize to save vector features.
> >   riscv: Reset vector register
> >   riscv: Add vector struct and assembler definitions
> >   riscv: Add task switch support for vector
> >   riscv: Add ptrace vector support
> >   riscv: Add sigcontext save/restore for vector
> >
> > Vincent Chen (1):
> >   riscv: signal: Report signal frame size to userspace via auxv
> >
> >  arch/riscv/Kconfig                       |   9 ++
> >  arch/riscv/Makefile                      |  19 ++--
> >  arch/riscv/include/asm/csr.h             |  16 +++-
> >  arch/riscv/include/asm/elf.h             |  17 +++-
> >  arch/riscv/include/asm/processor.h       |   3 +
> >  arch/riscv/include/asm/switch_to.h       |  77 ++++++++++++++-
> >  arch/riscv/include/uapi/asm/auxvec.h     |   2 +
> >  arch/riscv/include/uapi/asm/elf.h        |   1 +
> >  arch/riscv/include/uapi/asm/hwcap.h      |   1 +
> >  arch/riscv/include/uapi/asm/ptrace.h     |  13 +++
> >  arch/riscv/include/uapi/asm/sigcontext.h |   2 +
> >  arch/riscv/kernel/Makefile               |   1 +
> >  arch/riscv/kernel/asm-offsets.c          |   8 ++
> >  arch/riscv/kernel/cpufeature.c           |  15 ++-
> >  arch/riscv/kernel/entry.S                |   2 +-
> >  arch/riscv/kernel/head.S                 |  49 +++++++++-
> >  arch/riscv/kernel/process.c              |  40 ++++++++
> >  arch/riscv/kernel/ptrace.c               | 114 +++++++++++++++++++++++
> >  arch/riscv/kernel/setup.c                |   5 +
> >  arch/riscv/kernel/signal.c               | 108 ++++++++++++++++++++-
> >  arch/riscv/kernel/vector.S               |  84 +++++++++++++++++
> >  include/uapi/linux/elf.h                 |   1 +
> >  kernel/ptrace.c                          |  11 ++-
> >  23 files changed, 573 insertions(+), 25 deletions(-)
> >  create mode 100644 arch/riscv/kernel/vector.S
> >
> > --
> > 2.26.2
> >
> >
>
>
> --
> Best Regards
>  Guo Ren
>
> ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
  2020-06-02  2:21     ` Greentime Hu
@ 2020-06-02  3:08       ` Guo Ren
  -1 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-02  3:08 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	linux-riscv, Linux Kernel Mailing List, Oleg Nesterov

On Tue, Jun 2, 2020 at 10:21 AM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 下午11:52寫道:
> >
> > Hi Greentime & Vincent,
> >
> > Thx for the dynamic vlen implementation. I've two suggestions:
> >  - Please give out glibc patches mail URL, we need to review them together.
> >  - We need to consider that not all processes need vectors. Most
> > system processes do not have vector features, and we should not force
> > save/restore vector for every process.
> >
>
> Hi Guo,
>
> Thanks for reviewing the patch. We are still cooking the glibc patch,
> we will add the glibc link address once we post it.
> For the save/restore mechanism in signal, it is basically the same
> with FPU porting, we can optimize it when setup_sigcontext() for both
> FPU and VECTOR in the future.
>
> /* Save the floating-point state. */
> if (has_fpu)
>         err |= save_fp_state(regs, &sc->sc_fpregs);
> /* Save the vector state. */
> if (has_vector)
>         err |= save_v_state(regs, sc);
>
> There should be a better way to detect whether this task use
> fpu/vector or not. Might be elf attributes or something else.
Ok, we could improve it in future patches.

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH v4 00/13] riscv: Add vector ISA support
@ 2020-06-02  3:08       ` Guo Ren
  0 siblings, 0 replies; 54+ messages in thread
From: Guo Ren @ 2020-06-02  3:08 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Guo Ren, Palmer Dabbelt, Linux Kernel Mailing List,
	Oleg Nesterov, Vincent Chen, Paul Walmsley, linux-riscv

On Tue, Jun 2, 2020 at 10:21 AM Greentime Hu <greentime.hu@sifive.com> wrote:
>
> Guo Ren <guoren@kernel.org> 於 2020年5月31日 週日 下午11:52寫道:
> >
> > Hi Greentime & Vincent,
> >
> > Thx for the dynamic vlen implementation. I've two suggestions:
> >  - Please give out glibc patches mail URL, we need to review them together.
> >  - We need to consider that not all processes need vectors. Most
> > system processes do not have vector features, and we should not force
> > save/restore vector for every process.
> >
>
> Hi Guo,
>
> Thanks for reviewing the patch. We are still cooking the glibc patch,
> we will add the glibc link address once we post it.
> For the save/restore mechanism in signal, it is basically the same
> with FPU porting, we can optimize it when setup_sigcontext() for both
> FPU and VECTOR in the future.
>
> /* Save the floating-point state. */
> if (has_fpu)
>         err |= save_fp_state(regs, &sc->sc_fpregs);
> /* Save the vector state. */
> if (has_vector)
>         err |= save_v_state(regs, sc);
>
> There should be a better way to detect whether this task use
> fpu/vector or not. Might be elf attributes or something else.
Ok, we could improve it in future patches.

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2020-06-02  3:08 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-26  7:02 [RFC PATCH v4 00/13] riscv: Add vector ISA support Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 01/13] ptrace: Use regset_size() for dynamic regset size Greentime Hu
2020-05-26 14:00   ` Oleg Nesterov
2020-05-26 14:00     ` Oleg Nesterov
2020-05-27  6:34     ` Greentime Hu
2020-05-27  6:34       ` Greentime Hu
2020-05-27 11:31       ` Oleg Nesterov
2020-05-27 11:31         ` Oleg Nesterov
2020-05-26  7:02 ` [RFC PATCH v4 02/13] riscv: Separate patch for cflags and aflags Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 03/13] riscv: Rename __switch_to_aux -> fpu Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 04/13] riscv: Extending cpufeature.c to detect V-extension Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 05/13] riscv: Add new csr defines related to vector extension Greentime Hu
2020-05-31  1:56   ` Guo Ren
2020-05-31  1:56     ` Guo Ren
2020-06-01  8:15     ` Greentime Hu
2020-06-01  8:15       ` Greentime Hu
2020-06-01  8:59       ` Guo Ren
2020-06-01  8:59         ` Guo Ren
2020-06-01  9:03   ` Guo Ren
2020-06-01  9:03     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 06/13] riscv: Add vector feature to compile Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 07/13] riscv: Add has_vector/riscv_vsize to save vector features Greentime Hu
2020-05-31  0:58   ` Guo Ren
2020-05-31  0:58     ` Guo Ren
2020-06-01  8:07     ` Greentime Hu
2020-06-01  8:07       ` Greentime Hu
2020-06-01  9:13   ` Guo Ren
2020-06-01  9:13     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 08/13] riscv: Reset vector register Greentime Hu
2020-05-26  7:02 ` [RFC PATCH v4 09/13] riscv: Add vector struct and assembler definitions Greentime Hu
2020-06-01  9:12   ` Guo Ren
2020-06-01  9:12     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 10/13] riscv: Add task switch support for vector Greentime Hu
2020-05-31 15:29   ` Guo Ren
2020-05-31 15:29     ` Guo Ren
2020-05-31 16:08   ` Guo Ren
2020-05-31 16:08     ` Guo Ren
2020-06-01  9:12   ` Guo Ren
2020-06-01  9:12     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 11/13] riscv: Add ptrace vector support Greentime Hu
2020-06-01  9:14   ` Guo Ren
2020-06-01  9:14     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 12/13] riscv: Add sigcontext save/restore for vector Greentime Hu
2020-05-31 15:28   ` Guo Ren
2020-05-31 15:28     ` Guo Ren
2020-06-01  9:13   ` Guo Ren
2020-06-01  9:13     ` Guo Ren
2020-05-26  7:02 ` [RFC PATCH v4 13/13] riscv: signal: Report signal frame size to userspace via auxv Greentime Hu
2020-05-31 15:52 ` [RFC PATCH v4 00/13] riscv: Add vector ISA support Guo Ren
2020-05-31 15:52   ` Guo Ren
2020-06-02  2:21   ` Greentime Hu
2020-06-02  2:21     ` Greentime Hu
2020-06-02  3:08     ` Guo Ren
2020-06-02  3:08       ` Guo Ren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.