All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/7] x86/entry: Clean up entry code
@ 2022-03-15  7:39 Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
                   ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

This patchset moves the stack-switch code to the place where
error_entry() return, unravels error_entry() from XENpv and makes
entry_INT80_compat use idtentry macro.

This patchset is highly related to XENpv, because it does the extra
cleanup to convert SWAPGS to swapgs after major cleanup is done.

The patches are the third try to pick patches from the patchset
https://lore.kernel.org/lkml/20211126101209.8613-1-jiangshanlai@gmail.com/
which converts ASM code to C code.  These patches are prepared for that
purpose.  But this patchset has it own value: it simplifies the stack
switch, avoids leaving the old stack inside a function call, and
separates XENpv code with native code without adding new code.

Changed from V2:
	Make the patch of folding int80 thing as the first patch
	Add more changelog in "Switch the stack after error_entry() returns"

Changed from V1
	Squash cleanup patches converting SWAPGS to swapgs into one patch

	Use my official email address (Ant Group).  The work is backed
	by my company and I was incorrectly misunderstood that
	XXX@linux.alibaba.com is the only portal for opensource work
	in the corporate group.

[V2]: https://lore.kernel.org/lkml/20220303035434.20471-1-jiangshanlai@gmail.com/
[V1]: https://lore.kernel.org/lkml/20211208110833.65366-1-jiangshanlai@gmail.com/

Lai Jiangshan (7):
  x86/entry: Use idtentry macro for entry_INT80_compat
  x86/traps: Move pt_regs only in fixup_bad_iret()
  x86/entry: Switch the stack after error_entry() returns
  x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
  x86/entry: Move cld to the start of idtentry
  x86/entry: Don't call error_entry for XENPV
  x86/entry: Convert SWAPGS to swapgs and remove the definition of
    SWAPGS

 arch/x86/entry/entry_64.S        |  61 +++++++++++++-----
 arch/x86/entry/entry_64_compat.S | 105 +------------------------------
 arch/x86/include/asm/idtentry.h  |  47 ++++++++++++++
 arch/x86/include/asm/irqflags.h  |   8 ---
 arch/x86/include/asm/proto.h     |   4 --
 arch/x86/include/asm/traps.h     |   2 +-
 arch/x86/kernel/traps.c          |  17 ++---
 7 files changed, 100 insertions(+), 144 deletions(-)

-- 
2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-16 13:48   ` Peter Zijlstra
  2022-03-15  7:39 ` [PATCH V3 2/7] x86/traps: Move pt_regs only in fixup_bad_iret() Lai Jiangshan
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin, Josh Poimboeuf, Joerg Roedel, Chang S. Bae,
	Jan Kiszka

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

entry_INT80_compat is identical to idtentry macro except a special
handling for %rax in the prolog.

Add the prolog to idtentry and use idtentry for entry_INT80_compat.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S        |  18 ++++++
 arch/x86/entry/entry_64_compat.S | 103 -------------------------------
 arch/x86/include/asm/idtentry.h  |  47 ++++++++++++++
 arch/x86/include/asm/proto.h     |   4 --
 4 files changed, 65 insertions(+), 107 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index cb5b7348b9b8..47ed97cbf46c 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -360,6 +360,24 @@ SYM_CODE_START(\asmsym)
 		pushq	$-1			/* ORIG_RAX: no syscall to restart */
 	.endif
 
