Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1166373 > unrolled thread
| Started by | Andy Lutomirski <luto@kernel.org> |
|---|---|
| First post | 2015-06-16 22:20 +0200 |
| Last post | 2015-06-16 22:30 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[RFC/INCOMPLETE 00/13] x86: Rewrite exit-to-userspace code Andy Lutomirski <luto@kernel.org> - 2015-06-16 22:20 +0200
[RFC/INCOMPLETE 10/13] x86/asm/entry/64: Save all regs on interrupt entry Andy Lutomirski <luto@kernel.org> - 2015-06-16 22:30 +0200
[RFC/INCOMPLETE 09/13] x86/entry/compat: Migrate compat syscalls to new exit hooks Andy Lutomirski <luto@kernel.org> - 2015-06-16 22:30 +0200
[RFC/INCOMPLETE 11/13] x86/asm/entry/64: Simplify irq stack pt_regs handling Andy Lutomirski <luto@kernel.org> - 2015-06-16 22:30 +0200
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-06-16 22:20 +0200 |
| Subject | [RFC/INCOMPLETE 00/13] x86: Rewrite exit-to-userspace code |
| Message-ID | <pC5uV-4CR-3@gated-at.bofh.it> |
This is incomplete, but it's finally good enough that I think it's time to get other opinions on it. It is a complete rewrite of the slow path code that handles exits to user mode. The exit-to-usermode code is copied in several places and is written in a nasty combination of asm and C. It's not at all clear what it's supposed to do, and the way it's structured makes it very hard to work with. For example, it's not even clear why syscall exit hooks are called only once per syscall right now. (It seems to be a side effect of the way that rdi and rdx are handled in the asm loop, and it seems reliable, but it's still pointlessly complicated.) The existing code also makes context tracking overly complicated and hard to understand. Finally, it's nearly impossible for anyone to change what happens on exit to usermode, since the existing code is so fragile. I tried to clean it up incrementally, but I decided it was too hard. Instead, this series just replaces the code. It seems to work. Context tracking in particular works very differently now. The low-level entry code checks that we're in CONTEXT_USER and switches to CONTEXT_KERNEL. The exit code does the reverse. There is no need to track what CONTEXT_XYZ state we came from, because we already know. Similarly, SCHEDULE_USER is gone, since we can reschedule if needed by simply calling schedule() from C code. The main things that are missing are that I haven't done the 32-bit parts (anyone want to help?) and therefore I haven't deleted the old C code. I also think this may break UML for trivial reasons. Because I haven't converted the 32-bit code yet, all of the now-unnecessary unnecessary calls to exception_enter are still present in traps.c. IRQ context tracking is still duplicated. We should probably clean it up by changing the core code to supply something like irq_enter_we_are_already_in_context_kernel. Thoughts? Andy Lutomirski (13): context_tracking: Add context_tracking_assert_state notifiers: Assert that RCU is watching in notify_die x86: Move C entry and exit code to arch/x86/entry/common.c x86/traps: Assert that we're in CONTEXT_KERNEL in exception entries x86/entry: Add enter_from_user_mode and use it in syscalls x86/entry: Add new, comprehensible entry and exit hooks x86/entry/64: Really create an error-entry-from-usermode code path x86/entry/64: Migrate 64-bit syscalls to new exit hooks x86/entry/compat: Migrate compat syscalls to new exit hooks x86/asm/entry/64: Save all regs on interrupt entry x86/asm/entry/64: Simplify irq stack pt_regs handling x86/asm/entry/64: Migrate error and interrupt exit work to C x86/entry: Remove SCHEDULE_USER and asm/context-tracking.h arch/x86/entry/Makefile | 1 + arch/x86/entry/common.c | 372 ++++++++++++++++++++++++++++++++ arch/x86/entry/entry_64.S | 176 ++++----------- arch/x86/entry/entry_64_compat.S | 7 +- arch/x86/include/asm/context_tracking.h | 10 - arch/x86/include/asm/signal.h | 1 + arch/x86/kernel/ptrace.c | 202 +---------------- arch/x86/kernel/signal.c | 28 +-- arch/x86/kernel/traps.c | 9 + include/linux/context_tracking.h | 8 + kernel/notifier.c | 2 + 11 files changed, 439 insertions(+), 377 deletions(-) create mode 100644 arch/x86/entry/common.c delete mode 100644 arch/x86/include/asm/context_tracking.h -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-06-16 22:30 +0200 |
| Subject | [RFC/INCOMPLETE 10/13] x86/asm/entry/64: Save all regs on interrupt entry |
| Message-ID | <pC5EB-4Oe-3@gated-at.bofh.it> |
| In reply to | #1166373 |
To prepare for the big rewrite of the error and interrupt exit paths, we will need pt_regs completely filled in. It's already completely filled in when error_exit runs, so rearrange interrupt handling to match it. This will slow down interrupt handling very slightly (eight instructions), but the simplification it enables will be more than worth it. Signed-off-by: Andy Lutomirski <luto@kernel.org> --- arch/x86/entry/entry_64.S | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index a5044d7a9d43..43bf5762443c 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -501,21 +501,13 @@ END(irq_entries_start) /* 0(%rsp): ~(interrupt number) */ .macro interrupt func cld - /* - * Since nothing in interrupt handling code touches r12...r15 members - * of "struct pt_regs", and since interrupts can nest, we can save - * four stack slots and simultaneously provide - * an unwind-friendly stack layout by saving "truncated" pt_regs - * exactly up to rbp slot, without these members. - */ - ALLOC_PT_GPREGS_ON_STACK -RBP - SAVE_C_REGS -RBP - /* this goes to 0(%rsp) for unwinder, not for saving the value: */ - SAVE_EXTRA_REGS_RBP -RBP + ALLOC_PT_GPREGS_ON_STACK + SAVE_C_REGS + SAVE_EXTRA_REGS - leaq -RBP(%rsp), %rdi /* arg1 for \func (pointer to pt_regs) */ + movq %rsp,%rdi /* arg1 for \func (pointer to pt_regs) */ - testb $3, CS-RBP(%rsp) + testb $3, CS(%rsp) jz 1f SWAPGS 1: @@ -552,9 +544,7 @@ ret_from_intr: decl PER_CPU_VAR(irq_count) /* Restore saved previous stack */ - popq %rsi - /* return code expects complete pt_regs - adjust rsp accordingly: */ - leaq -RBP(%rsi), %rsp + popq %rsp testb $3, CS(%rsp) jz retint_kernel @@ -579,7 +569,7 @@ retint_swapgs: /* return to user-space */ TRACE_IRQS_IRETQ SWAPGS - jmp restore_c_regs_and_iret + jmp restore_regs_and_iret /* Returning to kernel space */ retint_kernel: @@ -603,6 +593,8 @@ retint_kernel: * At this label, code paths which return to kernel and to user, * which come from interrupts/exception and from syscalls, merge. */ +restore_regs_and_iret: + RESTORE_EXTRA_REGS restore_c_regs_and_iret: RESTORE_C_REGS REMOVE_PT_GPREGS_FROM_STACK 8 @@ -673,12 +665,10 @@ retint_signal: jz retint_swapgs TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) - SAVE_EXTRA_REGS movq $-1, ORIG_RAX(%rsp) xorl %esi, %esi /* oldset */ movq %rsp, %rdi /* &pt_regs */ call do_notify_resume - RESTORE_EXTRA_REGS DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) @@ -1158,7 +1148,6 @@ END(error_entry) */ ENTRY(error_exit) movl %ebx, %eax - RESTORE_EXTRA_REGS DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF testl %eax, %eax -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-06-16 22:30 +0200 |
| Subject | [RFC/INCOMPLETE 09/13] x86/entry/compat: Migrate compat syscalls to new exit hooks |
| Message-ID | <pC5EB-4Oe-9@gated-at.bofh.it> |
| In reply to | #1166373 |
This is separate for ease of bisection. Signed-off-by: Andy Lutomirski <luto@kernel.org> --- arch/x86/entry/entry_64_compat.S | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index bb187a6a877c..415afa038edf 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -209,10 +209,10 @@ sysexit_from_sys_call: .endm .macro auditsys_exit exit - testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) - jnz ia32_ret_from_sys_call TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) + testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) + jnz ia32_ret_from_sys_call movl %eax, %esi /* second arg, syscall return value */ cmpl $-MAX_ERRNO, %eax /* is it an error ? */ jbe 1f @@ -227,11 +227,10 @@ sysexit_from_sys_call: testl %edi, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) jz \exit xorl %eax, %eax /* Do not leak kernel information */ - movq %rax, R11(%rsp) + jmp int_ret_from_sys_call_irqs_off movq %rax, R10(%rsp) movq %rax, R9(%rsp) movq %rax, R8(%rsp) - jmp int_with_check .endm sysenter_auditsys: -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-06-16 22:30 +0200 |
| Subject | [RFC/INCOMPLETE 11/13] x86/asm/entry/64: Simplify irq stack pt_regs handling |
| Message-ID | <pC5EC-4Oe-21@gated-at.bofh.it> |
| In reply to | #1166373 |
There's no need for both rsi and rdi to point to the original stack. Signed-off-by: Andy Lutomirski <luto@kernel.org> --- arch/x86/entry/entry_64.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 43bf5762443c..ab8cbf602d19 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -505,8 +505,6 @@ END(irq_entries_start) SAVE_C_REGS SAVE_EXTRA_REGS - movq %rsp,%rdi /* arg1 for \func (pointer to pt_regs) */ - testb $3, CS(%rsp) jz 1f SWAPGS @@ -518,14 +516,14 @@ END(irq_entries_start) * a little cheaper to use a separate counter in the PDA (short of * moving irq_enter into assembly, which would be too much work) */ - movq %rsp, %rsi + movq %rsp, %rdi incl PER_CPU_VAR(irq_count) cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp - pushq %rsi + pushq %rdi /* We entered an interrupt context - irqs are off: */ TRACE_IRQS_OFF - call \func + call \func /* rdi points to pt_regs */ .endm /* -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web