Should Linux set the new constant-time mode CPU flags?
Subsystems (2)
Hi,
Intel and ARM recently published documentation that says that no instructions are guaranteed to be constant-time with respect to their data operands, unless a "data independent timing" flag in the IA32_UARCH_MISC_CTL register (Intel) or DIT register (arm64) is set:
* https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html
* https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/DIT--Data-Independent-Timing
This is a major problem for crypto code, which needs to be constant-time, especially with respect to keys. And since this is a CPU issue, it affects all code running on the CPU. While neither company is treating this as a security disclosure, to me this looks exactly like a CPU vulnerability.
For Intel, given that the mitigation is to set an MSR flag, it seems that the kernel will need to do that -- similar to the MSR flags that enable mitigations for speculative execution vulnerabilities.
For arm64, it's not clear to me whether the DIT flag is privileged or not. If privileged, I expect it would need to be set by the kernel just like the Intel flag. If unprivileged, I expect there will still be work to do in the kernel, as the flag will need to be set when running any crypto code in the kernel.
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to Adam Langley, who maintains BoringSSL, for bringing this to my attention.)
- Eric
Quoted 24 lines · Eric Biggers
Hi,
Intel and ARM recently published documentation that says that no instructions are guaranteed to be constant-time with respect to their data operands, unless a "data independent timing" flag in the
IA32_UARCH_MISC_CTLregister (Intel) or DIT register (arm64) is set:* https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html
* https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/DIT--Data-Independent-TimingThis is a major problem for crypto code, which needs to be constant-time, especially with respect to keys. And since this is a CPU issue, it affects all code running on the CPU. While neither company is treating this as a security disclosure, to me this looks exactly like a CPU vulnerability.
For Intel, given that the mitigation is to set an MSR flag, it seems that the kernel will need to do that -- similar to the MSR flags that enable mitigations for speculative execution vulnerabilities.
For arm64, it's not clear to me whether the DIT flag is privileged or not. If privileged, I expect it would need to be set by the kernel just like the Intel flag. If unprivileged, I expect there will still be work to do in the kernel, as the flag will need to be set when running any crypto code in the kernel.
Quoted 4 lines
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to Adam Langley, who maintains BoringSSL, for bringing this to my attention.)
Whichever way around I think you want OS support to make it a per-task property instead of a per CPU one.
Also, *sigh* yet another MSR to touch :/
Quoted 5 lines · Eric Biggers
For arm64, it's not clear to me whether the DIT flag is privileged or not. If privileged, I expect it would need to be set by the kernel just like the Intel flag. If unprivileged, I expect there will still be work to do in the kernel, as the flag will need to be set when running any crypto code in the kernel.
7206dc93a58f ("arm64: Expose Arm v8.4 features") added the feature bit for Armv8.4+ processors. From what I can tell from the documentation and the kernel source, I see:
- if the feature is set in HWCAP (or /proc/cpuinfo), then the instruction DIT register is available in user space, and sensitive code can set or clear the constant-time mode for the local thread.
- On CPUs without the feature (almost all ARMv8 ones), the register should not be touched.
- The bit is context switched on kernel entry, so setting the bit in user space does not change the behavior inside of a syscall
- If we add a user space interface for setting the bit per thread on x86, the same interface could be supported to set the bit on arm64 to save user space implementations the trouble of checking the feature bits
- the in-kernel crypto code does not set the bit today but could be easily changed to do this for CPUs that support it, if we can decide on a policy for when to enable or disable it.
Arnd
(catching up with this thread)
Quoted 6 lines · Arnd Bergmann
Quoted 4 lines · Eric Biggers
For arm64, it's not clear to me whether the DIT flag is privileged or not. If privileged, I expect it would need to be set by the kernel just like the Intel flag. If unprivileged, I expect there will still be work to do in the kernel, as the flag will need to be set when running any crypto code in the kernel.
Quoted 7 lines
7206dc93a58f("arm64: Expose Arm v8.4 features") added the feature bit for Armv8.4+ processors. From what I can tell from the documentation and the kernel source, I see:- if the feature is set in HWCAP (or
/proc/cpuinfo), then the instruction DIT register is available in user space, and sensitive code can set or clear the constant-time mode for the local thread.
Indeed, the arm64 DIT feature can be enabled in user space, subject to checking the HWCAP bit or the CPUID regs (via kernel trapping and emulation). The expectation was that some crypto routines would set it on function entry, restore it on return but...
Quoted 2 lines
- On CPUs without the feature (almost all ARMv8 ones), the register should not betouched.
That's one of the drawbacks of using the features in user-space (the instruction is not in the hint/nop space). It can be worked around with ifunc resolvers but with a slight overhead on function calling.
Quoted 5 lines
- The bit is context switched on kernel entry, so setting the bit in user space does not change the behavior inside of a syscall
- If we add a user space interface for setting the bit per thread on x86, the same interface could be supported to set the bit on arm64 to save user space implementations the trouble of checking the feature bits
A prctl() would do here but I think the default should be off or at least allow a sysctl to control this. Enabling DIT could have a small performance impact while lots of (most?) apps don't need such guarantees.
For arm64, my preference is to have this option per-thread and even be able to toggle it within a thread (not sure that's possible on x86 without a syscall).
Other random ideas of deploying this (for arm64): have an ELF annotation that data independent timing is required. If that's on the main executable, the kernel could turn it on for the app. If it's on a (crypto) library, it's up to the dynamic loader to either turn it on for the whole app or just use some function veneers to save/restore it when the library code is executed.
I assume having this per-thread would work on x86 as well but I'm not sure about the context switching cost.
Quoted 3 lines
- the in-kernel crypto code does not set the bit today but could be easily changed to do this for CPUs that support it, if we can decide on a policy for when to enable or disable it.
In the kernel it's easier, at least for arm64, to enable it for specific functions (we can do boot-time code patching).
Whichever way we support it, I'd rather not turn it on by default. Talking to some of the Arm microarchitects, such feature may prevent certain hardware optimisations.
Signature · 1 line
Catalin
Quoted 25 lines · Eric Biggers
Hi,
Intel and ARM recently published documentation that says that no instructions are guaranteed to be constant-time with respect to their data operands, unless a "data independent timing" flag in the
IA32_UARCH_MISC_CTLregister (Intel) or DIT register (arm64) is set:* https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html
* https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/DIT--Data-Independent-TimingThis is a major problem for crypto code, which needs to be constant-time, especially with respect to keys. And since this is a CPU issue, it affects all code running on the CPU. While neither company is treating this as a security disclosure, to me this looks exactly like a CPU vulnerability.
For Intel, given that the mitigation is to set an MSR flag, it seems that the kernel will need to do that -- similar to the MSR flags that enable mitigations for speculative execution vulnerabilities.
For arm64, it's not clear to me whether the DIT flag is privileged or not. If privileged, I expect it would need to be set by the kernel just like the Intel flag. If unprivileged, I expect there will still be work to do in the kernel, as the flag will need to be set when running any crypto code in the kernel.
Quoted 4 lines
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to Adam Langley, who maintains BoringSSL, for bringing this to my attention.)
The thought that comes to mind for me is, please make setting/clearing the bit available in userland. Libraries like Botan, Crypto++ and OpenSSL could benefit from it.
Jeff
Hi Eric,
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
In terms of granularity, I saw other folks suggesting making it per-task (so, presumably, a prctl() knob), and others mentioning doing it just for kernel crypto. For the latter, I guess the crypto API could set it inside of its abstractions, and the various lib/crypto APIs could set it at invocation time. I wonder, though, what's the cost of enabling/disabling it? Would we in fact need a kind of lazy-deferred disabling, like we have with kernel_fpu_end()? I also wonder what crypto-adjacent code might wind up being missed if we're going function by function. Like, obviously we'd set this for crypto_memneq, but what about potential unprotected == of ID numbers that could leak some info in various protocols? What other subtle nearby code should we be thinking about, that relies on constant time logic but isn't neatly folded inside a crypto_do_something() function?
Jason
Quoted 10 lines · Jason A. Donenfeld
Hi Eric,
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
Quoted 14 lines
In terms of granularity, I saw other folks suggesting making it per-task (so, presumably, a
prctl()knob), and others mentioning doing it just for kernel crypto. For the latter, I guess the crypto API could set it inside of its abstractions, and the various lib/crypto APIs could set it at invocation time. I wonder, though, what's the cost of enabling/disabling it? Would we in fact need a kind of lazy-deferred disabling, like we have withkernel_fpu_end()? I also wonder what crypto-adjacent code might wind up being missed if we're going function by function. Like, obviously we'd set this forcrypto_memneq, but what about potential unprotected==of ID numbers that could leak some info in various protocols? What other subtle nearby code should we be thinking about, that relies on constant time logic but isn't neatly folded inside acrypto_do_something()function?
I'd much prefer it being set unconditionally by default as well, as making everyone (both kernel and userspace) turn it on and off constantly would be a nightmare.
Note that Intel's documentation says that CPUs before Ice Lake behave as if DOITM is always set:
"For Intel® Core™ family processors based on microarchitectures before Ice Lake and Intel Atom® family processors based on microarchitectures before Gracemont that do not enumerate IA32_UARCH_MISC_CTL, developers may assume that the instructions listed here operate as if DOITM is enabled."
(It's a bit ambiguous, as it leaves the door open to IA32_UARCH_MISC_CTL being retroactively added to old CPUs. But I assume that hasn't actually happened.)
So I think the logical approach is to unconditionally set DOITM by default, to fix this CPU bug in Ice Lake and later and just bring things back to the way they were in CPUs before Ice Lake. With that as a baseline, we can then discuss whether it's useful to provide ways to re-enable this CPU bug / "feature", for people who want to get the performance boost (if one actually exists) of data dependent timing after carefully assessing the risks.
The other way around, of making everything insecure by default, seems like a really bad idea.
- Eric
Quoted 22 lines · Eric Biggers
I'd much prefer it being set unconditionally by default as well, as making everyone (both kernel and userspace) turn it on and off constantly would be a nightmare.
Note that Intel's documentation says that CPUs before Ice Lake behave as if DOITM is always set:
"For Intel® Core™ family processors based on microarchitectures before Ice Lake and Intel Atom® family processors based on microarchitectures before Gracemont that do not enumerate
IA32_UARCH_MISC_CTL, developers may assume that the instructions listed here operate as if DOITM is enabled."(It's a bit ambiguous, as it leaves the door open to
IA32_UARCH_MISC_CTLbeing retroactively added to old CPUs. But I assume that hasn't actually happened.)So I think the logical approach is to unconditionally set DOITM by default, to fix this CPU bug in Ice Lake and later and just bring things back to the way they were in CPUs before Ice Lake. With that as a baseline, we can then discuss whether it's useful to provide ways to re-enable this CPU bug / "feature", for people who want to get the performance boost (if one actually exists) of data dependent timing after carefully assessing the risks.
Quoted 2 lines
The other way around, of making everything insecure by default, seems like a really bad idea.
Right. It's actually kind of surprising that Intel didn't already do this by default. Sure, maybe the Intel manual never explicitly guaranteed constant time, but a heck of a lot of code relies on that being the case.
Jason
Quoted 5 lines · Jason A. Donenfeld
In terms of granularity, I saw other folks suggesting making it per-task (so, presumably, a
prctl()knob), and others mentioning doing it just for kernel crypto. For the latter, I guess the crypto API could set it inside of its abstractions, and the various lib/crypto APIs could set it at invocation time. I wonder, though, what's the cost of
Quoted 8 lines
enabling/disabling it? Would we in fact need a kind of lazy-deferred disabling, like we have with
kernel_fpu_end()? I also wonder what crypto-adjacent code might wind up being missed if we're going function by function. Like, obviously we'd set this forcrypto_memneq, but what about potential unprotected==of ID numbers that could leak some info in various protocols? What other subtle nearby code should we be thinking about, that relies on constant time logic but isn't neatly folded inside acrypto_do_something()function?
Another random note on this: I would hope that setting that MSR represents a speculation barrier or general instruction stream barrier, so that you can't do something naughty with the scheduler to toggle it rapidly and measure crypto timings somehow.
Quoted 6 lines · Jason A. Donenfeld
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
Personally, I'm in this camp as well. Let's be safe and set it by default. There's also this tidbit in the Intel docs (and chopping out a bunch of the noise):
(On) processors based on microarchitectures before Ice Lake ... the instructions listed here operate as if DOITM is enabled.
IOW, setting DOITM=0 isn't going back to the stone age. At worst, I'd guess that you're giving up some optimization that only shows up in very recent CPUs in the first place.
If folks want DOITM=1 on their snazzy new CPUs, then they came come with performance data to demonstrate the gain they'll get from adding kernel code to get DOITM=1. There are a range of ways we could handle it, all the way from adding a command-line parameter to per-task management.
Anybody disagree?
Quoted 19 lines · Dave Hansen
Quoted 6 lines · Jason A. Donenfeld
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
Personally, I'm in this camp as well. Let's be safe and set it by default. There's also this tidbit in the Intel docs (and chopping out a bunch of the noise):
(On) processors based on microarchitectures before Ice Lake ... the instructions listed here operate as if DOITM is enabled.
IOW, setting DOITM=0 isn't going back to the stone age. At worst, I'd guess that you're giving up some optimization that only shows up in very recent CPUs in the first place.
Quoted 6 lines
If folks want DOITM=1 on their snazzy new CPUs, then they came come with performance data to demonstrate the gain they'll get from adding kernel code to get DOITM=1. There are a range of ways we could handle it, all the way from adding a command-line parameter to per-task management.
Anybody disagree?
Since I'm not feeling too well I figured I'd do something trivial and whipped up the below patch.
--- arch/x86/include/asm/cpufeatures.h | 3 ++ arch/x86/include/asm/msr-index.h | 4 +++ arch/x86/kernel/cpu/common.c | 69 ++++++++++++++++++++++++++++++-------- arch/x86/kernel/cpu/scattered.c | 1 + 4 files changed, 63 insertions(+), 14 deletions(-)
arch/x86/include/asm/cpufeatures.h +3 -0
@@ -305,6 +305,7 @@#define X86_FEATURE_USE_IBPB_FW (11*32+16)/* "" Use IBPB during runtime firmware calls */ #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17)/* "" Fill RSB on VM exit when EIBRS is enabled */ #define X86_FEATURE_CALL_DEPTH (11*32+18)/* "" Call depth tracking for RSB stuffing */ +#define X86_FEATURE_MCDT_NO (11*32+19)/* Not affected by MCDT */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4)/* AVX VNNI instructions */
@@ -460,5 +461,7 @@#define X86_BUG_MMIO_STALE_DATA X86_BUG(25)/* CPU is affected by Processor MMIO Stale Data vulnerabilities */ #define X86_BUG_RETBLEED X86_BUG(26)/* CPU is affected by RETBleed */ #define X86_BUG_EIBRS_PBRSB X86_BUG(27)/* EIBRS is vulnerable to Post Barrier RSB Predictions */ +#define X86_BUG_DOIT X86_BUG(28) +#define X86_BUG_MCDT X86_BUG(29)#endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/include/asm/msr-index.h +4 -0
@@ -119,6 +119,7 @@* Not susceptible to * TSX Async Abort (TAA) vulnerabilities. */ +#define ARCH_CAP_DOIT BIT(12)/* Data Operand Independent Timing */ #define ARCH_CAP_SBDR_SSDP_NO BIT(13)/* * Not susceptible to SBDR and SSDP * variants of Processor MMIO stale data
@@ -155,6 +156,9 @@* Return Stack Buffer Predictions. */ +#define MSR_IA32_UARCH_MISC_CTL 0x00001b01 +#define UARCH_MISC_DOIT BIT(0)/* Enable DOIT */ +#define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/* * Writeback and invalidate the
arch/x86/kernel/cpu/common.c +55 -14
105 lines not on this page · raw message
arch/x86/kernel/cpu/scattered.c +1 -0
@@ -27,6 +27,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 }, { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 }, + { X86_FEATURE_MCDT_NO, CPUID_ECX, 5, 0x00000007, 2 }, { X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 }, { X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 }, { X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 },
Quoted 10 lines · Peter Zijlstra
Since I'm not feeling too well I figured I'd do something trivial and whipped up the below patch.
--- arch/x86/include/asm/cpufeatures.h | 3 ++ arch/x86/include/asm/msr-index.h | 4 +++ arch/x86/kernel/cpu/common.c | 69 ++++++++++++++++++++++++++++++-------- arch/x86/kernel/cpu/scattered.c | 1 + 4 files changed, 63 insertions(+), 14 deletions(-)
We still need to do something about this. As this thread died out, I'll revive it by reviewing this patch. (I'm not an expert in arch/x86/ stuff, though!)
arch/x86/include/asm/cpufeatures.h line 308
Quoted 9 lines
arch/x86/include/asm/cpufeatures.h +1
-0@@ -305,6 +305,7 @@#define X86_FEATURE_USE_IBPB_FW (11*32+16)/* "" Use IBPB during runtime firmware calls */ #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17)/* "" Fill RSB on VM exit when EIBRS is enabled */ #define X86_FEATURE_CALL_DEPTH (11*32+18)/* "" Call depth tracking for RSB stuffing */ +#define X86_FEATURE_MCDT_NO (11*32+19)/* Not affected by MCDT */
Some of the other CPU feature flags have comments beginning with "", which apparently results in the feature not being listed in /proc/cpuinfo. (This header file is run through a shell script that looks at these comments and generates C code...) Should this "feature" be listed in /proc/cpuinfo?
Looking for examples of other "feature" flags that mean that a CPU is not vulnerable to something, I found X86_FEATURE_AMD_SSB_NO and X86_FEATURE_BTC_NO. Those aren't listed in /proc/cpuinfo. Maybe this should be the same?
Side note: maybe the comment should spell out "MXCSR Configuration Dependent Timing"? Acronyms can be hard to read.
arch/x86/include/asm/cpufeatures.h line 464
Quoted 1 line
arch/x86/include/asm/cpufeatures.h +1
-0+#define X86_BUG_DOIT X86_BUG(28)
Maybe it should be X86_BUG_DODT? The bug is data operand *dependent* timing. Data operand *independent* timing is the desired behavior and the fix.
arch/x86/include/asm/cpufeatures.h line 465
Quoted 1 line
arch/x86/include/asm/cpufeatures.h +1
-0+#define X86_BUG_MCDT X86_BUG(29)
According to Intel's documentation
(https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html),
MCDT is a separate bug which requires a separate mitigation. So I think any MCDT related stuff should be in a separate patch from DOITM.
But more importantly, this patch doesn't actually implement any mitigation for MCDT. Should we be doing that? Intel recommends writing a certain value to MXCSR to mitigate MCDT. Is that feasible?
Quoted 15 lines
arch/x86/include/asm/cpufeatures.h +0
-0#endif /* _ASM_X86_CPUFEATURES_H */ arch/x86/include/asm/msr-index.h +1
-0@@ -119,6 +119,7 @@* Not susceptible to * TSX Async Abort (TAA) vulnerabilities. */ +#define ARCH_CAP_DOIT BIT(12)/* Data Operand Independent Timing */ #define ARCH_CAP_SBDR_SSDP_NO BIT(13)/* * Not susceptible to SBDR and SSDP * variants of Processor MMIO stale data
arch/x86/include/asm/msr-index.h line 160
Quoted 5 lines
arch/x86/include/asm/msr-index.h +2
-0@@ -155,6 +156,9 @@* Return Stack Buffer Predictions. */ +#define MSR_IA32_UARCH_MISC_CTL 0x00001b01 +#define UARCH_MISC_DOIT BIT(0)/* Enable DOIT */
The Intel documentation calls this bit "DOITM" (Data Operand Independent Timing Mode), not "DOIT".
arch/x86/include/asm/msr-index.h
Quoted 9 lines
arch/x86/include/asm/msr-index.h +9
-0+static __always_inline void setup_doit(struct cpuinfo_x86 *c) +{ +u64 msr =0 ; + +if (!cpu_has (c,X86_BUG_DOIT )) +return ; + +if (!doit_disabled) +return ;
This is backwards; it needs to be 'if (doit_disabled)'.
arch/x86/kernel/cpu/scattered.c static const struct cpuid_bit cpuid_bits[] = { · line 30
Quoted 9 lines
arch/x86/kernel/cpu/scattered.c +1
-0@@ -27,6 +27,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 }, { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 }, + { X86_FEATURE_MCDT_NO, CPUID_ECX, 5, 0x00000007, 2 },
The Intel documentation says this bit is CPUID.(EAX=7H,ECX=2):EDX[5]=1. So CPUID_ECX is wrong; it needs to be CPUID_EDX.
- Eric
Quoted 19 lines · Dave Hansen
Quoted 6 lines · Jason A. Donenfeld
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
Personally, I'm in this camp as well. Let's be safe and set it by default. There's also this tidbit in the Intel docs (and chopping out a bunch of the noise):
(On) processors based on microarchitectures before Ice Lake ... the instructions listed here operate as if DOITM is enabled.
IOW, setting DOITM=0 isn't going back to the stone age. At worst, I'd guess that you're giving up some optimization that only shows up in very recent CPUs in the first place.
Quoted 6 lines
If folks want DOITM=1 on their snazzy new CPUs, then they came come with performance data to demonstrate the gain they'll get from adding kernel code to get DOITM=1. There are a range of ways we could handle it, all the way from adding a command-line parameter to per-task management.
Anybody disagree?
It's not my preferred option for arm64 but I admit the same reasoning could equally apply to us. If some existing crypto libraries relied on data independent timing for current CPUs but newer ones (with the DIT feature) come up with more aggressive, data-dependent optimisations, they may be caught off-guard. That said the ARM architecture spec never promised any timing, that's a micro-architecture detail and not all implementations are done by ARM Ltd. So I can't really tell what's out there.
So I guess knobs for finer grained control would do, at least a sysctl (or cmdline) to turn it on/off globally and maybe a prctl() for user. We don't necessarily need this on arm64 but if x86 adds one, we might as well wire it up.
Signature · 1 line
Catalin
Quoted 37 lines · Catalin Marinas
Quoted 19 lines · Dave Hansen
Quoted 6 lines · Jason A. Donenfeld
Quoted 3 lines · Eric Biggers
I'm wondering if people are aware of this issue, and whether anyone has any thoughts on whether/where the kernel should be setting these new CPU flags. There don't appear to have been any prior discussions about this. (Thanks to
Maybe it should be set unconditionally now, until we figure out how to make it more granular.
Personally, I'm in this camp as well. Let's be safe and set it by default. There's also this tidbit in the Intel docs (and chopping out a bunch of the noise):
(On) processors based on microarchitectures before Ice Lake ... the instructions listed here operate as if DOITM is enabled.
IOW, setting DOITM=0 isn't going back to the stone age. At worst, I'd guess that you're giving up some optimization that only shows up in very recent CPUs in the first place.
Quoted 6 lines
If folks want DOITM=1 on their snazzy new CPUs, then they came come with performance data to demonstrate the gain they'll get from adding kernel code to get DOITM=1. There are a range of ways we could handle it, all the way from adding a command-line parameter to per-task management.
Anybody disagree?
It's not my preferred option for arm64 but I admit the same reasoning could equally apply to us. If some existing crypto libraries relied on data independent timing for current CPUs but newer ones (with the DIT feature) come up with more aggressive, data-dependent optimisations, they may be caught off-guard. That said the ARM architecture spec never promised any timing, that's a micro-architecture detail and not all implementations are done by ARM Ltd. So I can't really tell what's out there.
Quoted 5 lines
So I guess knobs for finer grained control would do, at least a sysctl (or cmdline) to turn it on/off globally and maybe a
prctl()for user. We don't necessarily need this on arm64 but if x86 adds one, we might as well wire it up.
With all the effort spent on plugging timing leaks in the kernel over the past couple of years, not enabling this at EL1 seems silly, no? Why would we ever permit privileged code to exhibit data dependent timing variances?
As for a prctl() for user space - wouldn't it make more sense to enable this by default, and add a hwcap so user space can clear DIT directly if it feels the need to do so?