Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
vm_fault_t fault;
unsigned int flags = FAULT_FLAG_DEFAULT;
vm_flags_t vm_flags = VM_ACCESS_FLAGS;
bool vma_lock_retried = false;

if (kprobe_page_fault(regs, fsr))
return 0;
Expand Down Expand Up @@ -395,6 +396,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, addr);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -424,6 +426,12 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
goto no_context;
return 0;
}

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

retry:
Expand Down
8 changes: 8 additions & 0 deletions arch/arm64/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
struct vm_area_struct *vma;
int si_code;
int pkey = -1;
bool vma_lock_retried = false;

if (kprobe_page_fault(regs, esr))
return 0;
Expand Down Expand Up @@ -678,6 +679,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
if (!(mm_flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, addr);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -724,6 +726,12 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
goto no_context;
return 0;
}

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

retry:
Expand Down
8 changes: 8 additions & 0 deletions arch/loongarch/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs,
struct mm_struct *mm = tsk->mm;
struct vm_area_struct *vma = NULL;
vm_fault_t fault;
bool vma_lock_retried = false;

if (kprobe_page_fault(regs, current->thread.trap_nr))
return;
Expand Down Expand Up @@ -219,6 +220,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs,
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -265,6 +267,12 @@ static void __kprobes __do_page_fault(struct pt_regs *regs,
no_context(regs, write, address);
return;
}

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

retry:
Expand Down
7 changes: 7 additions & 0 deletions arch/powerpc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
int is_write = page_fault_is_write(error_code);
vm_fault_t fault, major = 0;
bool kprobe_fault = kprobe_page_fault(regs, 11);
bool vma_lock_retried = false;

if (unlikely(debugger_fault_handler(regs) || kprobe_fault))
return 0;
Expand Down Expand Up @@ -487,6 +488,7 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -517,6 +519,11 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
if (fault_signal_pending(fault, regs))
return user_mode(regs) ? 0 : SIGBUS;

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

/* When running in the kernel we expect faults to occur only to
Expand Down
8 changes: 8 additions & 0 deletions arch/riscv/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ void handle_page_fault(struct pt_regs *regs)
unsigned int flags = FAULT_FLAG_DEFAULT;
int code = SEGV_MAPERR;
vm_fault_t fault;
bool vma_lock_retried = false;

cause = regs->cause;
addr = regs->badaddr;
Expand Down Expand Up @@ -347,6 +348,7 @@ void handle_page_fault(struct pt_regs *regs)
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, addr);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -376,6 +378,12 @@ void handle_page_fault(struct pt_regs *regs)
no_context(regs, addr);
return;
}

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

retry:
Expand Down
6 changes: 6 additions & 0 deletions arch/s390/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ static void do_exception(struct pt_regs *regs, int access)
unsigned int flags;
vm_fault_t fault;
bool is_write;
bool vma_lock_retried = false;

/*
* The instruction that caused the program check has
Expand All @@ -294,6 +295,7 @@ static void do_exception(struct pt_regs *regs, int access)
flags |= FAULT_FLAG_WRITE;
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;
lock_vma:
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap;
Expand All @@ -318,6 +320,10 @@ static void do_exception(struct pt_regs *regs, int access)
handle_fault_error_nolock(regs, 0);
return;
}
if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}
lock_mmap:
retry:
vma = lock_mm_and_find_vma(mm, address, regs);
Expand Down
8 changes: 8 additions & 0 deletions arch/x86/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,7 @@ void do_user_addr_fault(struct pt_regs *regs,
struct mm_struct *mm;
vm_fault_t fault;
unsigned int flags = FAULT_FLAG_DEFAULT;
bool vma_lock_retried = false;

tsk = current;
mm = tsk->mm;
Expand Down Expand Up @@ -1331,6 +1332,7 @@ void do_user_addr_fault(struct pt_regs *regs,
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;

lock_vma:
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap;
Expand Down Expand Up @@ -1360,6 +1362,12 @@ void do_user_addr_fault(struct pt_regs *regs,
ARCH_DEFAULT_PKEY);
return;
}

if (!vma_lock_retried) {
vma_lock_retried = true;
goto lock_vma;
}

lock_mmap:

retry:
Expand Down
Loading