From: AMEET M. PARANJAPE <aparanja@redhat.com> Date: Thu, 6 Nov 2008 13:33:02 -0500 Subject: [ppc64] cell: fix page fault error checking in spufs Message-id: 20081106183226.12344.58739.sendpatchset@squad5-lp1.lab.bos.redhat.com O-Subject: [PATCH RHEL5.3 BZ470301] Fix page fault error checking in Cell spufs Bugzilla: 470301 RH-Acked-by: David Howells <dhowells@redhat.com> RHBZ#: ====== https://bugzilla.redhat.com/show_bug.cgi?id=470301 Description: =========== Note the upstream commit 83c54070ee1a2d05c89793884bea1a03f2851ed4 turned the VM_FAULT_* constants into bit flags, including handling in spufs. However, the RHEL5.3 beta kernel still has the non-bitflag form of return codes from handle_mm_fault. As the current backport of spufs expects the bit-flag format, this breaks the error checking in spu_handle_mm_fault, as flt & VM_FAULT_SIGBUS (0x2) will return true if flt is VM_FAULT_MAJOR (0x3), a standard successful return code. This means that any major page fault handled by spufs will fail. This change alters the check to the return value of handle_mm_fault in spu_handle_mm_fault to use the non-bit flag form of the VM_FAULT constants. RHEL Version Found: ================ RHEL 5.3 Beta kABI Status: ============ No symbols were harmed. Brew: ===== Built on all platforms. http://brewweb.devel.redhat.com/brew/taskinfo?taskID=1561667 Upstream Status: ================ Upstream commit 83c54070ee1a2d05c89793884bea1a03f2851ed4 Test Status: ============ There is a testcase given in the Bugzilla. Without this patch the testcase shows that the the Direct Memory Access (DMA) from the source file into the Local Store (LS) succeeds, but the DMA from the LS to the destination file fails which causes the segfault. This problem is not seen with this patch. =============================================================== Ameet Paranjape 978-392-3903 ext 23903 IBM on-site partner Proposed Patch: =============== diff --git a/arch/powerpc/platforms/cell/spu_fault.c b/arch/powerpc/platforms/cell/spu_fault.c index 90a8a5f..54ee12c 100644 --- a/arch/powerpc/platforms/cell/spu_fault.c +++ b/arch/powerpc/platforms/cell/spu_fault.c @@ -74,20 +74,22 @@ good_area: } ret = 0; *flt = handle_mm_fault(mm, vma, ea, is_write); - if (unlikely(*flt & (VM_FAULT_OOM | VM_FAULT_SIGBUS))) { - if (*flt & VM_FAULT_OOM) { - ret = -ENOMEM; - goto bad_area; - } else if (*flt & VM_FAULT_SIGBUS) { - ret = -EFAULT; - goto bad_area; - } - BUG(); + + if (unlikely(*flt == VM_FAULT_OOM)) { + ret = -ENOMEM; + goto bad_area; } - if (*flt & VM_FAULT_MAJOR) + + if (unlikely(*flt == VM_FAULT_SIGBUS)) { + ret = -EFAULT; + goto bad_area; + } + + if (*flt == VM_FAULT_MAJOR) current->maj_flt++; else current->min_flt++; + up_read(&mm->mmap_sem); return ret;