2022-04-12 22:02:42

by Lai Jiangshan

[permalink] [raw]
Subject: [PATCH V5 0/7] x86/entry: Clean up entry code

From: Lai Jiangshan <[email protected]>

This patchset moves the stack-switch code to the place where
error_entry() return, unravels error_entry() from XENpv and makes
entry_INT80_compat() uses 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 5th version to pick patches from the patchset
https://lore.kernel.org/lkml/[email protected]/
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.

Peter said in V3:
> So AFAICT these patches are indeed correct.
>
> I'd love for some of the other x86 people to also look at this,
> but a tentative ACK on this.

[V4]: https://lore.kernel.org/lkml/[email protected]/
[V3]: https://lore.kernel.org/lkml/[email protected]/
[V2]: https://lore.kernel.org/lkml/[email protected]/
[V1]: https://lore.kernel.org/lkml/[email protected]/

Changed from V4:
Update changelog largely of patch 1 and patch 2
Update changelog slightly of other patches
Unbreak the line of fixup_bad_iret() in patch1

Add Reviewed-by from Juergen Gross <[email protected]> in patch 6
since he gave the Reviewed-by in one of the squashed patches.

Changed from V3:
Only reorder the int80 thing as the last patch to make patches
ordering more natural. (Both orders are correct)

Other interactions in V3:
Peter raised several questions and I think I answered them and I
don't think the code need to be updated unless I missed some
points. (Except reordering the patches)

Josh asked to remove UNWIND_HINT_REGS in patch5, but I think
UNWIND_HINT_REGS is old code before this patchset and I don't
want to do a cleanup that is not relate to preparing converting
ASM code C code in this patchset. He also asked to remove
ENCODE_FRAME_POINTER in xenpv case, and I think it just
complicates the code for just optimizing out a single assignment
to %rbp. I would not always stick to these reasons of mine,
but I just keep the code unchanged since he hasn't emphasized it
again nor other people has requested it.

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
[email protected] is the only portal for opensource work
in the corporate group.


Lai Jiangshan (7):
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 macro
x86/entry: Don't call error_entry() for XENPV
x86/entry: Convert SWAPGS to swapgs and remove the definition of
SWAPGS
x86/entry: Use idtentry macro for entry_INT80_compat

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 | 18 ++----
7 files changed, 100 insertions(+), 145 deletions(-)

--
2.19.1.6.gb485710b


2022-04-12 22:19:19

by Lai Jiangshan

[permalink] [raw]
Subject: [PATCH V5 4/7] x86/entry: Move cld to the start of idtentry macro

From: Lai Jiangshan <[email protected]>

Make it next to CLAC

Suggested-by: Peter Zijlstra <[email protected]>
Signed-off-by: Lai Jiangshan <[email protected]>
---
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 835b798556fb..7b6a0f15bb20 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 */
@@ -428,6 +429,7 @@ SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS
ENDBR
ASM_CLAC
+ cld

pushq $-1 /* ORIG_RAX: no syscall to restart */

@@ -484,6 +486,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
@@ -546,6 +549,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
@@ -871,7 +875,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

@@ -989,7 +992,6 @@ SYM_CODE_END(paranoid_exit)
*/
SYM_CODE_START_LOCAL(error_entry)
UNWIND_HINT_FUNC
- cld
testb $3, CS+8(%rsp)
jz .Lerror_kernelspace

@@ -1123,6 +1125,7 @@ SYM_CODE_START(asm_exc_nmi)
*/

ASM_CLAC
+ cld

/* Use %rdx as our temp variable throughout */
pushq %rdx
@@ -1142,7 +1145,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

2022-04-12 23:23:04

by Lai Jiangshan

[permalink] [raw]
Subject: [PATCH V5 7/7] x86/entry: Use idtentry macro for entry_INT80_compat

From: Lai Jiangshan <[email protected]>

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 <[email protected]>
---
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 6611032979d9..d49b93f494df 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -375,6 +375,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 c5aeb0819707..6866151bbef3 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 72184b0b2219..5bf8a01d31f3 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)

@@ -642,6 +685,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 0f899c8d7a4e..4700d1650410 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

2022-04-12 23:37:10

by Lai Jiangshan

[permalink] [raw]
Subject: [PATCH V5 5/7] x86/entry: Don't call error_entry() for XENPV

From: Lai Jiangshan <[email protected]>

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 the CR3.

So there is no reason to call error_entry() in XENPV.

