mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
riscv: Introduce riscv_v_vsize to record size of Vector context
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>
This commit is contained in:
parent
0a3381a01d
commit
7017858eb2
5 changed files with 54 additions and 0 deletions
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -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.
|
||||
|
|
36
arch/riscv/kernel/vector.c
Normal file
36
arch/riscv/kernel/vector.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue