traps.c (6d9256f0a89eaff97fca6006100bcaea8d1d8bdb) traps.c (7f2590a110b837af5679d08fc25c6227c5a8c497)
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 *
5 * Pentium III FXSR, SSE support
6 * Gareth Hughes <gareth@valinux.com>, May 2000
7 */
8

--- 605 unchanged lines hidden (view full) ---

614 debug_stack_usage_dec();
615exit:
616 ist_exit(regs);
617}
618NOKPROBE_SYMBOL(do_int3);
619
620#ifdef CONFIG_X86_64
621/*
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 *
5 * Pentium III FXSR, SSE support
6 * Gareth Hughes <gareth@valinux.com>, May 2000
7 */
8

--- 605 unchanged lines hidden (view full) ---

614 debug_stack_usage_dec();
615exit:
616 ist_exit(regs);
617}
618NOKPROBE_SYMBOL(do_int3);
619
620#ifdef CONFIG_X86_64
621/*
622 * Help handler running on IST stack to switch off the IST stack if the
623 * interrupted code was in user mode. The actual stack switch is done in
624 * entry_64.S
622 * Help handler running on a per-cpu (IST or entry trampoline) stack
623 * to switch to the normal thread stack if the interrupted code was in
624 * user mode. The actual stack switch is done in entry_64.S
625 */
626asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs)
627{
625 */
626asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs)
627{
628 struct pt_regs *regs = task_pt_regs(current);
629 *regs = *eregs;
628 struct pt_regs *regs = (struct pt_regs *)this_cpu_read(cpu_current_top_of_stack) - 1;
629 if (regs != eregs)
630 *regs = *eregs;
630 return regs;
631}
632NOKPROBE_SYMBOL(sync_regs);
633
634struct bad_iret_stack {
635 void *error_entry_ret;
636 struct pt_regs regs;
637};
638
639asmlinkage __visible notrace
640struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
641{
642 /*
643 * This is called from entry_64.S early in handling a fault
644 * caused by a bad iret to user mode. To handle the fault
631 return regs;
632}
633NOKPROBE_SYMBOL(sync_regs);
634
635struct bad_iret_stack {
636 void *error_entry_ret;
637 struct pt_regs regs;
638};
639
640asmlinkage __visible notrace
641struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
642{
643 /*
644 * This is called from entry_64.S early in handling a fault
645 * caused by a bad iret to user mode. To handle the fault
645 * correctly, we want move our stack frame to task_pt_regs
646 * and we want to pretend that the exception came from the
647 * iret target.
646 * correctly, we want to move our stack frame to where it would
647 * be had we entered directly on the entry stack (rather than
648 * just below the IRET frame) and we want to pretend that the
649 * exception came from the IRET target.
648 */
649 struct bad_iret_stack *new_stack =
650 */
651 struct bad_iret_stack *new_stack =
650 container_of(task_pt_regs(current),
651 struct bad_iret_stack, regs);
652 (struct bad_iret_stack *)this_cpu_read(cpu_tss.x86_tss.sp0) - 1;
652
653 /* Copy the IRET target to the new stack. */
654 memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8);
655
656 /* Copy the remainder of the stack from the current stack. */
657 memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip));
658
659 BUG_ON(!user_mode(&new_stack->regs));

--- 310 unchanged lines hidden ---
653
654 /* Copy the IRET target to the new stack. */
655 memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8);
656
657 /* Copy the remainder of the stack from the current stack. */
658 memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip));
659
660 BUG_ON(!user_mode(&new_stack->regs));

--- 310 unchanged lines hidden ---