If handle_speculative_fault failed due to a VM ERROR, we try again the
slow path to allow the signal to be delivered.

Signed-off-by: Laurent Dufour <[email protected]>
---
 arch/x86/mm/fault.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 0c0b45dfda76..02c0b884ca18 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1369,10 +1369,14 @@ __do_page_fault(struct pt_regs *regs, unsigned long 
error_code,
                fault = handle_speculative_fault(mm, address,
                                        flags & ~FAULT_FLAG_ALLOW_RETRY);
 
-               if (fault & VM_FAULT_RETRY)
-                       goto retry;
-
-               goto done;
+               /*
+                * We also check against VM_FAULT_ERROR because we have to
+                * raise a signal by calling later mm_fault_error() which
+                * requires the vma pointer to be set. So in that case,
+                * we fall through the normal path.
+                */
+               if (!(fault & VM_FAULT_RETRY || fault & VM_FAULT_ERROR))
+                       goto done;
        }
 
        /*
@@ -1478,20 +1482,13 @@ __do_page_fault(struct pt_regs *regs, unsigned long 
error_code,
                return;
        }
 
-       if (unlikely(fault & VM_FAULT_RETRY)) {
-               if (fatal_signal_pending(current))
-                       return;
-
-               goto done;
-       }
-
        up_read(&mm->mmap_sem);
-done:
        if (unlikely(fault & VM_FAULT_ERROR)) {
                mm_fault_error(regs, error_code, address, vma, fault);
                return;
        }
 
+done:
        /*
         * Major/minor page fault accounting. If any of the events
         * returned VM_FAULT_MAJOR, we account it as a major fault.
-- 
2.7.4

Reply via email to