[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 02/11] x86/traps: Move pt_regs only in fixup_bad_iret()



From: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx>

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 <laijs@xxxxxxxxxxxxxxxxx>
---
 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 d95a02ecee16..f8faff3ca61e 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1040,9 +1040,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 6221be7cafc3..1cdd7e8bcba7 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 c9d566dcf89a..a6c0bc9ee36f 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -761,13 +761,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
@@ -777,19 +772,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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.