diff options
Diffstat (limited to 'arch/riscv/mm/fault.c')
| -rw-r--r-- | arch/riscv/mm/fault.c | 15 | 
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index d86f7cebd4a7..460f785f6e09 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -267,10 +267,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs)  	if (user_mode(regs))  		flags |= FAULT_FLAG_USER; -	if (!user_mode(regs) && addr < TASK_SIZE && -			unlikely(!(regs->status & SR_SUM))) -		die_kernel_fault("access to user memory without uaccess routines", -				addr, regs); +	if (!user_mode(regs) && addr < TASK_SIZE && unlikely(!(regs->status & SR_SUM))) { +		if (fixup_exception(regs)) +			return; + +		die_kernel_fault("access to user memory without uaccess routines", addr, regs); +	}  	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); @@ -324,8 +326,11 @@ good_area:  	 * signal first. We do not need to release the mmap_lock because it  	 * would already be released in __lock_page_or_retry in mm/filemap.c.  	 */ -	if (fault_signal_pending(fault, regs)) +	if (fault_signal_pending(fault, regs)) { +		if (!user_mode(regs)) +			no_context(regs, addr);  		return; +	}  	/* The fault is fully completed (including releasing mmap lock) */  	if (fault & VM_FAULT_COMPLETED)  |