Signed-off-by: Lai Jiangshan <[email protected]>
---
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 7b6a0f15bb20..3aca7815fe79 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 to the task stack if from userspace */
+ /*
+ * Call error_entry() and switch to the task stack if from userspace.
+ *
+ * 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 the 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

2022-04-12 23:55:46

by Lai Jiangshan

[permalink] [raw]
Subject: [PATCH V5 2/7] x86/entry: Switch the stack after error_entry() returns

From: Lai Jiangshan <[email protected]>

error_entry() calls sync_regs(), and fixup_bad_iret() before sync_regs()
if it is a fault from bad IRET, to copy the pt_regs to the kernel stack
and switches the kernel stack directly after sync_regs().

But error_entry() itself is also a function call, so the code has to
stash the address error_entry() is going to return to, in %r12 and
makes the work complicated.

Move the code of switching stack after error_entry() and get rid of the
need to handle the return address.

Signed-off-by: Lai Jiangshan <[email protected]>
---
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 e9d896717ab4..e1efc56fbcd4 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 to the task stack if from userspace */
+ ENCODE_FRAME_POINTER
UNWIND_HINT_REGS

movq %rsp, %rdi /* pt_regs pointer into 1st argument*/
@@ -999,14 +1001,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

/*
@@ -1038,6 +1036,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:
@@ -1058,12 +1057,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

2022-04-21 06:43:03

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH V5 5/7] x86/entry: Don't call error_entry() for XENPV

On Tue, Apr 12, 2022 at 08:15:39PM +0800, Lai Jiangshan wrote:
> From: Lai Jiangshan <[email protected]>
>
> 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 the CR3.
>
> So there is no reason to call error_entry() in XENPV.
>
> Signed-off-by: Lai Jiangshan <[email protected]>
> ---
> 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 7b6a0f15bb20..3aca7815fe79 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 to the task stack if from userspace */
> + /*
> + * Call error_entry() and switch to the task stack if from userspace.
> + *
> + * 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 the CR3. So it can skip invoking error_entry().
> + */
> + ALTERNATIVE "call error_entry; movq %rax, %rsp", \
> + "", X86_FEATURE_XENPV
> +
> ENCODE_FRAME_POINTER
> UNWIND_HINT_REGS
>
> --

This one needs Jürgen. CCed.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2022-04-25 19:26:20

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH V5 7/7] x86/entry: Use idtentry macro for entry_INT80_compat

On Tue, Apr 12 2022 at 20:15, Lai Jiangshan wrote:
> From: Lai Jiangshan <[email protected]>
>
> entry_INT80_compat is identical to idtentry macro except a special
> handling for %rax in the prolog.

Seriously?

> - pushq %rsi /* pt_regs->si */
> - xorl %esi, %esi /* nospec si */

esi is not cleared in CLEAR_REGS. So much for identical.

Thanks,

tglx


2022-04-26 08:35:51

by Lai Jiangshan

[permalink] [raw]
Subject: Re: [PATCH V5 7/7] x86/entry: Use idtentry macro for entry_INT80_compat

On Mon, Apr 25, 2022 at 6:24 PM Thomas Gleixner <[email protected]> wrote:
>
> On Tue, Apr 12 2022 at 20:15, Lai Jiangshan wrote:
> > From: Lai Jiangshan <[email protected]>
> >
> > entry_INT80_compat is identical to idtentry macro except a special
> > handling for %rax in the prolog.
>
> Seriously?
>
> > - pushq %rsi /* pt_regs->si */
> > - xorl %esi, %esi /* nospec si */
>
> esi is not cleared in CLEAR_REGS. So much for identical.
>
>

Hello, Thomas

Thank you for the review.

They (the old entry_INT80_compat() and the new using the macro
idtentry) are not identical in ASM code.

The macro idtentry pushes %rsi to the entry stack and then copies
it from the entry stack to the kernel stack and then switches
the stack.

The original entry_INT80_compat() is much more straightforward
and efficient. It switches the stack as soon as possible and
then pushes %rsi directly onto the kernel stack.

So they are different in this aspect.

I compared the macro idtentry and the original entry_INT80_compat(),
to check if the macro idtentry has all the behaviors that the INT80
thing has and check if what the macro idtentry has but the INT80
thing doesn't is a No-op (like the handling of bad IRET).

In my view, the checks don't fail my expectations except for
regs->ax and regs->orig_ax.

As for CLEAR_REGS, I also have reviewed it many times. To me, it
equals clearing all registers although it doesn't clear ax, sp,
di, si. In the comments, it says

The lower registers are likely clobbered well before they could
be put to use in a speculative execution gadget.

When using CLEAR_REGS for the INT80 thing, the %rsi will be cleared
explicitly when syscall_enter_from_user_mode() which has 2 arguments
is called.

"identical" is overstated. I will change the changelog to say their
behaviors are almost similar and the final result are the same when
the macro idtentry has the prolog.

Thanks
Lai