Patch "sparc64: Handle PIO & MEM non-resumable errors." has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
sparc64: Handle PIO & MEM non-resumable errors.
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
sparc64-handle-pio-mem-non-resumable-errors.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Jul 3 11:00:33 CEST 2017
From: "Liam R. Howlett" <[email protected]>
Date: Tue, 23 May 2017 21:54:10 -0400
Subject: sparc64: Handle PIO & MEM non-resumable errors.
From: "Liam R. Howlett" <[email protected]>
[ Upstream commit 047487241ff59374fded8c477f21453681f5995c ]
User processes trying to access an invalid memory address via PIO will receive a SIGBUS signal instead of causing a panic. Memory errors will receive a SIGKILL since a SIGBUS may result in a coredump which may attempt to repeat the faulting access.
--- arch/sparc/kernel/traps_64.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
arch/sparc/kernel/traps_64.c +73 -0
@@ -2051,6 +2051,73 @@ void sun4v_resum_overflow(struct pt_regsatomic_inc (&sun4v_resum_oflow_cnt); } +/* Given a set of registers, get the virtual addressi that was being accessed +* by the faulting instructions at tpc. +*/ +static unsigned long sun4v_get_vaddr (struct pt_regs *regs) +{ +unsigned int insn; + +if (!copy_from_user (&insn, (void __user *)regs->tpc,4 )) { +return compute_effective_address (regs, insn, + (insn >>25 ) &0x1f ); + } +return 0 ; +} + +/* Attempt to handle non-resumable errors generated from userspace. +* Returns true if the signal was handled, false otherwise. +*/ +bool sun4v_nonresum_error_user_handled (struct pt_regs *regs, +struct sun4v_error_entry *ent) { + +unsigned int attrs = ent->err_attrs; + +if (attrs &SUN4V_ERR_ATTRS_MEMORY ) { +unsigned long addr = ent->err_raddr; +siginfo_t info; + +if (addr == ~(u64 )0 ) { +/* This seems highly unlikely to ever occur */ +pr_emerg ("SUN4V NON-RECOVERABLE ERROR: Memory error detected in unknown location!\n" ); + }else { +unsigned long page_cnt =DIV_ROUND_UP (ent->err_size, +PAGE_SIZE ); + +/* Break the unfortunate news. */ +pr_emerg ("SUN4V NON-RECOVERABLE ERROR: Memory failed at %016lX\n" , + addr); +pr_emerg ("SUN4V NON-RECOVERABLE ERROR: Claiming %lu ages.\n" , + page_cnt); + +while (page_cnt-- >0 ) { +if (pfn_valid (addr >>PAGE_SHIFT )) +get_page (pfn_to_page (addr >>PAGE_SHIFT )); + addr +=PAGE_SIZE ; + } + } + info.si_signo =SIGKILL ; + info.si_errno =0 ; + info.si_trapno =0 ; +force_sig_info (info.si_signo, &info, current); + +return true; + } +if (attrs &SUN4V_ERR_ATTRS_PIO ) { +siginfo_t info; + + info.si_signo =SIGBUS ; + info.si_code =BUS_ADRERR ; + info.si_addr = (void __user *)sun4v_get_vaddr (regs); +force_sig_info (info.si_signo, &info, current); + +return true; + } + +/* Default to doing nothing */ +return false; +} +/* We run with %pil set to PIL_NORMAL_MAX and PSTATE_IE enabled in %pstate. * Log the event, clear the first word of the entry, and die. */
@@ -2075,6 +2142,12 @@ void sun4v_nonresum_error(struct pt_regsput_cpu (); +if (!(regs->tstate &TSTATE_PRIV ) && +sun4v_nonresum_error_user_handled (regs, &local_copy)) { +/* DON'T PANIC: This userspace error was handled. */ +return ; + } +#ifdef CONFIG_PCI /* Check for the special PCI poke sequence. */ if (pci_poke_in_progress && pci_poke_cpu == cpu) {
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/sparc64-handle-pio-mem-non-resumable-errors.patch queue-4.9/sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch