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 --- |