+	.if \vector == IA32_SYSCALL_VECTOR
+		/*
+		 * User tracing code (ptrace or signal handlers) might assume
+		 * that the saved RAX contains a 32-bit number when we're
+		 * invoking a 32-bit syscall.  Just in case the high bits are
+		 * nonzero, zero-extend the syscall number.  (This could almost
+		 * certainly be deleted with no ill effects.)
+		 */
+		movl	%eax, %eax
+
+		/*
+		 * do_int80_syscall_32() expects regs->orig_ax to be user ax,
+		 * and regs->ax to be $-ENOSYS.
+		 */
+		movq	%rax, (%rsp)
+		movq	$-ENOSYS, %rax
+	.endif
+
 	.if \vector == X86_TRAP_BP
 		/*
 		 * If coming from kernel space, create a 6-word gap to allow the
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 4fdb007cddbd..2b7496a36f65 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -315,106 +315,3 @@ sysret32_from_system_call:
 	swapgs
 	sysretl
 SYM_CODE_END(entry_SYSCALL_compat)
-
-/*
- * 32-bit legacy system call entry.
- *
- * 32-bit x86 Linux system calls traditionally used the INT $0x80
- * instruction.  INT $0x80 lands here.
- *
- * This entry point can be used by 32-bit and 64-bit programs to perform
- * 32-bit system calls.  Instances of INT $0x80 can be found inline in
- * various programs and libraries.  It is also used by the vDSO's
- * __kernel_vsyscall fallback for hardware that doesn't support a faster
- * entry method.  Restarted 32-bit system calls also fall back to INT
- * $0x80 regardless of what instruction was originally used to do the
- * system call.
- *
- * This is considered a slow path.  It is not used by most libc
- * implementations on modern hardware except during process startup.
- *
- * Arguments:
- * eax  system call number
- * ebx  arg1
- * ecx  arg2
- * edx  arg3
- * esi  arg4
- * edi  arg5
- * ebp  arg6
- */
-SYM_CODE_START(entry_INT80_compat)
-	UNWIND_HINT_EMPTY
-	ENDBR
-	/*
-	 * Interrupts are off on entry.
-	 */
-	ASM_CLAC			/* Do this early to minimize exposure */
-	SWAPGS
-
-	/*
-	 * User tracing code (ptrace or signal handlers) might assume that
-	 * the saved RAX contains a 32-bit number when we're invoking a 32-bit
-	 * syscall.  Just in case the high bits are nonzero, zero-extend
-	 * the syscall number.  (This could almost certainly be deleted
-	 * with no ill effects.)
-	 */
-	movl	%eax, %eax
-
-	/* switch to thread stack expects orig_ax and rdi to be pushed */
-	pushq	%rax			/* pt_regs->orig_ax */
-	pushq	%rdi			/* pt_regs->di */
-
-	/* Need to switch before accessing the thread stack. */
-	SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
-
-	/* In the Xen PV case we already run on the thread stack. */
-	ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
-
-	movq	%rsp, %rdi
-	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
-
-	pushq	6*8(%rdi)		/* regs->ss */
-	pushq	5*8(%rdi)		/* regs->rsp */
-	pushq	4*8(%rdi)		/* regs->eflags */
-	pushq	3*8(%rdi)		/* regs->cs */
-	pushq	2*8(%rdi)		/* regs->ip */
-	pushq	1*8(%rdi)		/* regs->orig_ax */
-	pushq	(%rdi)			/* pt_regs->di */
-.Lint80_keep_stack:
-
-	pushq	%rsi			/* pt_regs->si */
-	xorl	%esi, %esi		/* nospec   si */
-	pushq	%rdx			/* pt_regs->dx */
-	xorl	%edx, %edx		/* nospec   dx */
-	pushq	%rcx			/* pt_regs->cx */
-	xorl	%ecx, %ecx		/* nospec   cx */
-	pushq	$-ENOSYS		/* pt_regs->ax */
-	pushq   %r8			/* pt_regs->r8 */
-	xorl	%r8d, %r8d		/* nospec   r8 */
-	pushq   %r9			/* pt_regs->r9 */
-	xorl	%r9d, %r9d		/* nospec   r9 */
-	pushq   %r10			/* pt_regs->r10*/
-	xorl	%r10d, %r10d		/* nospec   r10 */
-	pushq   %r11			/* pt_regs->r11 */
-	xorl	%r11d, %r11d		/* nospec   r11 */
-	pushq   %rbx                    /* pt_regs->rbx */
-	xorl	%ebx, %ebx		/* nospec   rbx */
-	pushq   %rbp                    /* pt_regs->rbp */
-	xorl	%ebp, %ebp		/* nospec   rbp */
-	pushq   %r12                    /* pt_regs->r12 */
-	xorl	%r12d, %r12d		/* nospec   r12 */
-	pushq   %r13                    /* pt_regs->r13 */
-	xorl	%r13d, %r13d		/* nospec   r13 */
-	pushq   %r14                    /* pt_regs->r14 */
-	xorl	%r14d, %r14d		/* nospec   r14 */
-	pushq   %r15                    /* pt_regs->r15 */
-	xorl	%r15d, %r15d		/* nospec   r15 */
-
-	UNWIND_HINT_REGS
-
-	cld
-
-	movq	%rsp, %rdi
-	call	do_int80_syscall_32
-	jmp	swapgs_restore_regs_and_return_to_usermode
-SYM_CODE_END(entry_INT80_compat)
diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index 7924f27f5c8b..fac5db38c895 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -206,6 +206,20 @@ __visible noinstr void func(struct pt_regs *regs,			\
 									\
 static noinline void __##func(struct pt_regs *regs, u32 vector)
 
+/**
+ * DECLARE_IDTENTRY_IA32_EMULATION - Declare functions for int80
+ * @vector:	Vector number (ignored for C)
+ * @asm_func:	Function name of the entry point
+ * @cfunc:	The C handler called from the ASM entry point (ignored for C)
+ *
+ * Declares two functions:
+ * - The ASM entry point: asm_func
+ * - The XEN PV trap entry point: xen_##asm_func (maybe unused)
+ */
+#define DECLARE_IDTENTRY_IA32_EMULATION(vector, asm_func, cfunc)	\
+	asmlinkage void asm_func(void);					\
+	asmlinkage void xen_##asm_func(void)
+
 /**
  * DECLARE_IDTENTRY_SYSVEC - Declare functions for system vector entry points
  * @vector:	Vector number (ignored for C)
@@ -432,6 +446,35 @@ __visible noinstr void func(struct pt_regs *regs,			\
 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
 	idtentry vector asm_##func func has_error_code=1
 
+/*
+ * 32-bit legacy system call entry.
+ *
+ * 32-bit x86 Linux system calls traditionally used the INT $0x80
+ * instruction.  INT $0x80 lands here.
+ *
+ * This entry point can be used by 32-bit and 64-bit programs to perform
+ * 32-bit system calls.  Instances of INT $0x80 can be found inline in
+ * various programs and libraries.  It is also used by the vDSO's
+ * __kernel_vsyscall fallback for hardware that doesn't support a faster
+ * entry method.  Restarted 32-bit system calls also fall back to INT
+ * $0x80 regardless of what instruction was originally used to do the
+ * system call.
+ *
+ * This is considered a slow path.  It is not used by most libc
+ * implementations on modern hardware except during process startup.
+ *
+ * Arguments:
+ * eax  system call number
+ * ebx  arg1
+ * ecx  arg2
+ * edx  arg3
+ * esi  arg4
+ * edi  arg5
+ * ebp  arg6
+ */
+#define DECLARE_IDTENTRY_IA32_EMULATION(vector, asm_func, cfunc)	\
+	idtentry vector asm_func cfunc has_error_code=0
+
 /* Special case for 32bit IRET 'trap'. Do not emit ASM code */
 #define DECLARE_IDTENTRY_SW(vector, func)
 
@@ -638,6 +681,10 @@ DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	common_interrupt);
 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	spurious_interrupt);
 #endif
 
+#ifdef CONFIG_IA32_EMULATION
+DECLARE_IDTENTRY_IA32_EMULATION(IA32_SYSCALL_VECTOR,	entry_INT80_compat, do_int80_syscall_32);
+#endif
+
 /* System vector entry points */
 #ifdef CONFIG_X86_LOCAL_APIC
 DECLARE_IDTENTRY_SYSVEC(ERROR_APIC_VECTOR,		sysvec_error_interrupt);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index feed36d44d04..c4d331fe65ff 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -28,10 +28,6 @@ void entry_SYSENTER_compat(void);
 void __end_entry_SYSENTER_compat(void);
 void entry_SYSCALL_compat(void);
 void entry_SYSCALL_compat_safe_stack(void);
-void entry_INT80_compat(void);
-#ifdef CONFIG_XEN_PV
-void xen_entry_INT80_compat(void);
-#endif
 #endif
 
 void x86_configure_nx(void);
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 2/7] x86/traps: Move pt_regs only in fixup_bad_iret()
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin, Josh Poimboeuf, Fenghua Yu, Thomas Tai,
	Chang S. Bae, Masami Hiramatsu

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

fixup_bad_iret() and sync_regs() have similar arguments and do similar
work that copies full or partial pt_regs to a place and switches stack
after return.  They are quite the same, but fixup_bad_iret() not only
copies the pt_regs but also the return address of error_entry() while
sync_regs() copies the pt_regs only and the return address of
error_entry() was preserved and handled in ASM code.

This patch makes fixup_bad_iret() work like sync_regs() and the
handling of the return address of error_entry() is moved in ASM code.

It removes the need to use the struct bad_iret_stack, simplifies
fixup_bad_iret() and makes the ASM error_entry() call fixup_bad_iret()
as the same as calling sync_regs() which adds readability because
the calling patterns are exactly the same.

It is prepared for later patch to do the stack switch after the
error_entry() which simplifies the code further.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S    |  5 ++++-
 arch/x86/include/asm/traps.h |  2 +-
 arch/x86/kernel/traps.c      | 17 ++++++-----------
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 47ed97cbf46c..37505331b7f1 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1073,9 +1073,12 @@ SYM_CODE_START_LOCAL(error_entry)
 	 * Pretend that the exception came from user mode: set up pt_regs
 	 * as if we faulted immediately after IRET.
 	 */
-	mov	%rsp, %rdi
+	popq	%r12				/* save return addr in %12 */
+	movq	%rsp, %rdi			/* arg0 = pt_regs pointer */
 	call	fixup_bad_iret
 	mov	%rax, %rsp
+	ENCODE_FRAME_POINTER
+	pushq	%r12
 	jmp	.Lerror_entry_from_usermode_after_swapgs
 SYM_CODE_END(error_entry)
 
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 35317c5c551d..47ecfff2c83d 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -13,7 +13,7 @@
 #ifdef CONFIG_X86_64
 asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs);
 asmlinkage __visible notrace
-struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s);
+struct pt_regs *fixup_bad_iret(struct pt_regs *bad_regs);
 void __init trap_init(void);
 asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *eregs);
 #endif
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 1563fb995005..9fe9cd9d3eeb 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -892,13 +892,8 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r
 }
 #endif
 
-struct bad_iret_stack {
-	void *error_entry_ret;
-	struct pt_regs regs;
-};
-
 asmlinkage __visible noinstr
-struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
+struct pt_regs *fixup_bad_iret(struct pt_regs *bad_regs)
 {
 	/*
 	 * This is called from entry_64.S early in handling a fault
@@ -908,19 +903,19 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
 	 * just below the IRET frame) and we want to pretend that the
 	 * exception came from the IRET target.
 	 */
-	struct bad_iret_stack tmp, *new_stack =
-		(struct bad_iret_stack *)__this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1;
+	struct pt_regs tmp, *new_stack =
+		(struct pt_regs *)__this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1;
 
 	/* Copy the IRET target to the temporary storage. */
-	__memcpy(&tmp.regs.ip, (void *)s->regs.sp, 5*8);
+	__memcpy(&tmp.ip, (void *)bad_regs->sp, 5*8);
 
 	/* Copy the remainder of the stack from the current stack. */
-	__memcpy(&tmp, s, offsetof(struct bad_iret_stack, regs.ip));
+	__memcpy(&tmp, bad_regs, offsetof(struct pt_regs, ip));
 
 	/* Update the entry stack */
 	__memcpy(new_stack, &tmp, sizeof(tmp));
 
-	BUG_ON(!user_mode(&new_stack->regs));
+	BUG_ON(!user_mode(new_stack));
 	return new_stack;
 }
 #endif
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 2/7] x86/traps: Move pt_regs only in fixup_bad_iret() Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-16  2:37   ` Josh Poimboeuf
  2022-03-16 15:05   ` Peter Zijlstra
  2022-03-15  7:39 ` [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry Lai Jiangshan
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

error_entry() calls sync_regs() to settle/copy the pt_regs and switches
the stack directly after sync_regs().  But error_entry() itself is also
a function call, the switching has to handle the return address of it
together, which causes the work complicated and tangly.

Switching to the stack after error_entry() makes the code simpler and
intuitive.

The behavior/logic is unchanged:
  1) (opt) feed fixup_bad_iret() with the pt_regs pushed by ASM code
  2) (opt) fixup_bad_iret() moves the partial pt_regs up
  3) feed sync_regs() with the pt_regs pushed by ASM code or returned
     by fixup_bad_iret()
  4) sync_regs() copies the whole pt_regs to kernel stack if needed
  5) after error_entry() and switching %rsp, it is in kernel stack with
     the pt_regs

Changes only in calling:
  Old code switches to copied pt_regs immediately twice in
  error_entry() while new code switches to the copied pt_regs only
  once after error_entry() returns.
  It is correct since sync_regs() doesn't need to be called close
  to the pt_regs it handles.

  Old code stashes the return-address of error_entry() in a scratch
  register and new code doesn't stash it.
  It relies on the fact that fixup_bad_iret() and sync_regs() don't
  corrupt the return-address of error_entry() on the stack.  But even
  the old code also relies on the fact that fixup_bad_iret() and
  sync_regs() don't corrupt the return-address of themselves.
  They are the same reliances and are assured.

After this change, error_entry() will not do fancy things with the stack
except when in the prolog which will be fixed in the next patch ("move
PUSH_AND_CLEAR_REGS out of error_entry").  This patch and the next patch
can't be swapped because the next patch relies on this patch's stopping
fiddling with the return-address of error_entry(), otherwise the objtool
would complain.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 37505331b7f1..7768cdd0c7ed 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -326,6 +326,8 @@ SYM_CODE_END(ret_from_fork)
 .macro idtentry_body cfunc has_error_code:req
 
 	call	error_entry
+	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
+	ENCODE_FRAME_POINTER
 	UNWIND_HINT_REGS
 
 	movq	%rsp, %rdi			/* pt_regs pointer into 1st argument*/
@@ -1014,14 +1016,10 @@ SYM_CODE_START_LOCAL(error_entry)
 	/* We have user CR3.  Change to kernel CR3. */
 	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
 
+	leaq	8(%rsp), %rdi			/* arg0 = pt_regs pointer */
 .Lerror_entry_from_usermode_after_swapgs:
 	/* Put us onto the real thread stack. */
-	popq	%r12				/* save return addr in %12 */
-	movq	%rsp, %rdi			/* arg0 = pt_regs pointer */
 	call	sync_regs
-	movq	%rax, %rsp			/* switch stack */
-	ENCODE_FRAME_POINTER
-	pushq	%r12
 	RET
 
 	/*
@@ -1053,6 +1051,7 @@ SYM_CODE_START_LOCAL(error_entry)
 	 */
 .Lerror_entry_done_lfence:
 	FENCE_SWAPGS_KERNEL_ENTRY
+	leaq	8(%rsp), %rax			/* return pt_regs pointer */
 	RET
 
 .Lbstep_iret:
@@ -1073,12 +1072,9 @@ SYM_CODE_START_LOCAL(error_entry)
 	 * Pretend that the exception came from user mode: set up pt_regs
 	 * as if we faulted immediately after IRET.
 	 */
-	popq	%r12				/* save return addr in %12 */
-	movq	%rsp, %rdi			/* arg0 = pt_regs pointer */
+	leaq	8(%rsp), %rdi			/* arg0 = pt_regs pointer */
 	call	fixup_bad_iret
-	mov	%rax, %rsp
-	ENCODE_FRAME_POINTER
-	pushq	%r12
+	mov	%rax, %rdi
 	jmp	.Lerror_entry_from_usermode_after_swapgs
 SYM_CODE_END(error_entry)
 
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
                   ` (2 preceding siblings ...)
  2022-03-15  7:39 ` [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-16 15:07   ` Peter Zijlstra
  2022-03-15  7:39 ` [PATCH V3 5/7] x86/entry: Move cld to the start of idtentry Lai Jiangshan
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

Moving PUSH_AND_CLEAR_REGS out of error_entry doesn't change any
functionality.

It makes error_entry() do not fiddle with the stack.

It will enlarge the size:

size arch/x86/entry/entry_64.o.before:
   text	   data	    bss	    dec	    hex	filename
  17916	    384	      0	  18300	   477c	arch/x86/entry/entry_64.o

size --format=SysV arch/x86/entry/entry_64.o.before:
.entry.text                      5528      0
.orc_unwind                      6456      0
.orc_unwind_ip                   4304      0

size arch/x86/entry/entry_64.o.after:
   text	   data	    bss	    dec	    hex	filename
  26868	    384	      0	  27252	   6a74	arch/x86/entry/entry_64.o

size --format=SysV arch/x86/entry/entry_64.o.after:
.entry.text                      8200      0
.orc_unwind                     10224      0
.orc_unwind_ip                   6816      0

But .entry.text in x86_64 is 2M aligned, enlarging it to 8.2k doesn't
enlarge the final text size.

The tables .orc_unwind[_ip] are enlarged due to it adds many pushes.

It is prepared for not calling error_entry() from XENPV in later patch
and for future converting the whole error_entry into C code.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7768cdd0c7ed..903da9119e7a 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -325,6 +325,9 @@ SYM_CODE_END(ret_from_fork)
  */
 .macro idtentry_body cfunc has_error_code:req
 
+	PUSH_AND_CLEAR_REGS
+	ENCODE_FRAME_POINTER
+
 	call	error_entry
 	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
 	ENCODE_FRAME_POINTER
@@ -1002,8 +1005,6 @@ SYM_CODE_END(paranoid_exit)
 SYM_CODE_START_LOCAL(error_entry)
 	UNWIND_HINT_FUNC
 	cld
-	PUSH_AND_CLEAR_REGS save_ret=1
-	ENCODE_FRAME_POINTER 8
 	testb	$3, CS+8(%rsp)
 	jz	.Lerror_kernelspace
 
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 5/7] x86/entry: Move cld to the start of idtentry
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
                   ` (3 preceding siblings ...)
  2022-03-15  7:39 ` [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-15  7:39 ` [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

Make it next to CLAC

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 903da9119e7a..e4a07276fd1c 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -360,6 +360,7 @@ SYM_CODE_START(\asmsym)
 	UNWIND_HINT_IRET_REGS offset=\has_error_code*8
 	ENDBR
 	ASM_CLAC
+	cld
 
 	.if \has_error_code == 0
 		pushq	$-1			/* ORIG_RAX: no syscall to restart */
@@ -446,6 +447,7 @@ SYM_CODE_START(\asmsym)
 	UNWIND_HINT_IRET_REGS
 	ENDBR
 	ASM_CLAC
+	cld
 
 	pushq	$-1			/* ORIG_RAX: no syscall to restart */
 
@@ -502,6 +504,7 @@ SYM_CODE_START(\asmsym)
 	UNWIND_HINT_IRET_REGS
 	ENDBR
 	ASM_CLAC
+	cld
 
 	/*
 	 * If the entry is from userspace, switch stacks and treat it as
@@ -564,6 +567,7 @@ SYM_CODE_START(\asmsym)
 	UNWIND_HINT_IRET_REGS offset=8
 	ENDBR
 	ASM_CLAC
+	cld
 
 	/* paranoid_entry returns GS information for paranoid_exit in EBX. */
 	call	paranoid_entry
@@ -886,7 +890,6 @@ SYM_CODE_END(xen_failsafe_callback)
  */
 SYM_CODE_START_LOCAL(paranoid_entry)
 	UNWIND_HINT_FUNC
-	cld
 	PUSH_AND_CLEAR_REGS save_ret=1
 	ENCODE_FRAME_POINTER 8
 
@@ -1004,7 +1007,6 @@ SYM_CODE_END(paranoid_exit)
  */
 SYM_CODE_START_LOCAL(error_entry)
 	UNWIND_HINT_FUNC
-	cld
 	testb	$3, CS+8(%rsp)
 	jz	.Lerror_kernelspace
 
@@ -1138,6 +1140,7 @@ SYM_CODE_START(asm_exc_nmi)
 	 */
 
 	ASM_CLAC
+	cld
 
 	/* Use %rdx as our temp variable throughout */
 	pushq	%rdx
@@ -1157,7 +1160,6 @@ SYM_CODE_START(asm_exc_nmi)
 	 */
 
 	swapgs
-	cld
 	FENCE_SWAPGS_USER_ENTRY
 	SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
 	movq	%rsp, %rdx
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
                   ` (4 preceding siblings ...)
  2022-03-15  7:39 ` [PATCH V3 5/7] x86/entry: Move cld to the start of idtentry Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-16  2:59   ` Josh Poimboeuf
  2022-03-16 15:09   ` Peter Zijlstra
  2022-03-15  7:39 ` [PATCH V3 7/7] x86/entry: Convert SWAPGS to swapgs and remove the definition of SWAPGS Lai Jiangshan
  2022-03-16 15:12 ` [PATCH V3 0/7] x86/entry: Clean up entry code Peter Zijlstra
  7 siblings, 2 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

When in XENPV, it is already in the task stack, and it can't fault
for native_iret() nor native_load_gs_index() since XENPV uses its own
pvops for iret and load_gs_index().  And it doesn't need to switch CR3.
So there is no reason to call error_entry() in XENPV.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index e4a07276fd1c..ec885c2107de 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -328,8 +328,17 @@ SYM_CODE_END(ret_from_fork)
 	PUSH_AND_CLEAR_REGS
 	ENCODE_FRAME_POINTER
 
-	call	error_entry
-	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
+	/*
+	 * Call error_entry and switch stack settled by sync_regs().
+	 *
+	 * When in XENPV, it is already in the task stack, and it can't fault
+	 * for native_iret() nor native_load_gs_index() since XENPV uses its
+	 * own pvops for iret and load_gs_index().  And it doesn't need to
+	 * switch CR3.  So it can skip invoking error_entry().
+	 */
+	ALTERNATIVE "call error_entry; movq %rax, %rsp", \
+		"", X86_FEATURE_XENPV
+
 	ENCODE_FRAME_POINTER
 	UNWIND_HINT_REGS
 
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V3 7/7] x86/entry: Convert SWAPGS to swapgs and remove the definition of SWAPGS
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
                   ` (5 preceding siblings ...)
  2022-03-15  7:39 ` [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
@ 2022-03-15  7:39 ` Lai Jiangshan
  2022-03-16 15:12 ` [PATCH V3 0/7] x86/entry: Clean up entry code Peter Zijlstra
  7 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-15  7:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin, Kirill A. Shutemov, Josh Poimboeuf

From: Lai Jiangshan <jiangshan.ljs@antgroup.com>

XENPV doesn't use swapgs_restore_regs_and_return_to_usermode(),
error_entry() and entry_SYSENTER_compat(), so the PV-awared SWAPGS in
them can be changed to swapgs.  There is no user of the SWAPGS anymore
after this change.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
 arch/x86/entry/entry_64.S        | 6 +++---
 arch/x86/entry/entry_64_compat.S | 2 +-
 arch/x86/include/asm/irqflags.h  | 8 --------
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index ec885c2107de..e20eabaa56b8 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1023,7 +1023,7 @@ SYM_CODE_START_LOCAL(error_entry)
 	 * We entered from user mode or we're pretending to have entered
 	 * from user mode due to an IRET fault.
 	 */
-	SWAPGS
+	swapgs
 	FENCE_SWAPGS_USER_ENTRY
 	/* We have user CR3.  Change to kernel CR3. */
 	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
@@ -1055,7 +1055,7 @@ SYM_CODE_START_LOCAL(error_entry)
 	 * gsbase and proceed.  We'll fix up the exception and land in
 	 * .Lgs_change's error handler with kernel gsbase.
 	 */
-	SWAPGS
+	swapgs
 
 	/*
 	 * Issue an LFENCE to prevent GS speculation, regardless of whether it is a
@@ -1076,7 +1076,7 @@ SYM_CODE_START_LOCAL(error_entry)
 	 * We came from an IRET to user mode, so we have user
 	 * gsbase and CR3.  Switch to kernel gsbase and CR3:
 	 */
-	SWAPGS
+	swapgs
 	FENCE_SWAPGS_USER_ENTRY
 	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
 
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 2b7496a36f65..6866151bbef3 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -50,7 +50,7 @@ SYM_CODE_START(entry_SYSENTER_compat)
 	UNWIND_HINT_EMPTY
 	ENDBR
 	/* Interrupts are off on entry. */
-	SWAPGS
+	swapgs
 
 	pushq	%rax
 	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index 111104d1c2cd..7793e52d6237 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -137,14 +137,6 @@ static __always_inline void arch_local_irq_restore(unsigned long flags)
 	if (!arch_irqs_disabled_flags(flags))
 		arch_local_irq_enable();
 }
