Linux 6.18 to Boost Intel E-Core Performance with Retpoline Optimization
Are you an Intel user frustrated with performance dips due to Spectre mitigations? The upcoming Linux 6.18 kernel is set to bring some relief, particularly for users of Intel processors with E-cores. A recent optimization to the retpoline code, specifically targeting the penalty for prefix decode on Intel E-cores (Efficiency cores), has been merged into the Linux kernel. This update promises to improve performance on hybrid core architectures.
Understanding Retpolines and Spectre
The need for this optimization stems from the infamous Spectre Variant Two vulnerability (https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)). Spectre, discovered in 2018, allows malicious programs to potentially access sensitive data stored in the kernel or other applications’ memory. Retpolines are a software mitigation technique used to prevent speculative execution attacks like Spectre.
-
What are retpolines? Retpolines, short for “return trampolines,” are a software-based mitigation technique for Spectre V2. They essentially replace indirect jumps (which are vulnerable to speculative execution) with a series of return instructions that “trap” the speculative execution, preventing it from accessing unintended memory locations. They act as a software fence.
-
Why are they necessary? Modern CPUs aggressively speculate to improve performance, but this speculation can be exploited by Spectre to leak data. Retpolines help mitigate this risk by preventing the CPU from speculatively executing code along vulnerable paths.
The Challenge: Prefix Decode Penalties on Intel E-Cores
While retpolines effectively mitigate Spectre, they introduce performance overhead. This overhead can be particularly noticeable on Intel E-cores (like those found in hybrid architectures), where the penalty for decoding instruction prefixes is higher than on P-cores (Performance cores).
- What are prefix decode penalties? x86 instructions can have prefixes that modify their behavior. Decoding these prefixes takes time, impacting performance. Intel P-cores generally handle prefixes efficiently, but E-cores, based on the Atom microarchitecture, are more sensitive to prefix decode penalties.
- How do prefixes relate to retpolines? Retpoline implementations often involve adding prefixes to instructions, such as
CS(code segment override prefix) to change how memory locations are accessed. However, doing so can introduce more overhead. - What is the significance? Intel hybrid architectures combine P-cores and E-cores. The OS needs to manage workloads effectively and the kernel code must consider the nuances of running on both core types to avoid performance bottlenecks.
Peter Zijlstra’s Optimization: Balancing Security and Performance
Intel engineer Peter Zijlstra recognized this issue and developed a patch to optimize the x86_patch_retpoline() code. The goal was to minimize the performance impact of retpolines on Intel E-cores without compromising security.
The Problem: The original retpoline implementation transformed code like "CS CALL __x86_indirect_thunk_r11" into "CALL *R11; NOP3". The patch notes also noted a similar case for paranoid fineibt where "CALL *R11; NOP" existed.
The issue is that the code segment override can often be avoided with CS stuffing. However, the implementation needs to make sure that too many CS prefixes are not used. A case in point is "CS CALL __x86_indirect_thunk_rax" because the implementation is not allowed to turn that into "CS CS CS CS CALL *RAX".
The Solution: Zijlstra’s patch strategically uses code segment prefixes (CS) to avoid unnecessary NOP (no-operation) instructions. By cleverly “stuffing” code segment prefixes, the kernel can reduce the overall instruction count and mitigate the prefix decode penalty on E-cores. The patch also ensures an INT3 call follows the JMP instruction when a tail-call retpoline is detected as a straight-line speculation mitigation.
Key Aspects of the Optimization:
- Strategic use of CS prefixes: Avoiding excessive prefixes while leveraging them to eliminate NOP instructions.
- Prefix budget awareness: Considering the prefix decode penalties on different microarchitectures. The “wisdom” that 3 prefixes is good was followed, keeping in mind that the
0x0fescape code is often counted towards the prefix budget.REXprefixes, however, are typically not counted. - Targeted at E-cores: Recognizing the different performance characteristics of Intel P-cores and E-cores.
- Straight-line speculation mitigation: The
emit_indirect()function now handles the insertion of theINT3to mitigate straight-line speculation on tail calls. - Code consolidation: This was moved into the
emit_indirect()function such that other users (paranoid-fineibt) can use it too.
How This Optimization Impacts Performance
While precise performance figures aren’t available, the optimization is expected to provide a noticeable improvement in performance, especially on systems with Intel hybrid processors running workloads that rely heavily on indirect jumps. By reducing the overhead of retpolines, the patch aims to close the performance gap between mitigated and unmitigated systems.
- Impact on hybrid processors: The optimization should be most beneficial on systems with Intel hybrid processors (e.g., 12th Gen Alder Lake and newer) that feature both P-cores and E-cores. E-cores should especially see a boost.
- Workload dependence: The performance improvement will vary depending on the workload. Applications that frequently use indirect jumps will likely benefit the most.
- Overall system responsiveness: By improving the efficiency of retpolines, the optimization can contribute to a more responsive and fluid user experience.
Integration into Linux 6.18
The patch has been successfully merged into the Linux Git tree as part of the x86 core updates, meaning it will be included in the upcoming Linux 6.18 kernel release. This is great news for Linux users with Intel processors, particularly those running hybrid core architectures.
- Availability: The optimization will be available to all users once Linux 6.18 is released and they upgrade their kernels.
- Transparency: The patch is open-source and available for review on the Linux kernel mailing list. This allows for community scrutiny and further optimization.
Future Directions
This retpoline optimization is a welcome step towards improving the performance of systems using Spectre mitigations. It highlights the ongoing efforts to balance security and performance in modern processors. Future efforts may focus on:
- Further microarchitecture-specific optimizations: Tailoring mitigations to the specific characteristics of different CPU architectures.
- Hardware-assisted mitigations: Developing hardware-based solutions that can mitigate Spectre without the performance overhead of software mitigations.
- Compiler-level optimizations: Optimizing compilers to generate code that is less susceptible to speculative execution vulnerabilities.
Linux Kernel Development
The original source includes the comment “I hate all this.” by Intel engineer Peter Zijlstra, which may seem out of place at first glance. It is a commentary on the complexity and difficulty associated with optimizing software for various CPU architectures and handling security mitigations without significant performance overhead.
Conclusion
The inclusion of this retpoline optimization in Linux 6.18 is a significant win for Intel users, particularly those with hybrid core CPUs. By addressing the prefix decode penalty on E-cores, the patch promises to improve performance without compromising the security provided by Spectre mitigations. This update underscores the continuous effort by kernel developers and Intel engineers to optimize the Linux kernel for modern hardware.
What do you think of this retpoline optimization in Linux 6.18? Are you an Intel user excited about the potential performance gains? Share your thoughts in the comments below!
Sources & Further Reading:
Original article at www.phoronix.com


