FAILED: patch "[PATCH] powerpc/64s: system call scv tabort fix for corrupt irq" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From b871895b148256f1721bc565d803860242755a0b Mon Sep 17 00:00:00 2001
From: Nicholas Piggin <[email protected]>
Date: Fri, 3 Sep 2021 22:57:06 +1000
Subject: [PATCH] powerpc/64s: system call scv tabort fix for corrupt irq
soft-mask state
If a system call is made with a transaction active, the kernel immediately aborts it and returns. scv system calls disable irqs even earlier in their interrupt handler, and tabort_syscall does not fix this up.
This can result in irq soft-mask state being messed up on the next kernel entry, and crashing at BUG_ON(arch_irq_disabled_regs(regs)) in the kernel exit handlers, or possibly worse.
This can't easily be fixed in asm because at this point an async irq may have hit, which is soft-masked and marked pending. The pending interrupt has to be replayed before returning to userspace. The fix is to move the tabort_syscall code to C in the main syscall handler, and just skip the system call but otherwise return as usual, which will take care of the pending irqs. This also does a bunch of other things including possible signal delivery to the process, but the doomed transaction should still be aborted when it is eventually returned to.
The sc system call path is changed to use the new C function as well to reduce code and path differences. This slows down how quickly system calls are aborted when called while a transaction is active, which could potentially impact TM performance. But making any system call is already bad for performance, and TM is on the way out, so go with simpler over faster.
arch/powerpc/kernel/interrupt.c +30 -0
@@ -18,6 +18,7 @@#include <asm/switch_to.h> #include <asm/syscall.h> #include <asm/time.h> +#include <asm/tm.h> #include <asm/unistd.h> #if defined(CONFIG_PPC_ADV_DEBUG_REGS ) && defined(CONFIG_PPC32 )
@@ -136,6 +137,35 @@ notrace long system_call_exception(long r3, long r4, long r5,*/ irq_soft_mask_regs_set_state (regs,IRQS_ENABLED ); +/* +* If the system call was made with a transaction active, doom it and +* return without performing the system call. Unless it was an +* unsupported scv vector, in which case it's treated like an illegal +* instruction. +*/ +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +if (unlikely (MSR_TM_TRANSACTIONAL (regs->msr)) && + !trap_is_unsupported_scv (regs)) { +/* Enable TM in the kernel, and disable EE (for scv) */ +hard_irq_disable (); +mtmsr (mfmsr () |MSR_TM ); + +/* tabort, this dooms the transaction, nothing else */ + asmvolatile (".long 0x7c00071d | ((%0) << 16)" + ::"r" (TM_CAUSE_SYSCALL |TM_CAUSE_PERSISTENT )); + +/* +* Userspace will never see the return value. Execution will +* resume after the tbegin. of the aborted transaction with the +* checkpointed register state. A context switch could occur +* or signal delivered to the process before resuming the +* doomed transaction context, but that should all be handled +* as expected. +*/ +return -ENOSYS ; + } +#endif // CONFIG_PPC_TRANSACTIONAL_MEM +local_irq_enable ();if (unlikely (current_thread_info ()->flags & _TIF_SYSCALL_DOTRACE)) {
arch/powerpc/kernel/interrupt_64.S +0 -41
65 lines not on this page · raw message