Path: blob/master/arch/powerpc/platforms/cell/spu_fault.c
10818 views
/*1* SPU mm fault handler2*3* (C) Copyright IBM Deutschland Entwicklung GmbH 20074*5* Author: Arnd Bergmann <[email protected]>6* Author: Jeremy Kerr <[email protected]>7*8* This program is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License as published by10* the Free Software Foundation; either version 2, or (at your option)11* any later version.12*13* This program is distributed in the hope that it will be useful,14* but WITHOUT ANY WARRANTY; without even the implied warranty of15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software20* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.21*/22#include <linux/sched.h>23#include <linux/mm.h>24#include <linux/module.h>2526#include <asm/spu.h>27#include <asm/spu_csa.h>2829/*30* This ought to be kept in sync with the powerpc specific do_page_fault31* function. Currently, there are a few corner cases that we haven't had32* to handle fortunately.33*/34int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,35unsigned long dsisr, unsigned *flt)36{37struct vm_area_struct *vma;38unsigned long is_write;39int ret;4041if (mm == NULL)42return -EFAULT;4344if (mm->pgd == NULL)45return -EFAULT;4647down_read(&mm->mmap_sem);48ret = -EFAULT;49vma = find_vma(mm, ea);50if (!vma)51goto out_unlock;5253if (ea < vma->vm_start) {54if (!(vma->vm_flags & VM_GROWSDOWN))55goto out_unlock;56if (expand_stack(vma, ea))57goto out_unlock;58}5960is_write = dsisr & MFC_DSISR_ACCESS_PUT;61if (is_write) {62if (!(vma->vm_flags & VM_WRITE))63goto out_unlock;64} else {65if (dsisr & MFC_DSISR_ACCESS_DENIED)66goto out_unlock;67if (!(vma->vm_flags & (VM_READ | VM_EXEC)))68goto out_unlock;69}7071ret = 0;72*flt = handle_mm_fault(mm, vma, ea, is_write ? FAULT_FLAG_WRITE : 0);73if (unlikely(*flt & VM_FAULT_ERROR)) {74if (*flt & VM_FAULT_OOM) {75ret = -ENOMEM;76goto out_unlock;77} else if (*flt & VM_FAULT_SIGBUS) {78ret = -EFAULT;79goto out_unlock;80}81BUG();82}8384if (*flt & VM_FAULT_MAJOR)85current->maj_flt++;86else87current->min_flt++;8889out_unlock:90up_read(&mm->mmap_sem);91return ret;92}93EXPORT_SYMBOL_GPL(spu_handle_mm_fault);949596