-#else
-#ifdef CONFIG_X86_64
-#ifdef CONFIG_XEN_PV
-#define SWAPGS	ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV
-#else
-#define SWAPGS	swapgs
-#endif
-#endif
 #endif /* !__ASSEMBLY__ */
 
 #endif
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-15  7:39 ` [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
@ 2022-03-16  2:37   ` Josh Poimboeuf
  2022-03-16  3:02     ` Lai Jiangshan
  2022-03-16 15:05   ` Peter Zijlstra
  1 sibling, 1 reply; 22+ messages in thread
From: Josh Poimboeuf @ 2022-03-16  2:37 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Peter Zijlstra,
	Lai Jiangshan, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, H. Peter Anvin

On Tue, Mar 15, 2022 at 03:39:45PM +0800, Lai Jiangshan wrote:
>  .Lerror_entry_from_usermode_after_swapgs:
>  	/* Put us onto the real thread stack. */

This comment is no longer correct.

-- 
Josh


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV
  2022-03-15  7:39 ` [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
@ 2022-03-16  2:59   ` Josh Poimboeuf
  2022-03-16 15:09   ` Peter Zijlstra
  1 sibling, 0 replies; 22+ messages in thread
From: Josh Poimboeuf @ 2022-03-16  2:59 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Peter Zijlstra,
	Lai Jiangshan, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, H. Peter Anvin

On Tue, Mar 15, 2022 at 03:39:48PM +0800, Lai Jiangshan wrote:
> +++ b/arch/x86/entry/entry_64.S
> @@ -328,8 +328,17 @@ SYM_CODE_END(ret_from_fork)
>  	PUSH_AND_CLEAR_REGS
>  	ENCODE_FRAME_POINTER
>  
> -	call	error_entry
> -	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
> +	/*
> +	 * Call error_entry and switch stack settled by sync_regs().
> +	 *
> +	 * When in XENPV, it is already in the task stack, and it can't fault
> +	 * for native_iret() nor native_load_gs_index() since XENPV uses its
> +	 * own pvops for iret and load_gs_index().  And it doesn't need to
> +	 * switch CR3.  So it can skip invoking error_entry().
> +	 */
> +	ALTERNATIVE "call error_entry; movq %rax, %rsp", \
> +		"", X86_FEATURE_XENPV
> +
>  	ENCODE_FRAME_POINTER
>  	UNWIND_HINT_REGS

The second ENCODE_FRAME_POINTER is only needed for the stack-switching
(non-XENPV) case.  The second UNWIND_HINT_REGS shouldn't be needed at
all, since the first one still applies after the call.

How about something more readable like this?

.macro idtentry_body cfunc has_error_code:req

	PUSH_AND_CLEAR_REGS
	ENCODE_FRAME_POINTER

#ifdef CONFIG_XEN_PV
	/*
	 * When in XENPV, it is already in the task stack, and it can't fault
	 * for native_iret() nor native_load_gs_index() since XENPV uses its
	 * own pvops for iret and load_gs_index().  And it doesn't need to
	 * switch CR3.  So it can skip invoking error_entry().
	 */
	ALTERNATIVE "", "jmp 1f", X86_FEATURE_XENPV
#endif

	call error_entry
	movq %rax, %rsp
	ENCODE_FRAME_POINTER
1:
	movq	%rsp, %rdi			/* pt_regs pointer into 1st argument*/

-- 
Josh


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-16  2:37   ` Josh Poimboeuf
@ 2022-03-16  3:02     ` Lai Jiangshan
  0 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-16  3:02 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: LKML, X86 ML, Borislav Petkov, Peter Zijlstra, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

On Wed, Mar 16, 2022 at 10:37 AM Josh Poimboeuf <jpoimboe@redhat.com> wrote:
>
> On Tue, Mar 15, 2022 at 03:39:45PM +0800, Lai Jiangshan wrote:
> >  .Lerror_entry_from_usermode_after_swapgs:
> >       /* Put us onto the real thread stack. */
>
> This comment is no longer correct.

Thanks for the review.

I thought "us" is the pt_regs. But it can be everything including
the "running environment" and "running stack".

I will change "us" to "the pt_regs"

>
> --
> Josh
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat
  2022-03-15  7:39 ` [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
@ 2022-03-16 13:48   ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 13:48 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin, Josh Poimboeuf, Joerg Roedel, Chang S. Bae,
	Jan Kiszka

On Tue, Mar 15, 2022 at 03:39:43PM +0800, Lai Jiangshan wrote:
> From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> 
> entry_INT80_compat is identical to idtentry macro except a special
> handling for %rax in the prolog.
> 
> Add the prolog to idtentry and use idtentry for entry_INT80_compat.

I'm struggling to see the Xen case. Currently it has:

> -	/* In the Xen PV case we already run on the thread stack. */
> -	ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV

But idtentry's error_entry() does not have that afaict.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-15  7:39 ` [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
  2022-03-16  2:37   ` Josh Poimboeuf
@ 2022-03-16 15:05   ` Peter Zijlstra
  2022-03-16 16:43     ` Lai Jiangshan
  1 sibling, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 15:05 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

On Tue, Mar 15, 2022 at 03:39:45PM +0800, Lai Jiangshan wrote:
> From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> 
> error_entry() calls sync_regs() to settle/copy the pt_regs and switches
> the stack directly after sync_regs().  But error_entry() itself is also
> a function call, the switching has to handle the return address of it
> together, which causes the work complicated and tangly.
> 
> Switching to the stack after error_entry() makes the code simpler and
> intuitive.
> 
> The behavior/logic is unchanged:
>   1) (opt) feed fixup_bad_iret() with the pt_regs pushed by ASM code
>   2) (opt) fixup_bad_iret() moves the partial pt_regs up
>   3) feed sync_regs() with the pt_regs pushed by ASM code or returned
>      by fixup_bad_iret()
>   4) sync_regs() copies the whole pt_regs to kernel stack if needed
>   5) after error_entry() and switching %rsp, it is in kernel stack with
>      the pt_regs
> 
> Changes only in calling:
>   Old code switches to copied pt_regs immediately twice in
>   error_entry() while new code switches to the copied pt_regs only
>   once after error_entry() returns.
>   It is correct since sync_regs() doesn't need to be called close
>   to the pt_regs it handles.
> 
>   Old code stashes the return-address of error_entry() in a scratch
>   register and new code doesn't stash it.
>   It relies on the fact that fixup_bad_iret() and sync_regs() don't
>   corrupt the return-address of error_entry() on the stack.  But even
>   the old code also relies on the fact that fixup_bad_iret() and
>   sync_regs() don't corrupt the return-address of themselves.
>   They are the same reliances and are assured.
> 
> After this change, error_entry() will not do fancy things with the stack
> except when in the prolog which will be fixed in the next patch ("move
> PUSH_AND_CLEAR_REGS out of error_entry").  This patch and the next patch
> can't be swapped because the next patch relies on this patch's stopping
> fiddling with the return-address of error_entry(), otherwise the objtool
> would complain.
> 
> Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> ---
>  arch/x86/entry/entry_64.S | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index 37505331b7f1..7768cdd0c7ed 100644
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -326,6 +326,8 @@ SYM_CODE_END(ret_from_fork)
>  .macro idtentry_body cfunc has_error_code:req
>  
>  	call	error_entry
> +	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
> +	ENCODE_FRAME_POINTER
>  	UNWIND_HINT_REGS
>  
>  	movq	%rsp, %rdi			/* pt_regs pointer into 1st argument*/
> @@ -1014,14 +1016,10 @@ SYM_CODE_START_LOCAL(error_entry)
>  	/* We have user CR3.  Change to kernel CR3. */
>  	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
>  
> +	leaq	8(%rsp), %rdi			/* arg0 = pt_regs pointer */
>  .Lerror_entry_from_usermode_after_swapgs:
>  	/* Put us onto the real thread stack. */
> -	popq	%r12				/* save return addr in %12 */
> -	movq	%rsp, %rdi			/* arg0 = pt_regs pointer */
>  	call	sync_regs
> -	movq	%rax, %rsp			/* switch stack */
> -	ENCODE_FRAME_POINTER
> -	pushq	%r12
>  	RET
>  
>  	/*
> @@ -1053,6 +1051,7 @@ SYM_CODE_START_LOCAL(error_entry)
>  	 */
>  .Lerror_entry_done_lfence:
>  	FENCE_SWAPGS_KERNEL_ENTRY
> +	leaq	8(%rsp), %rax			/* return pt_regs pointer */
>  	RET
>  
>  .Lbstep_iret:
> @@ -1073,12 +1072,9 @@ SYM_CODE_START_LOCAL(error_entry)
>  	 * Pretend that the exception came from user mode: set up pt_regs
>  	 * as if we faulted immediately after IRET.
>  	 */
> -	popq	%r12				/* save return addr in %12 */
> -	movq	%rsp, %rdi			/* arg0 = pt_regs pointer */
> +	leaq	8(%rsp), %rdi			/* arg0 = pt_regs pointer */
>  	call	fixup_bad_iret
> -	mov	%rax, %rsp
> -	ENCODE_FRAME_POINTER
> -	pushq	%r12
> +	mov	%rax, %rdi
>  	jmp	.Lerror_entry_from_usermode_after_swapgs
>  SYM_CODE_END(error_entry)

So the new Changelog doesn't seem to help me much. But looking at both
fixup_bad_iret() and sync_regs(), they both have:

  __this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1

as hard-coded destination. Now, fixup_bad_iret() sets up a complete
ptregs there and then returns a pointer to this stack.

sync_regs otoh, does a straight up pt_regs sized copy from arg0 to this
new stack.

Therefore it appears to me that doing sync_regs() after fixup_bad_iret()
is a complete NO-OP and only confuses things further.

Would not something like the below clarify things?

--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1004,6 +1004,7 @@ SYM_CODE_START_LOCAL(error_entry)
 .Lerror_entry_from_usermode_after_swapgs:
 	/* Put us onto the real thread stack. */
 	call	sync_regs
+.Lerror_entry_from_usermode_after_sync_regs:
 	RET
 
 	/*
@@ -1058,8 +1059,12 @@ SYM_CODE_START_LOCAL(error_entry)
 	 */
 	leaq	8(%rsp), %rdi			/* arg0 = pt_regs pointer */
 	call	fixup_bad_iret
-	mov	%rax, %rdi
-	jmp	.Lerror_entry_from_usermode_after_swapgs
+	/*
+	 * fixup_bad_iret() will have setup pt_regs on the thread stack, and
+	 * returns a pointer to that stack exactly like sync_regs() would've
+	 * done. As such, calling sync_regs again makes no sense.
+	 */
+	jmp	.Lerror_entry_from_usermode_after_sync_regs
 SYM_CODE_END(error_entry)
 
 SYM_CODE_START_LOCAL(error_return)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
  2022-03-15  7:39 ` [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry Lai Jiangshan
@ 2022-03-16 15:07   ` Peter Zijlstra
  2022-03-16 16:18     ` Lai Jiangshan
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 15:07 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

On Tue, Mar 15, 2022 at 03:39:46PM +0800, Lai Jiangshan wrote:
> From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> 
> Moving PUSH_AND_CLEAR_REGS out of error_entry doesn't change any
> functionality.
> 
> It makes error_entry() do not fiddle with the stack.
> 
> It will enlarge the size:
> 
> size arch/x86/entry/entry_64.o.before:
>    text	   data	    bss	    dec	    hex	filename
>   17916	    384	      0	  18300	   477c	arch/x86/entry/entry_64.o
> 
> size --format=SysV arch/x86/entry/entry_64.o.before:
> .entry.text                      5528      0
> .orc_unwind                      6456      0
> .orc_unwind_ip                   4304      0
> 
> size arch/x86/entry/entry_64.o.after:
>    text	   data	    bss	    dec	    hex	filename
>   26868	    384	      0	  27252	   6a74	arch/x86/entry/entry_64.o
> 
> size --format=SysV arch/x86/entry/entry_64.o.after:
> .entry.text                      8200      0
> .orc_unwind                     10224      0
> .orc_unwind_ip                   6816      0
> 
> But .entry.text in x86_64 is 2M aligned, enlarging it to 8.2k doesn't
> enlarge the final text size.

So I don't much care about the orc data, that's only used when
unwinding, a relatively rare occasion, anyway. But the text increase
does bother me a little, this can blow up I$ misses on syscall heavy
workloads.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV
  2022-03-15  7:39 ` [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
  2022-03-16  2:59   ` Josh Poimboeuf
@ 2022-03-16 15:09   ` Peter Zijlstra
  2022-03-16 16:48     ` Lai Jiangshan
  1 sibling, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 15:09 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	H. Peter Anvin

On Tue, Mar 15, 2022 at 03:39:48PM +0800, Lai Jiangshan wrote:
> From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> 
> When in XENPV, it is already in the task stack, and it can't fault
> for native_iret() nor native_load_gs_index() since XENPV uses its own
> pvops for iret and load_gs_index().  And it doesn't need to switch CR3.
> So there is no reason to call error_entry() in XENPV.
> 
> Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> ---
>  arch/x86/entry/entry_64.S | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index e4a07276fd1c..ec885c2107de 100644
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -328,8 +328,17 @@ SYM_CODE_END(ret_from_fork)
>  	PUSH_AND_CLEAR_REGS
>  	ENCODE_FRAME_POINTER
>  
> -	call	error_entry
> -	movq	%rax, %rsp			/* switch stack settled by sync_regs() */
> +	/*
> +	 * Call error_entry and switch stack settled by sync_regs().
> +	 *
> +	 * When in XENPV, it is already in the task stack, and it can't fault
> +	 * for native_iret() nor native_load_gs_index() since XENPV uses its
> +	 * own pvops for iret and load_gs_index().  And it doesn't need to
> +	 * switch CR3.  So it can skip invoking error_entry().
> +	 */
> +	ALTERNATIVE "call error_entry; movq %rax, %rsp", \
> +		"", X86_FEATURE_XENPV
> +
>  	ENCODE_FRAME_POINTER
>  	UNWIND_HINT_REGS
>  

Oooh, here we go, this is the answer to my question for patch #1, a note
in the changelog might be nice. Something like:

"This looses a Xen PV optimization, which will be restored in a later
patch. The superfluous stack switch is just that."

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 0/7] x86/entry: Clean up entry code
  2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
                   ` (6 preceding siblings ...)
  2022-03-15  7:39 ` [PATCH V3 7/7] x86/entry: Convert SWAPGS to swapgs and remove the definition of SWAPGS Lai Jiangshan
@ 2022-03-16 15:12 ` Peter Zijlstra
  2022-03-16 15:13   ` Peter Zijlstra
  7 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 15:12 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan

On Tue, Mar 15, 2022 at 03:39:42PM +0800, Lai Jiangshan wrote:

> Lai Jiangshan (7):
>   x86/entry: Use idtentry macro for entry_INT80_compat
>   x86/traps: Move pt_regs only in fixup_bad_iret()
>   x86/entry: Switch the stack after error_entry() returns
>   x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
>   x86/entry: Move cld to the start of idtentry
>   x86/entry: Don't call error_entry for XENPV
>   x86/entry: Convert SWAPGS to swapgs and remove the definition of
>     SWAPGS

So AFAICT these patches are indeed correct.

I do however worry a little bit about the I$ impact of patch 4, and
there's a few niggles, but otherwise looks good.

I'd love for some of the other x86 people to also look at this, but a
tentative ACK on this.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 0/7] x86/entry: Clean up entry code
  2022-03-16 15:12 ` [PATCH V3 0/7] x86/entry: Clean up entry code Peter Zijlstra
@ 2022-03-16 15:13   ` Peter Zijlstra
  2022-03-17 12:58     ` Lai Jiangshan
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-16 15:13 UTC (permalink / raw)
  To: Lai Jiangshan; +Cc: linux-kernel, x86, Borislav Petkov, Lai Jiangshan

On Wed, Mar 16, 2022 at 04:12:21PM +0100, Peter Zijlstra wrote:
> On Tue, Mar 15, 2022 at 03:39:42PM +0800, Lai Jiangshan wrote:
> 
> > Lai Jiangshan (7):
> >   x86/entry: Use idtentry macro for entry_INT80_compat
> >   x86/traps: Move pt_regs only in fixup_bad_iret()
> >   x86/entry: Switch the stack after error_entry() returns
> >   x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
> >   x86/entry: Move cld to the start of idtentry
> >   x86/entry: Don't call error_entry for XENPV
> >   x86/entry: Convert SWAPGS to swapgs and remove the definition of
> >     SWAPGS
> 
> So AFAICT these patches are indeed correct.
> 
> I do however worry a little bit about the I$ impact of patch 4, and
> there's a few niggles, but otherwise looks good.
> 
> I'd love for some of the other x86 people to also look at this, but a
> tentative ACK on this.
> 

Also, I forgot to mention; they no longer apply cleanly because I
sprinked ENDBR all over the place. Mostly trivial to fixup though.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
  2022-03-16 15:07   ` Peter Zijlstra
