Skip to content

Commit

Permalink
riscv: Introduce riscv_v_vsize to record size of Vector context
Browse files Browse the repository at this point in the history
This patch is used to detect the size of CPU vector registers and use
riscv_v_vsize to save the size of all the vector registers. It assumes all
harts has the same capabilities in a SMP system. If a core detects VLENB
that is different from the boot core, then it warns and turns off V
support for user space.

Co-developed-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Co-developed-by: Vincent Chen <vincent.chen@sifive.com>
Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Andy Chiu <andy.chiu@sifive.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
Tested-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
Link: https://lore.kernel.org/r/20230605110724.21391-9-andy.chiu@sifive.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
  • Loading branch information
Greentime Hu authored and Palmer Dabbelt committed Jun 8, 2023
1 parent 0a3381a commit 7017858
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/riscv/include/asm/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
#define __ASM_RISCV_VECTOR_H

#include <linux/types.h>
#include <uapi/asm-generic/errno.h>

#ifdef CONFIG_RISCV_ISA_V

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

extern unsigned long riscv_v_vsize;
int riscv_v_setup_vsize(void);

static __always_inline bool has_vector(void)
{
return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
Expand All @@ -30,7 +34,11 @@ static __always_inline void riscv_v_disable(void)

#else /* ! CONFIG_RISCV_ISA_V */

struct pt_regs;

static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
static __always_inline bool has_vector(void) { return false; }
#define riscv_v_vsize (0)

#endif /* CONFIG_RISCV_ISA_V */

Expand Down
1 change: 1 addition & 0 deletions arch/riscv/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/

obj-$(CONFIG_RISCV_M_MODE) += traps_misaligned.o
obj-$(CONFIG_FPU) += fpu.o
obj-$(CONFIG_RISCV_ISA_V) += vector.o
obj-$(CONFIG_SMP) += smpboot.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP) += cpu_ops.o
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <asm/hwcap.h>
#include <asm/patch.h>
#include <asm/processor.h>
#include <asm/vector.h>

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

Expand Down Expand Up @@ -269,6 +270,7 @@ void __init riscv_fill_hwcap(void)
}

if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
riscv_v_setup_vsize();
/*
* ISA string in device tree might have 'v' flag, but
* CONFIG_RISCV_ISA_V is disabled in kernel.
Expand Down
7 changes: 7 additions & 0 deletions arch/riscv/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <asm/tlbflush.h>
#include <asm/sections.h>
#include <asm/smp.h>
#include <uapi/asm/hwcap.h>
#include <asm/vector.h>

#include "head.h"

Expand Down Expand Up @@ -169,6 +171,11 @@ asmlinkage __visible void smp_callin(void)
set_cpu_online(curr_cpuid, 1);
probe_vendor_features(curr_cpuid);

if (has_vector()) {
if (riscv_v_setup_vsize())
elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
}

/*
* Remote TLB flushes are ignored while the CPU is offline, so emit
* a local TLB flush right now just in case.
Expand Down
36 changes: 36 additions & 0 deletions arch/riscv/kernel/vector.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2023 SiFive
* Author: Andy Chiu <andy.chiu@sifive.com>
*/
#include <linux/export.h>

#include <asm/vector.h>
#include <asm/csr.h>
#include <asm/elf.h>
#include <asm/bug.h>

unsigned long riscv_v_vsize __read_mostly;
EXPORT_SYMBOL_GPL(riscv_v_vsize);

int riscv_v_setup_vsize(void)
{
unsigned long this_vsize;

/* There are 32 vector registers with vlenb length. */
riscv_v_enable();
this_vsize = csr_read(CSR_VLENB) * 32;
riscv_v_disable();

if (!riscv_v_vsize) {
riscv_v_vsize = this_vsize;
return 0;
}

if (riscv_v_vsize != this_vsize) {
WARN(1, "RISCV_ISA_V only supports one vlenb on SMP systems");
return -EOPNOTSUPP;
}

return 0;
}

0 comments on commit 7017858

Please sign in to comment.