Help developers and deployers defend against speculative-execution (“Spectre”) vulnerabilities by providing a means to limit speculative execution, and enable further mitigations to be implemented in future releases.
It is not a goal to automatically detect when speculative execution should be limited. End users will have to make that determination.
It is not a goal to provide a complete defense against all forms of speculative execution.
One of the defenses against speculative-execution vulnerabilities is to recompile C and C++ code with compiler options that limit the extent to which the CPU can do speculative execution. Limiting speculative execution can, however, impact performance. This impact can be significant for the C and C++ code in the JDK.
We will therefore include a distinct, alternate JVM in the JDK that is compiled with these options and can be selected at launch time. We will compile all non-JVM code with these options by default; since the performance impact is small, it’s not worth including second copies of all of that code.
It will be up to the end user to decide whether to limit speculative execution. The performance impact may vary widely based on such factors as CPU type, operating system, and workload, and should be assessed via performance testing. If untrusted code is running anywhere on the system, however, then we recommend using the alternate JVM.
Selecting and detecting the alternate JVM
A new launcher command-line option,
select the alternate JVM. The current JVM, which does not limit
speculative execution, will remain the default.
The output of
java --version will indicate which JVM is being used.
$ java --version java 11-ea 2018-09-25 Java(TM) SE Runtime Environment 18.9 (build 11-ea+19) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11-ea+19, mixed mode, sharing) $ java -nonspeculative --version java 11-ea 2018-09-25 Java(TM) SE Runtime Environment 18.9 (build 11-ea+19) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11-ea+19, limit speculative execution, mixed mode) $
(This is a custom-built JDK; the exact output in a product build will be slightly different.)
On platforms where the alternate JVM is not available, but explicitly asked for with the -nonspeculative flag, an error will be displayed and the JVM will terminate:
Unrecognized option: -nonspeculative Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.
Differences in the alternate JVM
The alternate JVM will be compiled as follows:
Linux(*): The following gcc options will be enabled:
-mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register(requires gcc 7.3.0+)
Windows: The following VisualStudio compiler option will be enabled:
/Qspectre(requires VS2017 15.5+)
(*) Linux platforms where gcc is used and the relevant flags are implemented, e.g. x86/x64.
The JIT compilers in the JVM will also need to be updated in much the same way as the C/C++ compilers have been. The changes might have a significant performance impact on most JIT compiled code and for this reason the JIT compiler changes will only be enabled in the alternate JVM. In future releases we may include additional changes in the alternate JVM to strengthen the defense that it provides.
This feature does not require new functional tests, but appropriate stress and performance testing should be done on the alternate JVM.