Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp2353190pxb; Mon, 20 Sep 2021 19:51:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwaQA4OJmGnEIVdE2maRgLgkTy288G+Ohy0euuTlKFyRDCC5V0F8EV0TteAAx+Hqj3a0gar X-Received: by 2002:a05:6e02:b4e:: with SMTP id f14mr7886695ilu.172.1632192666248; Mon, 20 Sep 2021 19:51:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632192666; cv=none; d=google.com; s=arc-20160816; b=gUW8wPp8AJxRclfo6I58jMFEDmBLGEmW/bpC1uv3oUQw2ZThy27Cycz/p1CY2fPgM2 uAyhTKVHjPQsmP1jn3o7SB9jClhQKJslLD7bUy/s3gRzW3FvT8KmaSiJKuIoGxl6ViLG kmJej7oApE0bJam4/O2oBfR6lgscBuuvZXc/jjhPxSbzrQupEH2CsbNDw/PLm5j89zbo Xhg1sLWSdnJrcXfVVyG4Lgkk4b3f8dQkbkP6mzRRFfNufFI4dn/ddLWu2aGvXKD/fH/r j8EItlEjg5+w894UmDLPeS17K+pHofx0BnYdMVbhq5snJRuPcdtaNffShcA/lZ8R8U8h D6Pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=p90EmKuGM4zqZnoajsoWts1lBGjPflkPBVCskjtMjcw=; b=V8UCIhpJYkiT4vBqbxfburDss7qp4GGDNpcIrcK6KdwlvIfe8OT7l6lgTWk4+N0yBi aHfS5XFdAvizPT6dEPN4jfB/rDV7IEV2cnQnEYleeFzYomygtJSV7NWuzx1hnmCWy6dv Y2xvARjpZlgqP3ho0NvGf4fgqpk3MSY0q7LJf7wR2+G0wx2wmW31B72xtdlZyikhYfU7 SxD6KRG4aKVwCty3NtXITYXmkENM3HFWxw5E8Fpl/m5R961DnOwON9ukwtGYzF3An1nM aC30MtHP/MNQgTXRCefWy9HHfSk6Kjsr6QI28GpVIO8/f//2So+wg2qw7LquRVOjKjiz PkPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="iXgC/Qgd"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d7si13492089jaf.9.2021.09.20.19.50.55; Mon, 20 Sep 2021 19:51:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="iXgC/Qgd"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1383482AbhITSog (ORCPT + 99 others); Mon, 20 Sep 2021 14:44:36 -0400 Received: from mail.kernel.org ([198.145.29.99]:54226 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1382294AbhITSkR (ORCPT ); Mon, 20 Sep 2021 14:40:17 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3691F61502; Mon, 20 Sep 2021 17:30:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1632159059; bh=WaatLd0W3bb6F9P9z+w9hXiMrtEsDr9qfqz2Pcx+5sg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iXgC/QgddeBTzqeh7CyZpGjFL/g866ZvBiXp52HeuWiQbtgQHv6JGZghLJDFXNCW/ 2ldHlAeysXjPxN2OE2oA3tquAgaNzOf/M7rIlxxsLs1nFnoMENe7P8UdYhAhPKvfy4 GO0nw1S6k6hHoY4dk7uPysZR5S6Evo2yjfNb+WJc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eirik Fuller , Nicholas Piggin , Michael Ellerman Subject: [PATCH 5.14 056/168] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state Date: Mon, 20 Sep 2021 18:43:14 +0200 Message-Id: <20210920163923.480010777@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210920163921.633181900@linuxfoundation.org> References: <20210920163921.633181900@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Nicholas Piggin commit b871895b148256f1721bc565d803860242755a0b upstream. 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. Fixes: 7fa95f9adaee7 ("powerpc/64s: system call support for scv/rfscv instructions") Reported-by: Eirik Fuller Signed-off-by: Nicholas Piggin [mpe: Use #ifdef rather than IS_ENABLED() to fix build error on 32-bit] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210903125707.1601269-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/interrupt.c | 30 +++++++++++++++++++++++++++ arch/powerpc/kernel/interrupt_64.S | 41 ------------------------------------- 2 files changed, 30 insertions(+), 41 deletions(-) --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #if defined(CONFIG_PPC_ADV_DEBUG_REGS) && defined(CONFIG_PPC32) @@ -138,6 +139,35 @@ notrace long system_call_exception(long */ 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 */ + 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; + } +#endif // CONFIG_PPC_TRANSACTIONAL_MEM + local_irq_enable(); if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) { --- a/arch/powerpc/kernel/interrupt_64.S +++ b/arch/powerpc/kernel/interrupt_64.S @@ -12,7 +12,6 @@ #include #include #include -#include .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_ .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.