@ 2022-03-16 16:18     ` Lai Jiangshan
  0 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-16 16:18 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: LKML, X86 ML, Borislav Petkov, Lai Jiangshan, Andy Lutomirski,
	Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin

On Wed, Mar 16, 2022 at 11:07 PM Peter Zijlstra <peterz@infradead.org> wrote:

>
> So I don't much care about the orc data, that's only used when
> unwinding, a relatively rare occasion, anyway. But the text increase
> does bother me a little, this can blow up I$ misses on syscall heavy
> workloads.

It has nothing to do with the syscall.

It does add a lot in I$.  But it is fortunate that the footprint
is the same (before and after the patch) for a single exception vector.
For example heavy #PF workloads.

Footprint will increase after this patch when two or more exception
vectors happen heavily at the same time, for example when #PF and
timer are occurring heavily.

We can put PUSH_AND_CLEAR_REGS in a single function to reduce the
footprint for heavy multi-exception workloads.  What do you think?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-16 15:05   ` Peter Zijlstra
@ 2022-03-16 16:43     ` Lai Jiangshan
  2022-03-18 11:12       ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-16 16:43 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: LKML, X86 ML, Borislav Petkov, Lai Jiangshan, Andy Lutomirski,
	Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin

On Wed, Mar 16, 2022 at 11:05 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> >  SYM_CODE_END(error_entry)
>
> So the new Changelog doesn't seem to help me much. But looking at both
> fixup_bad_iret() and sync_regs(), they both have:
>
>   __this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1


For a long time in old days (before KPTI), tss.sp0 does be the kernel
thread stack, but now is not the kernel thread stack, rather it is the
trampoline stack (or entry stack) in the cpu entry area.

And bad IRET can happen when doing IRET to return to userspace and it
is also the trampoline stack. So fixup_bad_iret() is really just moving
the lower partial pt_regs up to concat with user IRET frame head
in the entry stack.

So fixup_bad_iret() will NOT have setup pt_regs on the thread stack.
And sync_regs() is needed after fixup_bad_iret()

The patch
https://lore.kernel.org/lkml/20200817062355.2884-3-jiangshanlai@gmail.com/
tried changing fixup_bad_iret() to copy the pt_regs directly to
the kernel stack.

And in the V1 of the patchset that converting ASM to code also
tried it:
https://lore.kernel.org/lkml/20210831175025.27570-13-jiangshanlai@gmail.com/

And in the current patchset, it focuses on ASM code only. I don't think
we need to change it.  It would be much simpler to change the behavior
of fixup_bad_iret() when error_entry() is converted to C.

>
> as hard-coded destination. Now, fixup_bad_iret() sets up a complete
> ptregs there and then returns a pointer to this stack.
>
> sync_regs otoh, does a straight up pt_regs sized copy from arg0 to this
> new stack.
>
> Therefore it appears to me that doing sync_regs() after fixup_bad_iret()
> is a complete NO-OP and only confuses things further.
>
> Would not something like the below clarify things?
>
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -1004,6 +1004,7 @@ SYM_CODE_START_LOCAL(error_entry)
>  .Lerror_entry_from_usermode_after_swapgs:
>         /* Put us onto the real thread stack. */
>         call    sync_regs
> +.Lerror_entry_from_usermode_after_sync_regs:
>         RET
>
>         /*
> @@ -1058,8 +1059,12 @@ SYM_CODE_START_LOCAL(error_entry)
>          */
>         leaq    8(%rsp), %rdi                   /* arg0 = pt_regs pointer */
>         call    fixup_bad_iret
> -       mov     %rax, %rdi
> -       jmp     .Lerror_entry_from_usermode_after_swapgs
> +       /*
> +        * fixup_bad_iret() will have setup pt_regs on the thread stack, and
> +        * returns a pointer to that stack exactly like sync_regs() would've
> +        * done. As such, calling sync_regs again makes no sense.
> +        */
> +       jmp     .Lerror_entry_from_usermode_after_sync_regs
>  SYM_CODE_END(error_entry)
>
>  SYM_CODE_START_LOCAL(error_return)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV
  2022-03-16 15:09   ` Peter Zijlstra
