diff options
Diffstat (limited to 'Documentation/x86')
-rw-r--r-- | Documentation/x86/entry_64.txt | 18 | ||||
-rw-r--r-- | Documentation/x86/x86_64/kernel-stacks | 8 |
2 files changed, 17 insertions, 9 deletions
diff --git a/Documentation/x86/entry_64.txt b/Documentation/x86/entry_64.txt index 4a1c5c2dc5a9..9132b86176a3 100644 --- a/Documentation/x86/entry_64.txt +++ b/Documentation/x86/entry_64.txt | |||
@@ -78,9 +78,6 @@ The expensive (paranoid) way is to read back the MSR_GS_BASE value | |||
78 | xorl %ebx,%ebx | 78 | xorl %ebx,%ebx |
79 | 1: ret | 79 | 1: ret |
80 | 80 | ||
81 | and the whole paranoid non-paranoid macro complexity is about whether | ||
82 | to suffer that RDMSR cost. | ||
83 | |||
84 | If we are at an interrupt or user-trap/gate-alike boundary then we can | 81 | If we are at an interrupt or user-trap/gate-alike boundary then we can |
85 | use the faster check: the stack will be a reliable indicator of | 82 | use the faster check: the stack will be a reliable indicator of |
86 | whether SWAPGS was already done: if we see that we are a secondary | 83 | whether SWAPGS was already done: if we see that we are a secondary |
@@ -93,6 +90,15 @@ which might have triggered right after a normal entry wrote CS to the | |||
93 | stack but before we executed SWAPGS, then the only safe way to check | 90 | stack but before we executed SWAPGS, then the only safe way to check |
94 | for GS is the slower method: the RDMSR. | 91 | for GS is the slower method: the RDMSR. |
95 | 92 | ||
96 | So we try only to mark those entry methods 'paranoid' that absolutely | 93 | Therefore, super-atomic entries (except NMI, which is handled separately) |
97 | need the more expensive check for the GS base - and we generate all | 94 | must use idtentry with paranoid=1 to handle gsbase correctly. This |
98 | 'normal' entry points with the regular (faster) entry macros. | 95 | triggers three main behavior changes: |
96 | |||
97 | - Interrupt entry will use the slower gsbase check. | ||
98 | - Interrupt entry from user mode will switch off the IST stack. | ||
99 | - Interrupt exit to kernel mode will not attempt to reschedule. | ||
100 | |||
101 | We try to only use IST entries and the paranoid entry code for vectors | ||
102 | that absolutely need the more expensive check for the GS base - and we | ||
103 | generate all 'normal' entry points with the regular (faster) paranoid=0 | ||
104 | variant. | ||
diff --git a/Documentation/x86/x86_64/kernel-stacks b/Documentation/x86/x86_64/kernel-stacks index a01eec5d1d0b..e3c8a49d1a2f 100644 --- a/Documentation/x86/x86_64/kernel-stacks +++ b/Documentation/x86/x86_64/kernel-stacks | |||
@@ -40,9 +40,11 @@ An IST is selected by a non-zero value in the IST field of an | |||
40 | interrupt-gate descriptor. When an interrupt occurs and the hardware | 40 | interrupt-gate descriptor. When an interrupt occurs and the hardware |
41 | loads such a descriptor, the hardware automatically sets the new stack | 41 | loads such a descriptor, the hardware automatically sets the new stack |
42 | pointer based on the IST value, then invokes the interrupt handler. If | 42 | pointer based on the IST value, then invokes the interrupt handler. If |
43 | software wants to allow nested IST interrupts then the handler must | 43 | the interrupt came from user mode, then the interrupt handler prologue |
44 | adjust the IST values on entry to and exit from the interrupt handler. | 44 | will switch back to the per-thread stack. If software wants to allow |
45 | (This is occasionally done, e.g. for debug exceptions.) | 45 | nested IST interrupts then the handler must adjust the IST values on |
46 | entry to and exit from the interrupt handler. (This is occasionally | ||
47 | done, e.g. for debug exceptions.) | ||
46 | 48 | ||
47 | Events with different IST codes (i.e. with different stacks) can be | 49 | Events with different IST codes (i.e. with different stacks) can be |
48 | nested. For example, a debug interrupt can safely be interrupted by an | 50 | nested. For example, a debug interrupt can safely be interrupted by an |