[v1, 2/6] riscv: Add support for kernel mode vector
Andy Chiu
andy.chiu at sifive.com
Thu Jul 20 07:54:15 PDT 2023
On Mon, Jul 17, 2023 at 6:23 PM Conor Dooley <conor.dooley at microchip.com> wrote:
>
> On Sat, Jul 15, 2023 at 03:00:28PM +0000, Andy Chiu wrote:
> > From: Greentime Hu <greentime.hu at sifive.com>
> >
> > Add kernel_rvv_begin() and kernel_rvv_end() function declarations
> > and corresponding definitions in kernel_mode_vector.c
> >
> > These are needed to wrap uses of vector in kernel mode.
> >
> > Co-developed-by: Vincent Chen <vincent.chen at sifive.com>
> > Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
> > Signed-off-by: Greentime Hu <greentime.hu at sifive.com>
> > Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
> > ---
> > arch/riscv/include/asm/vector.h | 2 +
> > arch/riscv/kernel/Makefile | 1 +
> > arch/riscv/kernel/kernel_mode_vector.c | 129 +++++++++++++++++++++++++
> > 3 files changed, 132 insertions(+)
> > create mode 100644 arch/riscv/kernel/kernel_mode_vector.c
> >
> > diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
> > index a4f3705fd144..9831b19153ae 100644
> > --- a/arch/riscv/include/asm/vector.h
> > +++ b/arch/riscv/include/asm/vector.h
> > @@ -22,6 +22,8 @@
> > extern unsigned long riscv_v_vsize;
> > int riscv_v_setup_vsize(void);
> > bool riscv_v_first_use_handler(struct pt_regs *regs);
> > +int kernel_rvv_begin(void);
> > +void kernel_rvv_end(void);
>
> So, we ditched all of the "rvv" stuff in the last series, using either
> "vector" - has_vector() - or "riscv_v". I'd rather not introduce a third
> naming scheme for vector related things...
>
> Given what you add below is full of other things that use "vector", how
> does s/rvv/vector/ sound here?
Yes, I agree. Let's use 'vector' instead of rvv.
>
>
> > diff --git a/arch/riscv/kernel/kernel_mode_vector.c b/arch/riscv/kernel/kernel_mode_vector.c
> > new file mode 100644
> > index 000000000000..c0c152c501a5
> > --- /dev/null
> > +++ b/arch/riscv/kernel/kernel_mode_vector.c
>
> > +/*
> > + * kernel_rvv_begin(): obtain the CPU vector registers for use by the calling
> > + * context
> > + *
> > + * Must not be called unless may_use_vector() returns true.
> > + * Task context in the vector registers is saved back to memory as necessary.
> > + *
> > + * A matching call to kernel_rvv_end() must be made before returning from the
> > + * calling context.
> > + *
> > + * The caller may freely use the vector registers until kernel_rvv_end() is
> > + * called.
> > + */
> > +int kernel_rvv_begin(void)
>
> How come this returns an int, but you never actually check the result? The
> other kernel_*_begin()s don't seem to return anything other than void.
>
> > +{
> > + if (!has_vector())
> > + return -EOPNOTSUPP;
> > +
> > + if (!may_use_vector())
> > + return -EPERM;
>
> I notice arm64 takes a stronger approach. There, if the has() call
> fails, it has a WARN_ON(). For the !may_use() case, it BUG()s.
> Since users are forced to check may_use_vector() before calling
> kernel_rvv_begin().
>
> Is there a reason that we should not take the same approach?
Yes, I agree that it is better to return nothing after some thinking.
Originally I was hoping to return a failure code if the preemptible
kernel-mode Vector failed to allocate memory in
riscv_v_start_kernel_context(). However, returning things here just
complicates the programming model for kernel-mode Vector. So, let's
just make it transparent to users of kernel_vector_begin() and return
nothing here.
>
> > +
> > + /* Save vector state, if any */
> > + riscv_v_vstate_save(current, task_pt_regs(current));
> > +
> > + /* Acquire kernel mode vector */
> > + get_cpu_vector_context();
> > +
> > + /* Enable vector */
>
> These three comments are mostly a statement of the obvious, no?
Agree, I will drop those comments.
>
> > + riscv_v_enable();
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(kernel_rvv_begin);
> > +
> > +/*
> > + * kernel_rvv_end(): give the CPU vector registers back to the current task
> > + *
> > + * Must be called from a context in which kernel_rvv_begin() was previously
> > + * called, with no call to kernel_rvv_end() in the meantime.
> > + *
> > + * The caller must not use the vector registers after this function is called,
> > + * unless kernel_rvv_begin() is called again in the meantime.
> > + */
> > +void kernel_rvv_end(void)
> > +{
> > + if (WARN_ON(!has_vector()))
>
> But there is a WARN_ON() here...
>
> > + return;
> > +
> > + /* Restore vector state, if any */
> > + riscv_v_vstate_set_restore(current, task_pt_regs(current));
> > +
> > + /* disable vector */
> > + riscv_v_disable();
> > +
> > + /* release kernel mode vector */
>
> Again, comments kinda state the obvious, no?
>
> Otherwise, this stuff looks generally fine to me & similar to what is
> being done elsewhere.
>
> Thanks,
> Conor.
Thanks,
Andy
More information about the linux-riscv
mailing list