@ 2022-03-16 16:48     ` Lai Jiangshan
  0 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-16 16:48 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: LKML, X86 ML, Borislav Petkov, Lai Jiangshan, Andy Lutomirski,
	Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin

On Wed, Mar 16, 2022 at 11:09 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Tue, Mar 15, 2022 at 03:39:48PM +0800, Lai Jiangshan wrote:
> > From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> >
> > When in XENPV, it is already in the task stack, and it can't fault
> > for native_iret() nor native_load_gs_index() since XENPV uses its own
> > pvops for iret and load_gs_index().  And it doesn't need to switch CR3.
> > So there is no reason to call error_entry() in XENPV.
> >
> > Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
> > ---
> >  arch/x86/entry/entry_64.S | 13 +++++++++++--
> >  1 file changed, 11 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> > index e4a07276fd1c..ec885c2107de 100644
> > --- a/arch/x86/entry/entry_64.S
> > +++ b/arch/x86/entry/entry_64.S
> > @@ -328,8 +328,17 @@ SYM_CODE_END(ret_from_fork)
> >       PUSH_AND_CLEAR_REGS
> >       ENCODE_FRAME_POINTER
> >
> > -     call    error_entry
> > -     movq    %rax, %rsp                      /* switch stack settled by sync_regs() */
> > +     /*
> > +      * Call error_entry and switch stack settled by sync_regs().
> > +      *
> > +      * When in XENPV, it is already in the task stack, and it can't fault
> > +      * for native_iret() nor native_load_gs_index() since XENPV uses its
> > +      * own pvops for iret and load_gs_index().  And it doesn't need to
> > +      * switch CR3.  So it can skip invoking error_entry().
> > +      */
> > +     ALTERNATIVE "call error_entry; movq %rax, %rsp", \
> > +             "", X86_FEATURE_XENPV
> > +
> >       ENCODE_FRAME_POINTER
> >       UNWIND_HINT_REGS
> >
>
> Oooh, here we go, this is the answer to my question for patch #1, a note
> in the changelog might be nice. Something like:
>
> "This looses a Xen PV optimization, which will be restored in a later
> patch. The superfluous stack switch is just that."


In V2, the change of int80 thing is after this patch.  Maybe that order
of patches is more natural.  I'm sorry to reorder them.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 0/7] x86/entry: Clean up entry code
  2022-03-16 15:13   ` Peter Zijlstra
