In do_page_fault where an mceerr is generated stop and call force_sig_mceerr.
Keeping the mcerr handling logic out of the force_sig_info call below.

This ensures that only and always in the mcerr case is lsb interesting.

This ensures setting set si_lsb in the future won't accidentally
stomp another siginfo field in the non mcerr case.

Cc: James Bottomley <j...@parisc-linux.org>
Cc: Helge Deller <del...@gmx.de>
Cc: linux-par...@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebied...@xmission.com>
---
 arch/parisc/mm/fault.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 657b35096bd8..51215b0048ef 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -354,7 +354,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 
        if (user_mode(regs)) {
                struct siginfo si;
-               unsigned int lsb = 0;
 
                clear_siginfo(&si);
                switch (code) {
@@ -391,26 +390,27 @@ void do_page_fault(struct pt_regs *regs, unsigned long 
code,
 
 #ifdef CONFIG_MEMORY_FAILURE
                if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
+                       unsigned int lsb = 0;
                        printk(KERN_ERR
        "MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n",
                        tsk->comm, tsk->pid, address);
-                       si.si_signo = SIGBUS;
-                       si.si_code = BUS_MCEERR_AR;
+                       /*
+                        * Either small page or large page may be poisoned.
+                        * In other words, VM_FAULT_HWPOISON_LARGE and
+                        * VM_FAULT_HWPOISON are mutually exclusive.
+                        */
+                       if (fault & VM_FAULT_HWPOISON_LARGE)
+                               lsb = 
hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
+                       else if (fault & VM_FAULT_HWPOISON)
+                               lsb = PAGE_SHIFT;
+
+                       force_sig_mceerr(BUS_MCEERR_AR, (void __user *) address,
+                                        lsb, current);
+                       return;
                }
 #endif
 
-               /*
-                * Either small page or large page may be poisoned.
-                * In other words, VM_FAULT_HWPOISON_LARGE and
-                * VM_FAULT_HWPOISON are mutually exclusive.
-                */
-               if (fault & VM_FAULT_HWPOISON_LARGE)
-                       lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
-               else if (fault & VM_FAULT_HWPOISON)
-                       lsb = PAGE_SHIFT;
-               else
-                       show_signal_msg(regs, code, address, tsk, vma);
-               si.si_addr_lsb = lsb;
+               show_signal_msg(regs, code, address, tsk, vma);
 
                si.si_errno = 0;
                si.si_addr = (void __user *) address;
-- 
2.14.1

Reply via email to