In a previous blog post, Microsoft described the Spectre mitigations available under /Qspectre
. These mitigations, while not significantly impacting performance, do not protect against all possible speculative load attacks, described in industry research as Load Value Injection. We are now adding two new switches /Qspectre-load
and /Qspectre-load-cf
to provide a more complete mitigation of Spectre attacks based on loads for customers. These switches are only available on x86 and x64 platforms.
What do the new switches do?
The /Qspectre-load
flag specifies compiler generation of serializing instructions for every load instruction. For most loads, this entails adding an LFENCE
instruction after the load instruction. However, for control flow instructions, this approach does not work. In most cases, the instruction can be split into the load and control flow, so an LFENCE
can be inserted after the load. When this is not possible, such as for jmp [rax]
the compiler uses an alternate mitigation strategy, loading the target non-destructively before inserting an LFENCE
as follows:
xor rbx, [rax] xor rbx, [rax] lfence jmp [rax]
The /Qspectre-load-cf
flag provides a subset of this behavior, only protecting control flow instructions: JMP
, RET
, and CALL
.
If there are performance critical blocks of code that do not require protection, then you can disable these mitigations using __declspec(spectre(nomitigation))
. As these switches stop speculation of all loads, the performance impact is very high, so this mitigation is not appropriate everywhere.
What versions of MSVC support the /Qspectre-load and /Qspectre-load-cf switches?
These switches are available starting in Visual Studio 16.5 preview 3 and will be available in MSVC toolsets included in all future releases of Visual Studio (including Previews). They have also been released in all currently supported versions of Visual Studio 2017 and 2019 as follows:
How do I enable this?
Starting from Visual Studio 2019 version 16.5 Preview 3, developers can use these new Spectre mitigation options. To enable either new flag, select the flag you want from “Spectre Mitigation” under the “Code Generation” section of the project Property Pages:
Your feedback is key to deliver the best experience. If you have any questions, please feel free to ask us below. You can also send us your comments through e-mail. If you encounter problems with the experience or have suggestions for improvement, please Report A Problem or reach out via Developer Community. You can also find us on Twitter @VisualC.
The Load Value Injection attacks have been reported to mainly affect code running in enclaves. Does that mean only Intel SGX enclaves, or also Microsoft VBS enclaves?
Visual Studio Installer offers CRT, ATL, and MFC libraries built with Spectre mitigations. Have those been rebuilt with /Qspectre-load or /Qspectre-load-cf? I guess not; the slowdown is said to be massive, and MFC seems unlikely to be used in enclaves anyway.
This blog post was published already in February, then...
Can you leave some words about performance? Are there gains for LOB applications (financial services) using MFC which a user might notice?