Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/arch/arm WIP: Draft kernel access to neon in arm.



details:   https://anonhg.NetBSD.org/src-all/rev/d809834adc86
branches:  trunk
changeset: 935279:d809834adc86
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Sun Jun 28 15:25:10 2020 +0000

description:
WIP: Draft kernel access to neon in arm.

Should maybe call it <arm/neon.h> and kernel_neon_enter/exit in case
there are other vector units that might be relevant, but this will
serve for now.

diffstat:

 sys/arch/arm/arm32/cpu.c    |   2 +
 sys/arch/arm/include/cpu.h  |   2 +
 sys/arch/arm/include/fpu.h  |  35 ++++++++++++++++++++++
 sys/arch/arm/vfp/vfp_init.c |  69 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 108 insertions(+), 0 deletions(-)

diffs (147 lines):

diff -r ebbce66388b2 -r d809834adc86 sys/arch/arm/arm32/cpu.c
--- a/sys/arch/arm/arm32/cpu.c  Sun Jun 28 02:00:56 2020 +0000
+++ b/sys/arch/arm/arm32/cpu.c  Sun Jun 28 15:25:10 2020 +0000
@@ -229,6 +229,8 @@
 #endif
 
        vfp_attach(ci);         /* XXX SMP */
+
+       ci->ci_kfpu_spl = -1;
 }
 
 enum cpu_class {
diff -r ebbce66388b2 -r d809834adc86 sys/arch/arm/include/cpu.h
--- a/sys/arch/arm/include/cpu.h        Sun Jun 28 02:00:56 2020 +0000
+++ b/sys/arch/arm/include/cpu.h        Sun Jun 28 15:25:10 2020 +0000
@@ -168,6 +168,8 @@
        int             ci_want_resched;/* resched() was called */
        int             ci_intr_depth;  /* */
 
+       int ci_kfpu_spl;
+
        struct cpu_softc *
                        ci_softc;       /* platform softc */
 
diff -r ebbce66388b2 -r d809834adc86 sys/arch/arm/include/fpu.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/include/fpu.h        Sun Jun 28 15:25:10 2020 +0000
@@ -0,0 +1,35 @@
+/*     $NetBSD$        */
+
+/*
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        _SYS_ARCH_ARM_FPU_H
+#define        _SYS_ARCH_ARM_FPU_H
+
+void fpu_kern_enter(void);
+void fpu_kern_leave(void);
+
+#endif /* _SYS_ARCH_ARM_FPU_H */
diff -r ebbce66388b2 -r d809834adc86 sys/arch/arm/vfp/vfp_init.c
--- a/sys/arch/arm/vfp/vfp_init.c       Sun Jun 28 02:00:56 2020 +0000
+++ b/sys/arch/arm/vfp/vfp_init.c       Sun Jun 28 15:25:10 2020 +0000
@@ -46,6 +46,7 @@
 #include <arm/undefined.h>
 #include <arm/vfpreg.h>
 #include <arm/mcontext.h>
+#include <arm/fpu.h>
 
 #include <uvm/uvm_extern.h>            /* for pmap.h */
 
@@ -658,4 +659,72 @@
            sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));
 }
 
+void
+fpu_kern_enter(void)
+{
+       struct lwp *l = curlwp;
+       struct cpu_info *ci;
+       uint32_t fpexc;
+       int s;
+
+       /*
+        * Block all interrupts.  We must block preemption since -- if
+        * this is a user thread -- there is nowhere to save the kernel
+        * fpu state, and if we want this to be usable in interrupts,
+        * we can't let interrupts interfere with the fpu state in use
+        * since there's nowhere for them to save it.
+        */
+       s = splhigh();
+       ci = curcpu();
+       KASSERT(ci->ci_kfpu_spl == -1);
+       ci->ci_kfpu_spl = s;
+
+       /*
+        * If we are in a softint and have a pinned lwp, the fpu state
+        * is that of the pinned lwp, so save it there.
+        */
+       if ((l->l_pflag & LP_INTR) && (l->l_switchto != NULL))
+               l = l->l_switchto;
+       if (vfp_used_p(l))
+               vfp_savecontext(l);
+
+       /* Enable the fpu.  */
+       fpexc = armreg_fpexc_read();
+       fpexc |= VFP_FPEXC_EN;
+       fpexc &= ~VFP_FPEXC_EX;
+       armreg_fpexc_write(fpexc);
+}
+
+void
+fpu_kern_leave(void)
+{
+       static const struct vfpreg zero_vfpreg;
+       struct cpu_info *ci = curcpu();
+       int s;
+       uint32_t fpexc;
+
+       KASSERT(ci->ci_cpl == IPL_HIGH);
+       KASSERT(ci->ci_kfpu_spl != -1);
+
+       /*
+        * Zero the fpu registers; otherwise we might leak secrets
+        * through Spectre-class attacks to userland, even if there are
+        * no bugs in fpu state management.
+        */
+       load_vfpregs(&zero_vfpreg);
+
+       /*
+        * Disable the fpu so that the kernel can't accidentally use
+        * it again.
+        */
+       fpexc = armreg_fpexc_read();
+       fpexc &= ~VFP_FPEXC_EN;
+       armreg_fpexc_write(fpexc);
+
+       /* Restore interrupts.  */
+       s = ci->ci_kfpu_spl;
+       ci->ci_kfpu_spl = -1;
+       splx(s);
+}
+
 #endif /* FPU_VFP */



Home | Main Index | Thread Index | Old Index