fault.c (b4fd52f25c614f6904b86f708c20c82951c152ca) fault.c (419ceeb12865998b940ebd86d5fb415efde1e864)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 1995 Linus Torvalds
4 * Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
5 * Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar
6 */
7#include <linux/sched.h> /* test_thread_flag(), ... */
8#include <linux/sched/task_stack.h> /* task_stack_*(), ... */

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

764
765 printk(KERN_CONT "\n");
766
767 show_opcodes((u8 *)regs->ip, loglvl);
768}
769
770static void
771__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 1995 Linus Torvalds
4 * Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
5 * Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar
6 */
7#include <linux/sched.h> /* test_thread_flag(), ... */
8#include <linux/sched/task_stack.h> /* task_stack_*(), ... */

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

764
765 printk(KERN_CONT "\n");
766
767 show_opcodes((u8 *)regs->ip, loglvl);
768}
769
770static void
771__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
772 unsigned long address, u32 *pkey, int si_code)
772 unsigned long address, u32 pkey, int si_code)
773{
774 struct task_struct *tsk = current;
775
776 /* User mode accesses just cause a SIGSEGV */
777 if (error_code & X86_PF_USER) {
778 /*
779 * It's possible to have interrupts off here:
780 */

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

813 if (likely(show_unhandled_signals))
814 show_signal_msg(regs, error_code, address, tsk);
815
816 tsk->thread.cr2 = address;
817 tsk->thread.error_code = error_code;
818 tsk->thread.trap_nr = X86_TRAP_PF;
819
820 if (si_code == SEGV_PKUERR)
773{
774 struct task_struct *tsk = current;
775
776 /* User mode accesses just cause a SIGSEGV */
777 if (error_code & X86_PF_USER) {
778 /*
779 * It's possible to have interrupts off here:
780 */

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

813 if (likely(show_unhandled_signals))
814 show_signal_msg(regs, error_code, address, tsk);
815
816 tsk->thread.cr2 = address;
817 tsk->thread.error_code = error_code;
818 tsk->thread.trap_nr = X86_TRAP_PF;
819
820 if (si_code == SEGV_PKUERR)
821 force_sig_pkuerr((void __user *)address, *pkey);
821 force_sig_pkuerr((void __user *)address, pkey);
822
823 force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
824
825 return;
826 }
827
828 if (is_f00f_bug(regs, address))
829 return;
830
831 no_context(regs, error_code, address, SIGSEGV, si_code);
832}
833
834static noinline void
835bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
836 unsigned long address)
837{
822
823 force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
824
825 return;
826 }
827
828 if (is_f00f_bug(regs, address))
829 return;
830
831 no_context(regs, error_code, address, SIGSEGV, si_code);
832}
833
834static noinline void
835bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
836 unsigned long address)
837{
838 __bad_area_nosemaphore(regs, error_code, address, NULL, SEGV_MAPERR);
838 __bad_area_nosemaphore(regs, error_code, address, 0, SEGV_MAPERR);
839}
840
841static void
842__bad_area(struct pt_regs *regs, unsigned long error_code,
839}
840
841static void
842__bad_area(struct pt_regs *regs, unsigned long error_code,
843 unsigned long address, u32 *pkey, int si_code)
843 unsigned long address, u32 pkey, int si_code)
844{
845 struct mm_struct *mm = current->mm;
846 /*
847 * Something tried to access memory that isn't in our memory map..
848 * Fix it, but check if it's kernel or user first..
849 */
850 up_read(&mm->mmap_sem);
851
852 __bad_area_nosemaphore(regs, error_code, address, pkey, si_code);
853}
854
855static noinline void
856bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
857{
844{
845 struct mm_struct *mm = current->mm;
846 /*
847 * Something tried to access memory that isn't in our memory map..
848 * Fix it, but check if it's kernel or user first..
849 */
850 up_read(&mm->mmap_sem);
851
852 __bad_area_nosemaphore(regs, error_code, address, pkey, si_code);
853}
854
855static noinline void
856bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
857{
858 __bad_area(regs, error_code, address, NULL, SEGV_MAPERR);
858 __bad_area(regs, error_code, address, 0, SEGV_MAPERR);
859}
860
861static inline bool bad_area_access_from_pkeys(unsigned long error_code,
862 struct vm_area_struct *vma)
863{
864 /* This code is always called on the current mm */
865 bool foreign = false;
866

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

902 * 3. T1 : faults...
903 * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5);
904 * 5. T1 : enters fault handler, takes mmap_sem, etc...
905 * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really
906 * faulted on a pte with its pkey=4.
907 */
908 u32 pkey = vma_pkey(vma);
909
859}
860
861static inline bool bad_area_access_from_pkeys(unsigned long error_code,
862 struct vm_area_struct *vma)
863{
864 /* This code is always called on the current mm */
865 bool foreign = false;
866

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

902 * 3. T1 : faults...
903 * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5);
904 * 5. T1 : enters fault handler, takes mmap_sem, etc...
905 * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really
906 * faulted on a pte with its pkey=4.
907 */
908 u32 pkey = vma_pkey(vma);
909
910 __bad_area(regs, error_code, address, &pkey, SEGV_PKUERR);
910 __bad_area(regs, error_code, address, pkey, SEGV_PKUERR);
911 } else {
911 } else {
912 __bad_area(regs, error_code, address, NULL, SEGV_ACCERR);
912 __bad_area(regs, error_code, address, 0, SEGV_ACCERR);
913 }
914}
915
916static void
917do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
918 unsigned int fault)
919{
920 struct task_struct *tsk = current;

--- 502 unchanged lines hidden ---
913 }
914}
915
916static void
917do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
918 unsigned int fault)
919{
920 struct task_struct *tsk = current;

--- 502 unchanged lines hidden ---