From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 03327CCFA02 for ; Sun, 2 Nov 2025 11:56:01 +0000 (UTC) Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4cztSs0yn2z3dVw; Sun, 2 Nov 2025 22:55:25 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1762084525; cv=none; b=SZmqIPSwOrivj6WM0W6tsL2IlHRwwx8apQZqfB+P0VF5ZHDMJDbfirpCAXREko4MNJu0JFYXs3vGbS6hW0iQvqsVU1LKqbC4CrLVJwXOMWv4OlBNeHJBB47TXMVA8w5stbocdK47DJCOo9WjJWdCM1kiH3fL1NtJDy1dNBj/XBfWV2tATe4ffJA7xpe9cgCBFWaYnKdlu6iH5/4xH1gAJXYnNa7jCfrHhj7Pm7uEL8aDyrqe25khgvr5zgnC0Eyn6KBafpcUzopsKKywQIkL2znyeDbUmTwIOIO6dz7FJk7RCCJribI71UXl4nVPNjRyb9oZw7H0xkIGenvh9D4v5g== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1762084525; c=relaxed/relaxed; bh=sHt0ipptftn4r9vnO4mrjC1oTX2qXQX3fcc0g3+Qf48=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HIdYPxpddhkJ8ScqDkB1WlbC8ObU+zI3MRYVXqYncNTZoH+dFCilFidx+sqBzIzkX/lUURp+wEZY/y1TGuTbOD0eH9cBDBes4gTZSAHpL8jatiV6lt8BHELEawQIIp3kNd9E0dv3Baqt5k+wREpwCxiDaMn64kx31YzmofDFxDqpL+D5KaoPERFjDCHnkdzPQ4YSdwuAsU4LprH5JSh3YOR9pnqp2hEX7qa/3w6j5qwbUfEQ/MgJrjgvAf53KbtbAfB5JESVa5bcQqhv9A1wRM6KBwBL6vN0su2Z/3yXAN84Co2blMwRNchqCKHmzScK8zwAS86MnF9+6KH6rtX8Gg== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=RDFyNBCg; dkim-atps=neutral; spf=pass (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=mkchauras@linux.ibm.com; receiver=lists.ozlabs.org) smtp.mailfrom=linux.ibm.com Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=RDFyNBCg; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=mkchauras@linux.ibm.com; receiver=lists.ozlabs.org) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4cztSq6Kzmz3dV6 for ; Sun, 2 Nov 2025 22:55:23 +1100 (AEDT) Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5A28eYIl026405; Sun, 2 Nov 2025 11:54:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=sHt0ipptftn4r9vnO 4mrjC1oTX2qXQX3fcc0g3+Qf48=; b=RDFyNBCgRqgBy/3mwQcyuwIFXFftA9fqb A5RtVEHKJlkd5O1ria9FVxwRJHIV4h1T9KcXGgnzbcaLKzs3tj5wkac8svWbC1KX o6/bMUsE6xYIkWsbDXqh/VdryJmpECYBw4eFK1V26JYZghPqWtAYQMQwkhvOL7BI PHL00jHoUc61754q0NlNz51ec/jFVHXxvI7i4ChA++C5o1nI+WR+LcrY4vhaADLz GafSF79+/Hcyqab4i6SeOM3FNCs9izFbmSFOlwXD+pyfkso+/WuZpg5yx3km4czU CLeslJWbB1tWVkRgrFp1LxgQHSKCH5EGCZpayMXVgZNA9+aEfYNBA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4a59vu3b4s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 02 Nov 2025 11:54:58 +0000 (GMT) Received: from m0353729.ppops.net (m0353729.ppops.net [127.0.0.1]) by pps.reinject (8.18.1.12/8.18.0.8) with ESMTP id 5A2BpDM7026732; Sun, 2 Nov 2025 11:54:58 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4a59vu3b4p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 02 Nov 2025 11:54:57 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 5A28e637009903; Sun, 2 Nov 2025 11:54:56 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4a5x1k1apt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 02 Nov 2025 11:54:56 +0000 Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 5A2BsqiV52363676 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 2 Nov 2025 11:54:52 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5409C20043; Sun, 2 Nov 2025 11:54:52 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 248CD20040; Sun, 2 Nov 2025 11:54:47 +0000 (GMT) Received: from li-ce33bfcc-25cf-11b2-a85c-dc105c39188e.ibm.com.com (unknown [9.124.213.75]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Sun, 2 Nov 2025 11:54:46 +0000 (GMT) From: Mukesh Kumar Chaurasiya To: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com, christophe.leroy@csgroup.eu, oleg@redhat.com, kees@kernel.org, luto@amacapital.net, wad@chromium.org, mchauras@linux.ibm.com, thuth@redhat.com, sshegde@linux.ibm.com, akpm@linux-foundation.org, macro@orcam.me.uk, ldv@strace.io, deller@gmx.de, charlie@rivosinc.com, bigeasy@linutronix.de, segher@kernel.crashing.org, thomas.weissschuh@linutronix.de, menglong8.dong@gmail.com, ankur.a.arora@oracle.com, peterz@infradead.org, namcao@linutronix.de, tglx@linutronix.de, kan.liang@linux.intel.com, mingo@kernel.org, atrajeev@linux.vnet.ibm.com, mark.barnett@arm.com, coltonlewis@google.com, rppt@kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH 8/8] powerpc: Enable Generic Entry/Exit for syscalls. Date: Sun, 2 Nov 2025 17:23:58 +0530 Message-ID: <20251102115358.1744304-9-mkchauras@linux.ibm.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251102115358.1744304-1-mkchauras@linux.ibm.com> References: <20251102115358.1744304-1-mkchauras@linux.ibm.com> X-Mailing-List: linuxppc-dev@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , List-Unsubscribe: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: AGWjPGkRmiAqmj_265yllrl6_6l09g1w X-Proofpoint-GUID: yyz7gAsNC4s_wBGwPXUk6j_ba_ykFcJr X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTAxMDAyMSBTYWx0ZWRfX184Peaaat5U6 vaJ4iIl+sKsKkpcBYpxTtaZ6eUYxSOYWWS2XG4co8EEUH2Z9t/E/hzyQ+Y917tWvZGRicnM/no6 6goIpbKF4/M56CIxM+kOx4Vk/LioVT+P26idNiiGvM1jMPFjj3FEveFH2c1CyoTMMAOFFOwWHCo kcykofiVt7CiDo97Nx9tx0N5dXaHy3zPhIU+88Oi4k8mqaDh7iBSyFmozwpICKuUUcWz8fyqzoS l23eDG9hk16xGtdcyRWLJhkCFWC4eEhKQdTA88NZK61VNzMiX/Y5mGTH9U1VeExoEV3iEd0ePSA F2hQpgt4H/fi7lXULYBtIRUvKdJbRXdF5h/BeNPCOIvJkm3LcR4uW1lru5B6OAKh7evDLjktVqY JmP5fu98tjcoi6UCkroVHJxS+B3gDA== X-Authority-Analysis: v=2.4 cv=U6qfzOru c=1 sm=1 tr=0 ts=69074692 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VnNF1IyMAAAA:8 a=hxrpC3j8_9yz7Jia3nEA:9 a=nl4s5V0KI7Kw-pW0DWrs:22 a=pHzHmUro8NiASowvMSCR:22 a=xoEH_sTeL_Rfw54TyV31:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-02_02,2025-10-29_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 impostorscore=0 spamscore=0 phishscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 suspectscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510240000 definitions=main-2511010021 From: Mukesh Kumar Chaurasiya Convert the PowerPC syscall entry and exit paths to use the generic entry/exit framework by selecting GENERIC_ENTRY and integrating with the common syscall handling routines. This change transitions PowerPC away from its custom syscall entry and exit code to use the generic helpers such as: - syscall_enter_from_user_mode() - syscall_exit_to_user_mode() As part of this migration: - The architecture now selects GENERIC_ENTRY in Kconfig. - Old tracing, seccomp, and audit handling in ptrace.c is removed in favor of generic entry infrastructure. - interrupt.c and syscall.c are simplified to delegate context management and user exit handling to the generic entry path. - The new pt_regs field `exit_flags` introduced earlier is now used to carry per-syscall exit state flags (e.g. _TIF_RESTOREALL). This aligns PowerPC with the common entry code used by other architectures and reduces duplicated logic around syscall tracing, context tracking, and signal handling. The performance benchmarks from perf bench basic syscall are below: | Metric | W/O Generic Framework | With Generic Framework | Change | | ---------- | --------------------- | ---------------------- | ------ | | Total time | 0.939 [sec] | 0.938 [sec] | ~0% | | usecs/op | 0.093900 | 0.093882 | ~0% | | ops/sec | 1,06,49,615 | 1,06,51,725 | ~0% | Thats very close to performance earlier with arch specific handling. Signed-off-by: Mukesh Kumar Chaurasiya --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/entry-common.h | 2 +- arch/powerpc/kernel/interrupt.c | 138 ++++++++--------------- arch/powerpc/kernel/ptrace/ptrace.c | 141 ------------------------ arch/powerpc/kernel/signal.c | 10 +- arch/powerpc/kernel/syscall.c | 119 +------------------- 6 files changed, 52 insertions(+), 359 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b0c602c3bbe1..a4330775b254 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -203,6 +203,7 @@ config PPC select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_VULNERABILITIES if PPC_BARRIER_NOSPEC select GENERIC_EARLY_IOREMAP + select GENERIC_ENTRY select GENERIC_GETTIMEOFDAY select GENERIC_IDLE_POLL_SETUP select GENERIC_IOREMAP diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h index e2ae7416dee1..466cfafc10ad 100644 --- a/arch/powerpc/include/asm/entry-common.h +++ b/arch/powerpc/include/asm/entry-common.h @@ -3,7 +3,7 @@ #ifndef _ASM_PPC_ENTRY_COMMON_H #define _ASM_PPC_ENTRY_COMMON_H -#ifdef CONFIG_GENERIC_IRQ_ENTRY +#ifdef CONFIG_GENERIC_ENTRY #include #include diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c index 7f67f0b9d627..ce59431f977c 100644 --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include #include @@ -73,79 +74,6 @@ static notrace __always_inline bool prep_irq_for_enabled_exit(bool restartable) return true; } -static notrace unsigned long -interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs) -{ - unsigned long ti_flags; - -again: - ti_flags = read_thread_flags(); - while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) { - local_irq_enable(); - if (ti_flags & (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY)) { - schedule(); - } else { - /* - * SIGPENDING must restore signal handler function - * argument GPRs, and some non-volatiles (e.g., r1). - * Restore all for now. This could be made lighter. - */ - if (ti_flags & _TIF_SIGPENDING) - ret |= _TIF_RESTOREALL; - do_notify_resume(regs, ti_flags); - } - local_irq_disable(); - ti_flags = read_thread_flags(); - } - - if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && IS_ENABLED(CONFIG_PPC_FPU)) { - if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && - unlikely((ti_flags & _TIF_RESTORE_TM))) { - restore_tm_state(regs); - } else { - unsigned long mathflags = MSR_FP; - - if (cpu_has_feature(CPU_FTR_VSX)) - mathflags |= MSR_VEC | MSR_VSX; - else if (cpu_has_feature(CPU_FTR_ALTIVEC)) - mathflags |= MSR_VEC; - - /* - * If userspace MSR has all available FP bits set, - * then they are live and no need to restore. If not, - * it means the regs were given up and restore_math - * may decide to restore them (to avoid taking an FP - * fault). - */ - if ((regs->msr & mathflags) != mathflags) - restore_math(regs); - } - } - - check_return_regs_valid(regs); - - user_enter_irqoff(); - if (!prep_irq_for_enabled_exit(true)) { - user_exit_irqoff(); - local_irq_enable(); - local_irq_disable(); - goto again; - } - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - local_paca->tm_scratch = regs->msr; -#endif - - booke_load_dbcr0(); - - account_cpu_user_exit(); - - /* Restore user access locks last */ - kuap_user_restore(regs); - - return ret; -} - /* * This should be called after a syscall returns, with r3 the return value * from the syscall. If this function returns non-zero, the system call @@ -160,17 +88,12 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, long scv) { unsigned long ti_flags; - unsigned long ret = 0; bool is_not_scv = !IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !scv; - CT_WARN_ON(ct_state() == CT_STATE_USER); - kuap_assert_locked(); regs->result = r3; - - /* Check whether the syscall is issued inside a restartable sequence */ - rseq_syscall(regs); + regs->exit_flags = 0; ti_flags = read_thread_flags(); @@ -183,7 +106,7 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, if (unlikely(ti_flags & _TIF_PERSYSCALL_MASK)) { if (ti_flags & _TIF_RESTOREALL) - ret = _TIF_RESTOREALL; + regs->exit_flags = _TIF_RESTOREALL; else regs->gpr[3] = r3; clear_bits(_TIF_PERSYSCALL_MASK, ¤t_thread_info()->flags); @@ -192,18 +115,28 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, } if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) { - do_syscall_trace_leave(regs); - ret |= _TIF_RESTOREALL; + regs->exit_flags |= _TIF_RESTOREALL; } - local_irq_disable(); - ret = interrupt_exit_user_prepare_main(ret, regs); +again: + syscall_exit_to_user_mode(regs); + + user_enter_irqoff(); + if (!prep_irq_for_enabled_exit(true)) { + user_exit_irqoff(); + local_irq_enable(); + local_irq_disable(); + goto again; + } + + /* Restore user access locks last */ + kuap_user_restore(regs); #ifdef CONFIG_PPC64 - regs->exit_result = ret; + regs->exit_result = regs->exit_flags; #endif - return ret; + return regs->exit_flags; } #ifdef CONFIG_PPC64 @@ -222,14 +155,18 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg #ifdef CONFIG_PPC_BOOK3S_64 set_kuap(AMR_KUAP_BLOCKED); #endif +again: + syscall_exit_to_user_mode(regs); - trace_hardirqs_off(); - user_exit_irqoff(); - account_cpu_user_entry(); - - BUG_ON(!user_mode(regs)); + user_enter_irqoff(); + if (!prep_irq_for_enabled_exit(true)) { + user_exit_irqoff(); + local_irq_enable(); + local_irq_disable(); + goto again; + } - regs->exit_result = interrupt_exit_user_prepare_main(regs->exit_result, regs); + regs->exit_result |= regs->exit_flags; return regs->exit_result; } @@ -250,8 +187,23 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs) kuap_assert_locked(); local_irq_disable(); + regs->exit_flags = 0; +again: + irqentry_exit_to_user_mode(regs); + check_return_regs_valid(regs); + + user_enter_irqoff(); + if (!prep_irq_for_enabled_exit(true)) { + user_exit_irqoff(); + local_irq_enable(); + local_irq_disable(); + goto again; + } + + /* Restore user access locks last */ + kuap_user_restore(regs); - ret = interrupt_exit_user_prepare_main(0, regs); + ret = regs->exit_flags; #ifdef CONFIG_PPC64 regs->exit_result = ret; diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index 2134b6d155ff..316d4f5ead8e 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -21,9 +21,6 @@ #include #include -#define CREATE_TRACE_POINTS -#include - #include "ptrace-decl.h" /* @@ -195,144 +192,6 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -#ifdef CONFIG_SECCOMP -static int do_seccomp(struct pt_regs *regs) -{ - if (!test_thread_flag(TIF_SECCOMP)) - return 0; - - /* - * The ABI we present to seccomp tracers is that r3 contains - * the syscall return value and orig_gpr3 contains the first - * syscall parameter. This is different to the ptrace ABI where - * both r3 and orig_gpr3 contain the first syscall parameter. - */ - regs->gpr[3] = -ENOSYS; - - /* - * We use the __ version here because we have already checked - * TIF_SECCOMP. If this fails, there is nothing left to do, we - * have already loaded -ENOSYS into r3, or seccomp has put - * something else in r3 (via SECCOMP_RET_ERRNO/TRACE). - */ - if (__secure_computing()) - return -1; - - /* - * The syscall was allowed by seccomp, restore the register - * state to what audit expects. - * Note that we use orig_gpr3, which means a seccomp tracer can - * modify the first syscall parameter (in orig_gpr3) and also - * allow the syscall to proceed. - */ - regs->gpr[3] = regs->orig_gpr3; - - return 0; -} -#else -static inline int do_seccomp(struct pt_regs *regs) { return 0; } -#endif /* CONFIG_SECCOMP */ - -/** - * do_syscall_trace_enter() - Do syscall tracing on kernel entry. - * @regs: the pt_regs of the task to trace (current) - * - * Performs various types of tracing on syscall entry. This includes seccomp, - * ptrace, syscall tracepoints and audit. - * - * The pt_regs are potentially visible to userspace via ptrace, so their - * contents is ABI. - * - * One or more of the tracers may modify the contents of pt_regs, in particular - * to modify arguments or even the syscall number itself. - * - * It's also possible that a tracer can choose to reject the system call. In - * that case this function will return an illegal syscall number, and will put - * an appropriate return value in regs->r3. - * - * Return: the (possibly changed) syscall number. - */ -long do_syscall_trace_enter(struct pt_regs *regs) -{ - u32 flags; - - flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); - - if (flags) { - int rc = ptrace_report_syscall_entry(regs); - - if (unlikely(flags & _TIF_SYSCALL_EMU)) { - /* - * A nonzero return code from - * ptrace_report_syscall_entry() tells us to prevent - * the syscall execution, but we are not going to - * execute it anyway. - * - * Returning -1 will skip the syscall execution. We want - * to avoid clobbering any registers, so we don't goto - * the skip label below. - */ - return -1; - } - - if (rc) { - /* - * The tracer decided to abort the syscall. Note that - * the tracer may also just change regs->gpr[0] to an - * invalid syscall number, that is handled below on the - * exit path. - */ - goto skip; - } - } - - /* Run seccomp after ptrace; allow it to set gpr[3]. */ - if (do_seccomp(regs)) - return -1; - - /* Avoid trace and audit when syscall is invalid. */ - if (regs->gpr[0] >= NR_syscalls) - goto skip; - - if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_enter(regs, regs->gpr[0]); - - if (!is_32bit_task()) - audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4], - regs->gpr[5], regs->gpr[6]); - else - audit_syscall_entry(regs->gpr[0], - regs->gpr[3] & 0xffffffff, - regs->gpr[4] & 0xffffffff, - regs->gpr[5] & 0xffffffff, - regs->gpr[6] & 0xffffffff); - - /* Return the possibly modified but valid syscall number */ - return regs->gpr[0]; - -skip: - /* - * If we are aborting explicitly, or if the syscall number is - * now invalid, set the return value to -ENOSYS. - */ - regs->gpr[3] = -ENOSYS; - return -1; -} - -void do_syscall_trace_leave(struct pt_regs *regs) -{ - int step; - - audit_syscall_exit(regs); - - if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_exit(regs, regs->result); - - step = test_thread_flag(TIF_SINGLESTEP); - if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - ptrace_report_syscall_exit(regs, step); -} - void __init pt_regs_check(void); /* diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 719930cf4ae1..9f1847b4742e 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -6,6 +6,7 @@ * Extracted from signal_32.c and signal_64.c */ +#include #include #include #include @@ -22,11 +23,6 @@ #include "signal.h" -/* This will be removed */ -#ifdef CONFIG_GENERIC_ENTRY -#include -#endif /* CONFIG_GENERIC_ENTRY */ - #ifdef CONFIG_VSX unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task) @@ -374,11 +370,9 @@ void signal_fault(struct task_struct *tsk, struct pt_regs *regs, task_pid_nr(tsk), where, ptr, regs->nip, regs->link); } -#ifdef CONFIG_GENERIC_ENTRY void arch_do_signal_or_restart(struct pt_regs *regs) { BUG_ON(regs != current->thread.regs); - local_paca->generic_fw_flags |= GFW_RESTORE_ALL; + regs->exit_flags |= _TIF_RESTOREALL; do_signal(current); } -#endif /* CONFIG_GENERIC_ENTRY */ diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/syscall.c index 9f03a6263fb4..df1c9a8d62bc 100644 --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -18,124 +19,10 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0) long ret; syscall_fn f; - kuap_lock(); - add_random_kstack_offset(); + r0 = syscall_enter_from_user_mode(regs, r0); - if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) - BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); - - trace_hardirqs_off(); /* finish reconciling */ - - CT_WARN_ON(ct_state() == CT_STATE_KERNEL); - user_exit_irqoff(); - - BUG_ON(regs_is_unrecoverable(regs)); - BUG_ON(!user_mode(regs)); - BUG_ON(regs_irqs_disabled(regs)); - -#ifdef CONFIG_PPC_PKEY - if (mmu_has_feature(MMU_FTR_PKEY)) { - unsigned long amr, iamr; - bool flush_needed = false; - /* - * When entering from userspace we mostly have the AMR/IAMR - * different from kernel default values. Hence don't compare. - */ - amr = mfspr(SPRN_AMR); - iamr = mfspr(SPRN_IAMR); - regs->amr = amr; - regs->iamr = iamr; - if (mmu_has_feature(MMU_FTR_KUAP)) { - mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); - flush_needed = true; - } - if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { - mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED); - flush_needed = true; - } - if (flush_needed) - isync(); - } else -#endif - kuap_assert_locked(); - - booke_restore_dbcr0(); - - account_cpu_user_entry(); - - account_stolen_time(); - - /* - * This is not required for the syscall exit path, but makes the - * stack frame look nicer. If this was initialised in the first stack - * frame, or if the unwinder was taught the first stack frame always - * returns to user with IRQS_ENABLED, this store could be avoided! - */ - irq_soft_mask_regs_set_state(regs, IRQS_ENABLED); - - /* - * If system call is called with TM active, set _TIF_RESTOREALL to - * prevent RFSCV being used to return to userspace, because POWER9 - * TM implementation has problems with this instruction returning to - * transactional state. Final register values are not relevant because - * the transaction will be aborted upon return anyway. Or in the case - * of unsupported_scv SIGILL fault, the return state does not much - * matter because it's an edge case. - */ - if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && - unlikely(MSR_TM_TRANSACTIONAL(regs->msr))) - set_bits(_TIF_RESTOREALL, ¤t_thread_info()->flags); - - /* - * 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(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) { - if (unlikely(trap_is_unsupported_scv(regs))) { - /* Unsupported scv vector */ - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - return regs->gpr[3]; - } - /* - * We use the return value of do_syscall_trace_enter() as the - * syscall number. If the syscall was rejected for any reason - * do_syscall_trace_enter() returns an invalid syscall number - * and the test against NR_syscalls will fail and the return - * value to be used is in regs->gpr[3]. - */ - r0 = do_syscall_trace_enter(regs); - if (unlikely(r0 >= NR_syscalls)) - return regs->gpr[3]; - - } else if (unlikely(r0 >= NR_syscalls)) { + if (unlikely(r0 >= NR_syscalls)) { if (unlikely(trap_is_unsupported_scv(regs))) { /* Unsupported scv vector */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); -- 2.51.0