diff options
Diffstat (limited to 'arch/s390/mm/fault.c')
| -rw-r--r-- | arch/s390/mm/fault.c | 24 | 
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index a2632fd97d00..b65144c392b0 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -407,6 +407,30 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access)  		access = VM_WRITE;  	if (access == VM_WRITE)  		flags |= FAULT_FLAG_WRITE; +#ifdef CONFIG_PER_VMA_LOCK +	if (!(flags & FAULT_FLAG_USER)) +		goto lock_mmap; +	vma = lock_vma_under_rcu(mm, address); +	if (!vma) +		goto lock_mmap; +	if (!(vma->vm_flags & access)) { +		vma_end_read(vma); +		goto lock_mmap; +	} +	fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs); +	vma_end_read(vma); +	if (!(fault & VM_FAULT_RETRY)) { +		count_vm_vma_lock_event(VMA_LOCK_SUCCESS); +		goto out; +	} +	count_vm_vma_lock_event(VMA_LOCK_RETRY); +	/* Quick path to respond to signals */ +	if (fault_signal_pending(fault, regs)) { +		fault = VM_FAULT_SIGNAL; +		goto out; +	} +lock_mmap: +#endif /* CONFIG_PER_VMA_LOCK */  	mmap_read_lock(mm);  	gmap = NULL;  |