Armv8.4 introduced a feature that provides data independent timing for
data processing instructions.  This feature is obviously introduced to
mitigate timing side-channel attacks.  Presumably enabling the feature
has some impact on performance as it would disable certain
optimizations to guarantee constant-time execution of instructions.

The only hardware that implements this feature that I've seen so far
is Apple's Icestorm/Firestorm (M1) and Avalanche/Blizzard (M2) cores.
I ran some benchmarks on an M2 Macbook Air.  In particular, I ran
"eopenssl30 speed" bound to a "performance" core.  I could not detect
a significant slowdown with this feature enabled.  Therefore I think
we should enable this feature by default on OpenBSD.  If at some point
a processor core appears where this feature does have a significant
performance impact, we can reconsider.

The use of this feature is still being discussed in the wider
comminity.  See for example the following thread:

  
https://lore.kernel.org/linux-arm-kernel/ywgcrqutxmx0w...@gmail.com/T/#mfcba14511c69461bd8921fef758baae120d090dc

On arm64, the feature can be controlled from userland, so even if we
turn it on by default, userland code can still make its own decisions
on whether it wants the feature enabled or disabled.  We may have to
expose the ID_AA64PFR0_EL1 register to userland when code shows uo
that attempts to do that.

The diff below enables the feature for both the kernel and for
userland processes.

ok?


Index: arch/arm64/arm64/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v
retrieving revision 1.70
diff -u -p -r1.70 cpu.c
--- arch/arm64/arm64/cpu.c      15 Sep 2022 01:57:52 -0000      1.70
+++ arch/arm64/arm64/cpu.c      1 Oct 2022 10:05:15 -0000
@@ -756,6 +756,7 @@ void
 cpu_init(void)
 {
        uint64_t id_aa64mmfr1, sctlr;
+       uint64_t id_aa64pfr0;
        uint64_t tcr;
 
        WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
@@ -774,6 +775,11 @@ cpu_init(void)
                sctlr &= ~SCTLR_SPAN;
                WRITE_SPECIALREG(sctlr_el1, sctlr);
        }
+
+       /* Enable DIT. */
+       id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
+       if (ID_AA64PFR0_DIT(id_aa64pfr0) >= ID_AA64PFR0_DIT_IMPL)
+               __asm volatile (".arch armv8.4-a; msr dit, #1");
 
        /* Initialize debug registers. */
        WRITE_SPECIALREG(mdscr_el1, DBG_MDSCR_TDCC);
Index: arch/arm64/arm64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.72
diff -u -p -r1.72 machdep.c
--- arch/arm64/arm64/machdep.c  5 Sep 2022 19:18:56 -0000       1.72
+++ arch/arm64/arm64/machdep.c  1 Oct 2022 10:05:15 -0000
@@ -433,7 +433,7 @@ setregs(struct proc *p, struct exec_pack
        tf->tf_sp = stack;
        tf->tf_lr = pack->ep_entry;
        tf->tf_elr = pack->ep_entry; /* ??? */
-       tf->tf_spsr = PSR_M_EL0t;
+       tf->tf_spsr = PSR_M_EL0t | PSR_DIT;
 
        retval[1] = 0;
 }
Index: arch/arm64/include/armreg.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/include/armreg.h,v
retrieving revision 1.21
diff -u -p -r1.21 armreg.h
--- arch/arm64/include/armreg.h 29 Aug 2022 02:01:18 -0000      1.21
+++ arch/arm64/include/armreg.h 1 Oct 2022 10:05:15 -0000
@@ -602,9 +602,13 @@
 #define        PSR_I           0x00000080
 #define        PSR_A           0x00000100
 #define        PSR_D           0x00000200
+#define        PSR_SSBS        0x00001000
 #define        PSR_IL          0x00100000
 #define        PSR_SS          0x00200000
 #define        PSR_PAN         0x00400000
+#define        PSR_UAO         0x00800000
+#define        PSR_DIT         0x01000000
+#define        PSR_TCO         0x02000000
 #define        PSR_V           0x10000000
 #define        PSR_C           0x20000000
 #define        PSR_Z           0x40000000

Reply via email to