1.. SPDX-License-Identifier: GPL-2.0 2 3========================================= 4Flexible Return and Event Delivery (FRED) 5========================================= 6 7Overview 8======== 9 10The FRED architecture defines simple new transitions that change 11privilege level (ring transitions). The FRED architecture was 12designed with the following goals: 13 141) Improve overall performance and response time by replacing event 15 delivery through the interrupt descriptor table (IDT event 16 delivery) and event return by the IRET instruction with lower 17 latency transitions. 18 192) Improve software robustness by ensuring that event delivery 20 establishes the full supervisor context and that event return 21 establishes the full user context. 22 23The new transitions defined by the FRED architecture are FRED event 24delivery and, for returning from events, two FRED return instructions. 25FRED event delivery can effect a transition from ring 3 to ring 0, but 26it is used also to deliver events incident to ring 0. One FRED 27instruction (ERETU) effects a return from ring 0 to ring 3, while the 28other (ERETS) returns while remaining in ring 0. Collectively, FRED 29event delivery and the FRED return instructions are FRED transitions. 30 31In addition to these transitions, the FRED architecture defines a new 32instruction (LKGS) for managing the state of the GS segment register. 33The LKGS instruction can be used by 64-bit operating systems that do 34not use the new FRED transitions. 35 36Furthermore, the FRED architecture is easy to extend for future CPU 37architectures. 38 39Software based event dispatching 40================================ 41 42FRED operates differently from IDT in terms of event handling. Instead 43of directly dispatching an event to its handler based on the event 44vector, FRED requires the software to dispatch an event to its handler 45based on both the event's type and vector. Therefore, an event dispatch 46framework must be implemented to facilitate the event-to-handler 47dispatch process. The FRED event dispatch framework takes control 48once an event is delivered, and employs a two-level dispatch. 49 50The first level dispatching is event type based, and the second level 51dispatching is event vector based. 52 53Full supervisor/user context 54============================ 55 56FRED event delivery atomically save and restore full supervisor/user 57context upon event delivery and return. Thus it avoids the problem of 58transient states due to %cr2 and/or %dr6, and it is no longer needed 59to handle all the ugly corner cases caused by half baked entry states. 60 61FRED allows explicit unblock of NMI with new event return instructions 62ERETS/ERETU, avoiding the mess caused by IRET which unconditionally 63unblocks NMI, e.g., when an exception happens during NMI handling. 64 65FRED always restores the full value of %rsp, thus ESPFIX is no longer 66needed when FRED is enabled. 67 68LKGS 69==== 70 71LKGS behaves like the MOV to GS instruction except that it loads the 72base address into the IA32_KERNEL_GS_BASE MSR instead of the GS 73segment’s descriptor cache. With LKGS, it ends up with avoiding 74mucking with kernel GS, i.e., an operating system can always operate 75with its own GS base address. 76 77Because FRED event delivery from ring 3 and ERETU both swap the value 78of the GS base address and that of the IA32_KERNEL_GS_BASE MSR, plus 79the introduction of LKGS instruction, the SWAPGS instruction is no 80longer needed when FRED is enabled, thus is disallowed (#UD). 81 82Stack levels 83============ 84 854 stack levels 0~3 are introduced to replace the nonreentrant IST for 86event handling, and each stack level should be configured to use a 87dedicated stack. 88 89The current stack level could be unchanged or go higher upon FRED 90event delivery. If unchanged, the CPU keeps using the current event 91stack. If higher, the CPU switches to a new event stack specified by 92the MSR of the new stack level, i.e., MSR_IA32_FRED_RSP[123]. 93 94Only execution of a FRED return instruction ERET[US], could lower the 95current stack level, causing the CPU to switch back to the stack it was 96on before a previous event delivery that promoted the stack level. 97