diff options
-rw-r--r-- | arch/x86/entry/entry_64.S | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 54b1b0468b2b..670306f588bf 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -1256,31 +1256,32 @@ END(paranoid_entry) | |||
1256 | ENTRY(paranoid_exit) | 1256 | ENTRY(paranoid_exit) |
1257 | UNWIND_HINT_REGS | 1257 | UNWIND_HINT_REGS |
1258 | DISABLE_INTERRUPTS(CLBR_ANY) | 1258 | DISABLE_INTERRUPTS(CLBR_ANY) |
1259 | TRACE_IRQS_OFF_DEBUG | ||
1260 | 1259 | ||
1261 | /* Handle GS depending on FSGSBASE availability */ | 1260 | /* |
1262 | ALTERNATIVE "jmp .Lparanoid_exit_checkgs", "nop",X86_FEATURE_FSGSBASE | 1261 | * The order of operations is important. IRQ tracing requires |
1262 | * kernel GSBASE and CR3. RESTORE_CR3 requires kernel GS base. | ||
1263 | * | ||
1264 | * NB to anyone to tries to optimize this code: this code does | ||
1265 | * not execute at all for exceptions coming from user mode. Those | ||
1266 | * exceptions go through error_exit instead. | ||
1267 | */ | ||
1268 | TRACE_IRQS_IRETQ_DEBUG | ||
1269 | RESTORE_CR3 scratch_reg=%rax save_reg=%r14 | ||
1270 | |||
1271 | /* Handle the three GSBASE cases. */ | ||
1272 | ALTERNATIVE "jmp .Lparanoid_exit_checkgs", "", X86_FEATURE_FSGSBASE | ||
1263 | 1273 | ||
1264 | /* With FSGSBASE enabled, unconditionally restore GSBASE */ | 1274 | /* With FSGSBASE enabled, unconditionally restore GSBASE */ |
1265 | wrgsbase %rbx | 1275 | wrgsbase %rbx |
1266 | jmp .Lparanoid_exit_no_swapgs; | 1276 | jmp restore_regs_and_return_to_kernel |
1267 | 1277 | ||
1268 | .Lparanoid_exit_checkgs: | 1278 | .Lparanoid_exit_checkgs: |
1269 | /* On non-FSGSBASE systems, conditionally do SWAPGS */ | 1279 | /* On non-FSGSBASE systems, conditionally do SWAPGS */ |
1270 | testl %ebx, %ebx | 1280 | testl %ebx, %ebx |
1271 | jnz .Lparanoid_exit_no_swapgs | 1281 | jnz restore_regs_and_return_to_kernel |
1272 | TRACE_IRQS_IRETQ | ||
1273 | /* Always restore stashed CR3 value (see paranoid_entry) */ | ||
1274 | RESTORE_CR3 scratch_reg=%rbx save_reg=%r14 | ||
1275 | SWAPGS_UNSAFE_STACK | ||
1276 | jmp .Lparanoid_exit_restore | ||
1277 | |||
1278 | .Lparanoid_exit_no_swapgs: | ||
1279 | TRACE_IRQS_IRETQ_DEBUG | ||
1280 | /* Always restore stashed CR3 value (see paranoid_entry) */ | ||
1281 | RESTORE_CR3 scratch_reg=%rbx save_reg=%r14 | ||
1282 | 1282 | ||
1283 | .Lparanoid_exit_restore: | 1283 | /* We are returning to a context with user GSBASE. */ |
1284 | SWAPGS_UNSAFE_STACK | ||
1284 | jmp restore_regs_and_return_to_kernel | 1285 | jmp restore_regs_and_return_to_kernel |
1285 | END(paranoid_exit) | 1286 | END(paranoid_exit) |
1286 | 1287 | ||