aboutsummaryrefslogtreecommitdiff
path: root/src/internal/runtime
diff options
context:
space:
mode:
authorRoland Shoemaker <roland@golang.org>2024-07-15 10:05:37 -0700
committerRoland Shoemaker <roland@golang.org>2024-11-19 16:47:03 +0000
commitbc1da38c3d29b4950b302b36fd180bf86bdcb45c (patch)
tree4edcacc9052dea3fec962b782e1c16c87e1e29b3 /src/internal/runtime
parent44cea1234dc18352fec89285e94f92693034323d (diff)
downloadgo-bc1da38c3d29b4950b302b36fd180bf86bdcb45c.tar.xz
crypto/subtle: add DIT closure
Add a new function, WithDataIndependentTiming, which takes a function as an argument, and encloses it with calls to set/unset the DIT PSTATE bit on Arm64. Since DIT is OS thread-local, for the duration of the execution of WithDataIndependentTiming, we lock the goroutine to the OS thread, using LockOSThread. For long running operations, this is likely to not be performant, but we expect this to be tightly scoped around cryptographic operations that have bounded execution times. If locking to the OS thread turns out to be too slow, another option is to add a bit to the g state indicating if a goroutine has DIT enabled, and then have the scheduler enable/disable DIT when scheduling a g. Additionally, we add a new GODEBUG, dataindependenttiming, which allows setting DIT for an entire program. Running a program with dataindependenttiming=1 enables DIT for the program during initialization. In an ideal world PSTATE.DIT would be inherited from the parent thread, so we'd only need to set it in the main thread and then all subsequent threads would inherit the value. While this does happen in the Linux kernel [0], it is not the case for darwin [1]. Rather than add complex logic to only set it on darwin for each new thread, we just unconditionally set it in mstart1 and cgocallbackg1 regardless of the OS. DIT will already impose some overhead, and the cost of setting the bit is only ~two instructions (CALL, MSR), so it should be cheap enough. Fixes #66450 Updates #49702 [0] https://github.com/torvalds/linux/blob/e8bdb3c8be08c9a3edc0a373c0aa8729355a0705/arch/arm64/kernel/process.c#L373 [1] https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/arm64/status.c#L1666 Change-Id: I78eda691ff9254b0415f2b54770e5850a0179749 Reviewed-on: https://go-review.googlesource.com/c/go/+/598336 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/internal/runtime')
-rw-r--r--src/internal/runtime/sys/dit_arm64.go17
-rw-r--r--src/internal/runtime/sys/dit_arm64.s18
-rw-r--r--src/internal/runtime/sys/no_dit.go13
3 files changed, 48 insertions, 0 deletions
diff --git a/src/internal/runtime/sys/dit_arm64.go b/src/internal/runtime/sys/dit_arm64.go
new file mode 100644
index 0000000000..643fd770d5
--- /dev/null
+++ b/src/internal/runtime/sys/dit_arm64.go
@@ -0,0 +1,17 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64
+
+package sys
+
+import (
+ "internal/cpu"
+)
+
+var DITSupported = cpu.ARM64.HasDIT
+
+func EnableDIT() bool
+func DITEnabled() bool
+func DisableDIT()
diff --git a/src/internal/runtime/sys/dit_arm64.s b/src/internal/runtime/sys/dit_arm64.s
new file mode 100644
index 0000000000..fcb44d6f22
--- /dev/null
+++ b/src/internal/runtime/sys/dit_arm64.s
@@ -0,0 +1,18 @@
+#include "textflag.h"
+
+TEXT ·EnableDIT(SB),$0-1
+ MRS DIT, R0
+ UBFX $24, R0, $1, R1
+ MOVB R1, ret+0(FP)
+ MSR $1, DIT
+ RET
+
+TEXT ·DITEnabled(SB),$0-1
+ MRS DIT, R0
+ UBFX $24, R0, $1, R1
+ MOVB R1, ret+0(FP)
+ RET
+
+TEXT ·DisableDIT(SB),$0
+ MSR $0, DIT
+ RET
diff --git a/src/internal/runtime/sys/no_dit.go b/src/internal/runtime/sys/no_dit.go
new file mode 100644
index 0000000000..0589d0ca14
--- /dev/null
+++ b/src/internal/runtime/sys/no_dit.go
@@ -0,0 +1,13 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !arm64
+
+package sys
+
+var DITSupported = false
+
+func EnableDIT() bool { return false }
+func DITEnabled() bool { return false }
+func DisableDIT() {}