forked from Minki/linux
powerpc/spufs: Use correct return value for spu_handle_mm_fault
Currently, spu_handle_mm_fault disregards the 'ret' variable and always returns -EFAULT on error. This change refactos spu_handle_mm_fault a little, to return the ret variable as appropriate. This allows us to combine the error and sucess paths. Also, remove the #if-0-ed IS_VALID_EA() check, it has never been used. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
13870b6575
commit
60ee031940
@ -39,60 +39,56 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
|
|||||||
unsigned long is_write;
|
unsigned long is_write;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#if 0
|
if (mm == NULL)
|
||||||
if (!IS_VALID_EA(ea)) {
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
|
||||||
#endif /* XXX */
|
if (mm->pgd == NULL)
|
||||||
if (mm == NULL) {
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
|
||||||
if (mm->pgd == NULL) {
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
|
ret = -EFAULT;
|
||||||
vma = find_vma(mm, ea);
|
vma = find_vma(mm, ea);
|
||||||
if (!vma)
|
if (!vma)
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
if (vma->vm_start <= ea)
|
|
||||||
goto good_area;
|
if (ea < vma->vm_start) {
|
||||||
if (!(vma->vm_flags & VM_GROWSDOWN))
|
if (!(vma->vm_flags & VM_GROWSDOWN))
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
if (expand_stack(vma, ea))
|
if (expand_stack(vma, ea))
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
good_area:
|
}
|
||||||
|
|
||||||
is_write = dsisr & MFC_DSISR_ACCESS_PUT;
|
is_write = dsisr & MFC_DSISR_ACCESS_PUT;
|
||||||
if (is_write) {
|
if (is_write) {
|
||||||
if (!(vma->vm_flags & VM_WRITE))
|
if (!(vma->vm_flags & VM_WRITE))
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
} else {
|
} else {
|
||||||
if (dsisr & MFC_DSISR_ACCESS_DENIED)
|
if (dsisr & MFC_DSISR_ACCESS_DENIED)
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
*flt = handle_mm_fault(mm, vma, ea, is_write);
|
*flt = handle_mm_fault(mm, vma, ea, is_write);
|
||||||
if (unlikely(*flt & VM_FAULT_ERROR)) {
|
if (unlikely(*flt & VM_FAULT_ERROR)) {
|
||||||
if (*flt & VM_FAULT_OOM) {
|
if (*flt & VM_FAULT_OOM) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
} else if (*flt & VM_FAULT_SIGBUS) {
|
} else if (*flt & VM_FAULT_SIGBUS) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto bad_area;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*flt & VM_FAULT_MAJOR)
|
if (*flt & VM_FAULT_MAJOR)
|
||||||
current->maj_flt++;
|
current->maj_flt++;
|
||||||
else
|
else
|
||||||
current->min_flt++;
|
current->min_flt++;
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
bad_area:
|
|
||||||
up_read(&mm->mmap_sem);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
|
EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
|
||||||
|
Loading…
Reference in New Issue
Block a user