diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index bea8474744ff..c7341e81941c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -582,7 +582,6 @@ retint_restore_args: /* return to kernel space */ | |||
582 | TRACE_IRQS_IRETQ | 582 | TRACE_IRQS_IRETQ |
583 | restore_args: | 583 | restore_args: |
584 | RESTORE_ARGS 0,8,0 | 584 | RESTORE_ARGS 0,8,0 |
585 | iret_label: | ||
586 | #ifdef CONFIG_PARAVIRT | 585 | #ifdef CONFIG_PARAVIRT |
587 | INTERRUPT_RETURN | 586 | INTERRUPT_RETURN |
588 | #endif | 587 | #endif |
@@ -593,13 +592,22 @@ ENTRY(native_iret) | |||
593 | .quad native_iret, bad_iret | 592 | .quad native_iret, bad_iret |
594 | .previous | 593 | .previous |
595 | .section .fixup,"ax" | 594 | .section .fixup,"ax" |
596 | /* force a signal here? this matches i386 behaviour */ | ||
597 | /* running with kernel gs */ | ||
598 | bad_iret: | 595 | bad_iret: |
599 | movq $11,%rdi /* SIGSEGV */ | 596 | /* |
600 | TRACE_IRQS_ON | 597 | * The iret traps when the %cs or %ss being restored is bogus. |
601 | ENABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI)) | 598 | * We've lost the original trap vector and error code. |
602 | jmp do_exit | 599 | * #GPF is the most likely one to get for an invalid selector. |
600 | * So pretend we completed the iret and took the #GPF in user mode. | ||
601 | * | ||
602 | * We are now running with the kernel GS after exception recovery. | ||
603 | * But error_entry expects us to have user GS to match the user %cs, | ||
604 | * so swap back. | ||
605 | */ | ||
606 | pushq $0 | ||
607 | |||
608 | SWAPGS | ||
609 | jmp general_protection | ||
610 | |||
603 | .previous | 611 | .previous |
604 | 612 | ||
605 | /* edi: workmask, edx: work */ | 613 | /* edi: workmask, edx: work */ |
@@ -911,7 +919,7 @@ error_kernelspace: | |||
911 | iret run with kernel gs again, so don't set the user space flag. | 919 | iret run with kernel gs again, so don't set the user space flag. |
912 | B stepping K8s sometimes report an truncated RIP for IRET | 920 | B stepping K8s sometimes report an truncated RIP for IRET |
913 | exceptions returning to compat mode. Check for these here too. */ | 921 | exceptions returning to compat mode. Check for these here too. */ |
914 | leaq iret_label(%rip),%rbp | 922 | leaq native_iret(%rip),%rbp |
915 | cmpq %rbp,RIP(%rsp) | 923 | cmpq %rbp,RIP(%rsp) |
916 | je error_swapgs | 924 | je error_swapgs |
917 | movl %ebp,%ebp /* zero extend */ | 925 | movl %ebp,%ebp /* zero extend */ |