Re: [patch 00/15] x86/entry: Consolidation - Part V

From: Peter Zijlstra
Date: Wed Feb 26 2020 - 04:53:38 EST


On Tue, Feb 25, 2020 at 11:47:19PM +0100, Thomas Gleixner wrote:

> git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git entry-v1-part5

How about the completely untested something below on top to avoid that
silly indirect call on 32bit idtentry.

---
arch/x86/entry/entry_32.S | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index cf94e724743d..c92cd8412ab2 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -723,19 +723,19 @@
.endm

#ifdef CONFIG_X86_INVD_BUG
-.macro idtentry_push_func vector cfunc
+.macro idtentry_call_func vector cfunc
.if \vector == X86_TRAP_XF
/* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
- ALTERNATIVE "pushl $exc_general_protection", \
- "pushl $exc_simd_coprocessor_error", \
+ ALTERNATIVE "call exc_general_protection", \
+ "call exc_simd_coprocessor_error", \
X86_FEATURE_XMM
.else
- pushl $\cfunc
+ call \cfunc
.endif
.endm
#else
-.macro idtentry_push_func vector cfunc
- pushl $\cfunc
+.macro idtentry_call_func vector cfunc
+ call \cfunc
.endm
#endif

@@ -755,10 +755,9 @@ SYM_CODE_START(\asmsym)
pushl $0 /* Clear the error code */
.endif

- /* Push the C-function address into the GS slot */
- idtentry_push_func \vector \cfunc
- /* Invoke the common exception entry */
- jmp common_exception
+ call common_idtentry
+ idtentry_call_func \vector \cfunc
+ jmp ret_from_exception
SYM_CODE_END(\asmsym)
.endm

@@ -1125,7 +1124,6 @@ SYM_FUNC_START(entry_INT80_32)
.section .fixup, "ax"
SYM_CODE_START(asm_exc_iret_error)
pushl $0 # no error code
- pushl $exc_iret_error

#ifdef CONFIG_DEBUG_ENTRY
/*
@@ -1139,7 +1137,9 @@ SYM_CODE_START(asm_exc_iret_error)
popl %eax
#endif

- jmp common_exception
+ call common_idtentry
+ call exc_iret_error
+ jmp ret_from_exception
SYM_CODE_END(asm_exc_iret_error)
.previous
_ASM_EXTABLE(.Lirq_return, asm_exc_iret_error)
@@ -1332,15 +1332,15 @@ SYM_FUNC_START(xen_failsafe_callback)
SYM_FUNC_END(xen_failsafe_callback)
#endif /* CONFIG_XEN_PV */

-SYM_CODE_START_LOCAL_NOALIGN(common_exception)
- /* the function address is in %gs's slot on the stack */
+SYM_CODE_START_LOCAL_NOALIGN(common_idtentry)
+ /* the return address is in the %gs stack slot */
SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1
ENCODE_FRAME_POINTER

/* fixup %gs */
GS_TO_REG %ecx
- movl PT_GS(%esp), %edi # get the function address
- REG_TO_PTGS %ecx
+ pushl PT_GS(%esp) # push return address
+ REG_TO_OTGS %ecx
SET_KERNEL_GS %ecx

/* fixup orig %eax */
@@ -1348,9 +1348,8 @@ SYM_CODE_START_LOCAL_NOALIGN(common_exception)
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart

movl %esp, %eax # pt_regs pointer
- CALL_NOSPEC %edi
- jmp ret_from_exception
-SYM_CODE_END(common_exception)
+ ret
+SYM_CODE_END(common_idtentry)

#ifdef CONFIG_DOUBLEFAULT
SYM_CODE_START(asm_exc_double_fault)