* [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state
@ 2021-09-03 12:57 Nicholas Piggin
2021-09-03 12:57 ` [PATCH v3 2/2] selftests/powerpc: Add scv versions of the basic TM syscall tests Nicholas Piggin
2021-09-19 12:20 ` [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Michael Ellerman
0 siblings, 2 replies; 4+ messages in thread
From: Nicholas Piggin @ 2021-09-03 12:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Eirik Fuller, Nicholas Piggin
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.
Reported-by: Eirik Fuller <efuller@redhat.com>
Fixes: 7fa95f9adaee7 ("powerpc/64s: system call support for scv/rfscv instructions")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
v2 of this fix had a bug where an irq could be soft masked and pending
before we hard disable interrupts in tabort_syscall for the case of
scv (because it enters the kernel with EE enabled). So this actually
requires a pretty large change to fix because we can't replay interrupts
just from this early asm context.
Thanks,
Nick
arch/powerpc/kernel/interrupt.c | 29 +++++++++++++++++++++
arch/powerpc/kernel/interrupt_64.S | 41 ------------------------------
2 files changed, 29 insertions(+), 41 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 21bbd615ca41..c77c80214ad3 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -19,6 +19,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)
@@ -138,6 +139,34 @@ 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.
+ */
+ if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
+ 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 */
+ asm volatile(".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;
+ }
+
local_irq_enable();
if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index d4212d2ff0b5..ec950b08a8dc 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -12,7 +12,6 @@
#include <asm/mmu.h>
#include <asm/ppc_asm.h>
#include <asm/ptrace.h>
-#include <asm/tm.h>
.section ".toc","aw"
SYS_CALL_TABLE:
@@ -55,12 +54,6 @@ COMPAT_SYS_CALL_TABLE:
.globl system_call_vectored_\name
system_call_vectored_\name:
_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-BEGIN_FTR_SECTION
- extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
- bne tabort_syscall
-END_FTR_SECTION_IFSET(CPU_FTR_TM)
-#endif
SCV_INTERRUPT_TO_KERNEL
mr r10,r1
ld r1,PACAKSAVE(r13)
@@ -247,12 +240,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_common_real)
.globl system_call_common
system_call_common:
_ASM_NOKPROBE_SYMBOL(system_call_common)
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-BEGIN_FTR_SECTION
- extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
- bne tabort_syscall
-END_FTR_SECTION_IFSET(CPU_FTR_TM)
-#endif
mr r10,r1
ld r1,PACAKSAVE(r13)
std r10,0(r1)
@@ -425,34 +412,6 @@ SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
#endif
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-tabort_syscall:
-_ASM_NOKPROBE_SYMBOL(tabort_syscall)
- /* Firstly we need to enable TM in the kernel */
- mfmsr r10
- li r9, 1
- rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG
- mtmsrd r10, 0
-
- /* tabort, this dooms the transaction, nothing else */
- li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
- TABORT(R9)
-
- /*
- * Return directly to userspace. We have corrupted user register state,
- * but userspace will never see that register state. Execution will
- * resume after the tbegin of the aborted transaction with the
- * checkpointed register state.
- */
- li r9, MSR_RI
- andc r10, r10, r9
- mtmsrd r10, 1
- mtspr SPRN_SRR0, r11
- mtspr SPRN_SRR1, r12
- RFI_TO_USER
- b . /* prevent speculative execution */
-#endif
-
/*
* If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
* touched, no exit work created, then this can be used.
--
2.23.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v3 2/2] selftests/powerpc: Add scv versions of the basic TM syscall tests
2021-09-03 12:57 [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Nicholas Piggin
@ 2021-09-03 12:57 ` Nicholas Piggin
2021-09-19 12:20 ` [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Michael Ellerman
1 sibling, 0 replies; 4+ messages in thread
From: Nicholas Piggin @ 2021-09-03 12:57 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Eirik Fuller, Nicholas Piggin
The basic TM vs syscall test code hard codes an sc instruction for the
system call, which fails to cover scv even when the userspace libc has
support for it.
Duplicate the tests with hard coded scv variants so both are tested
when possible.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
.../selftests/powerpc/tm/tm-syscall-asm.S | 32 ++++++++++++++++-
.../testing/selftests/powerpc/tm/tm-syscall.c | 36 +++++++++++++++----
2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S b/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
index bd1ca25febe4..e59e93aad2cf 100644
--- a/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#include <ppc-asm.h>
+#include <basic_asm.h>
#include <asm/unistd.h>
.text
@@ -26,3 +26,33 @@ FUNC_START(getppid_tm_suspended)
1:
li r3, -1
blr
+
+FUNC_START(getppid_scv_tm_active)
+ PUSH_BASIC_STACK(0)
+ tbegin.
+ beq 1f
+ li r0, __NR_getppid
+ scv 0
+ tend.
+ POP_BASIC_STACK(0)
+ blr
+1:
+ li r3, -1
+ POP_BASIC_STACK(0)
+ blr
+
+FUNC_START(getppid_scv_tm_suspended)
+ PUSH_BASIC_STACK(0)
+ tbegin.
+ beq 1f
+ li r0, __NR_getppid
+ tsuspend.
+ scv 0
+ tresume.
+ tend.
+ POP_BASIC_STACK(0)
+ blr
+1:
+ li r3, -1
+ POP_BASIC_STACK(0)
+ blr
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c
index becb8207b432..9a822208680e 100644
--- a/tools/testing/selftests/powerpc/tm/tm-syscall.c
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c
@@ -19,24 +19,37 @@
#include "utils.h"
#include "tm.h"
+#ifndef PPC_FEATURE2_SCV
+#define PPC_FEATURE2_SCV 0x00100000 /* scv syscall */
+#endif
+
extern int getppid_tm_active(void);
extern int getppid_tm_suspended(void);
+extern int getppid_scv_tm_active(void);
+extern int getppid_scv_tm_suspended(void);
unsigned retries = 0;
#define TEST_DURATION 10 /* seconds */
#define TM_RETRIES 100
-pid_t getppid_tm(bool suspend)
+pid_t getppid_tm(bool scv, bool suspend)
{
int i;
pid_t pid;
for (i = 0; i < TM_RETRIES; i++) {
- if (suspend)
- pid = getppid_tm_suspended();
- else
- pid = getppid_tm_active();
+ if (suspend) {
+ if (scv)
+ pid = getppid_scv_tm_suspended();
+ else
+ pid = getppid_tm_suspended();
+ } else {
+ if (scv)
+ pid = getppid_scv_tm_active();
+ else
+ pid = getppid_tm_active();
+ }
if (pid >= 0)
return pid;
@@ -82,15 +95,24 @@ int tm_syscall(void)
* Test a syscall within a suspended transaction and verify
* that it succeeds.
*/
- FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
+ FAIL_IF(getppid_tm(false, true) == -1); /* Should succeed. */
/*
* Test a syscall within an active transaction and verify that
* it fails with the correct failure code.
*/
- FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
+ FAIL_IF(getppid_tm(false, false) != -1); /* Should fail... */
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
+
+ /* Now do it all again with scv if it is available. */
+ if (have_hwcap2(PPC_FEATURE2_SCV)) {
+ FAIL_IF(getppid_tm(true, true) == -1); /* Should succeed. */
+ FAIL_IF(getppid_tm(true, false) != -1); /* Should fail... */
+ FAIL_IF(!failure_is_persistent()); /* ...persistently... */
+ FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
+ }
+
gettimeofday(&now, 0);
}
--
2.23.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state
2021-09-03 12:57 [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Nicholas Piggin
2021-09-03 12:57 ` [PATCH v3 2/2] selftests/powerpc: Add scv versions of the basic TM syscall tests Nicholas Piggin
@ 2021-09-19 12:20 ` Michael Ellerman
1 sibling, 0 replies; 4+ messages in thread
From: Michael Ellerman @ 2021-09-19 12:20 UTC (permalink / raw)
To: linuxppc-dev, Nicholas Piggin; +Cc: Eirik Fuller
On Fri, 3 Sep 2021 22:57:06 +1000, Nicholas Piggin wrote:
> 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.
>
> [...]
Applied to powerpc/fixes.
[1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state
https://git.kernel.org/powerpc/c/b871895b148256f1721bc565d803860242755a0b
[2/2] selftests/powerpc: Add scv versions of the basic TM syscall tests
https://git.kernel.org/powerpc/c/5379ef2a60431232b9bb01c6d3580b875123d723
cheers
^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <202109040154.k1W0uBhG-lkp@intel.com>]
* Re: [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state
[not found] <202109040154.k1W0uBhG-lkp@intel.com>
@ 2021-09-13 7:51 ` kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-09-13 7:51 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Eirik Fuller, kbuild-all, Nicholas Piggin
[-- Attachment #1: Type: text/plain, Size: 4421 bytes --]
Please kindly note that this is a powerpc32 build.
Hi Nicholas,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v5.14 next-20210903]
[cannot apply to powerpc/next scottwood/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-system-call-scv-tabort-fix-for-corrupt-irq-soft-mask-state/20210903-205907
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a9c9a6f741cdaa2fa9ba24a790db8d07295761e3
:::::: branch date: 5 hours ago
:::::: commit date: 5 hours ago
config: powerpc-randconfig-s032-20210903 (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce:
cd linux
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O make.cross
chmod +x make.cross
# https://github.com/0day-ci/linux/commit/3510c8c0951ec7ac98da8d6931df7499ca6c881e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-64s-system-call-scv-tabort-fix-for-corrupt-irq-soft-mask-state/20210903-205907
git checkout 3510c8c0951ec7ac98da8d6931df7499ca6c881e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 ./make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from arch/powerpc/include/asm/processor.h:11,
from arch/powerpc/include/asm/thread_info.h:40,
from include/linux/thread_info.h:60,
from arch/powerpc/include/asm/ptrace.h:298,
from arch/powerpc/include/asm/hw_irq.h:12,
from arch/powerpc/include/asm/irqflags.h:12,
from include/linux/irqflags.h:16,
from include/asm-generic/cmpxchg-local.h:6,
from arch/powerpc/include/asm/cmpxchg.h:526,
from arch/powerpc/include/asm/atomic.h:11,
from include/linux/atomic.h:7,
from include/linux/rcupdate.h:25,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from include/linux/context_tracking.h:5,
from arch/powerpc/kernel/interrupt.c:3:
arch/powerpc/kernel/interrupt.c: In function 'system_call_exception':
>> arch/powerpc/include/asm/reg.h:66:29: error: left shift count >= width of type [-Werror=shift-count-overflow]
66 | #define __MASK(X) (1UL<<(X))
| ^~
arch/powerpc/include/asm/reg.h:1378:61: note: in definition of macro 'mtmsr'
1378 | : "r" ((unsigned long)(v)) \
| ^
arch/powerpc/include/asm/reg.h:115:25: note: in expansion of macro '__MASK'
115 | #define MSR_TM __MASK(MSR_TM_LG) /* Transactional Mem Available */
| ^~~~~~
arch/powerpc/kernel/interrupt.c:153:33: note: in expansion of macro 'MSR_TM'
153 | mtmsr(mfmsr() | MSR_TM);
| ^~~~~~
cc1: all warnings being treated as errors
vim +66 arch/powerpc/include/asm/reg.h
14cf11af6cf608 include/asm-powerpc/reg.h Paul Mackerras 2005-09-26 62
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 63 #ifdef __ASSEMBLY__
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 64 #define __MASK(X) (1<<(X))
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 65 #else
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 @66 #define __MASK(X) (1UL<<(X))
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 67 #endif
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 68
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26576 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-09-19 12:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-09-03 12:57 [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Nicholas Piggin
2021-09-03 12:57 ` [PATCH v3 2/2] selftests/powerpc: Add scv versions of the basic TM syscall tests Nicholas Piggin
2021-09-19 12:20 ` [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Michael Ellerman
[not found] <202109040154.k1W0uBhG-lkp@intel.com>
2021-09-13 7:51 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).