@ 2022-03-17 12:58     ` Lai Jiangshan
  0 siblings, 0 replies; 22+ messages in thread
From: Lai Jiangshan @ 2022-03-17 12:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: LKML, X86 ML, Borislav Petkov, Lai Jiangshan

On Wed, Mar 16, 2022 at 11:13 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Wed, Mar 16, 2022 at 04:12:21PM +0100, Peter Zijlstra wrote:
> > On Tue, Mar 15, 2022 at 03:39:42PM +0800, Lai Jiangshan wrote:
> >
> > > Lai Jiangshan (7):
> > >   x86/entry: Use idtentry macro for entry_INT80_compat
> > >   x86/traps: Move pt_regs only in fixup_bad_iret()
> > >   x86/entry: Switch the stack after error_entry() returns
> > >   x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry
> > >   x86/entry: Move cld to the start of idtentry
> > >   x86/entry: Don't call error_entry for XENPV
> > >   x86/entry: Convert SWAPGS to swapgs and remove the definition of
> > >     SWAPGS
> >
> > So AFAICT these patches are indeed correct.
> >
> > I do however worry a little bit about the I$ impact of patch 4, and
> > there's a few niggles, but otherwise looks good.
> >
> > I'd love for some of the other x86 people to also look at this, but a
> > tentative ACK on this.
> >
>
> Also, I forgot to mention; they no longer apply cleanly because I
> sprinked ENDBR all over the place. Mostly trivial to fixup though.


They can still be applied to the newest tip/master which already has
sprinked ENDBR.  Is there a more proper branch for me to rebase the
patches onto?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns
  2022-03-16 16:43     ` Lai Jiangshan
@ 2022-03-18 11:12       ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2022-03-18 11:12 UTC (permalink / raw)
  To: Lai Jiangshan
  Cc: LKML, X86 ML, Borislav Petkov, Lai Jiangshan, Andy Lutomirski,
	Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin

On Thu, Mar 17, 2022 at 12:43:02AM +0800, Lai Jiangshan wrote:
> On Wed, Mar 16, 2022 at 11:05 PM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > >  SYM_CODE_END(error_entry)
> >
> > So the new Changelog doesn't seem to help me much. But looking at both
> > fixup_bad_iret() and sync_regs(), they both have:
> >
> >   __this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1
> 

Yes, I can't read :/ Functions don't both use that.

Your patch is correct, not switching the stack in between runs sync_regs
from another stack, but the end result should be the same.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2022-03-18 11:12 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-15  7:39 [PATCH V3 0/7] x86/entry: Clean up entry code Lai Jiangshan
2022-03-15  7:39 ` [PATCH V3 1/7] x86/entry: Use idtentry macro for entry_INT80_compat Lai Jiangshan
2022-03-16 13:48   ` Peter Zijlstra
2022-03-15  7:39 ` [PATCH V3 2/7] x86/traps: Move pt_regs only in fixup_bad_iret() Lai Jiangshan
2022-03-15  7:39 ` [PATCH V3 3/7] x86/entry: Switch the stack after error_entry() returns Lai Jiangshan
2022-03-16  2:37   ` Josh Poimboeuf
2022-03-16  3:02     ` Lai Jiangshan
2022-03-16 15:05   ` Peter Zijlstra
2022-03-16 16:43     ` Lai Jiangshan
2022-03-18 11:12       ` Peter Zijlstra
2022-03-15  7:39 ` [PATCH V3 4/7] x86/entry: move PUSH_AND_CLEAR_REGS out of error_entry Lai Jiangshan
2022-03-16 15:07   ` Peter Zijlstra
2022-03-16 16:18     ` Lai Jiangshan
2022-03-15  7:39 ` [PATCH V3 5/7] x86/entry: Move cld to the start of idtentry Lai Jiangshan
2022-03-15  7:39 ` [PATCH V3 6/7] x86/entry: Don't call error_entry for XENPV Lai Jiangshan
2022-03-16  2:59   ` Josh Poimboeuf
2022-03-16 15:09   ` Peter Zijlstra
2022-03-16 16:48     ` Lai Jiangshan
2022-03-15  7:39 ` [PATCH V3 7/7] x86/entry: Convert SWAPGS to swapgs and remove the definition of SWAPGS Lai Jiangshan
2022-03-16 15:12 ` [PATCH V3 0/7] x86/entry: Clean up entry code Peter Zijlstra
2022-03-16 15:13   ` Peter Zijlstra
2022-03-17 12:58     ` Lai Jiangshan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.