From nobody Sun May 10 09:53:16 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C697C433F5 for ; Fri, 13 May 2022 15:42:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234924AbiEMPmJ (ORCPT ); Fri, 13 May 2022 11:42:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234792AbiEMPmF (ORCPT ); Fri, 13 May 2022 11:42:05 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A22FD2409F for ; Fri, 13 May 2022 08:42:03 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id dk23so16993103ejb.8 for ; Fri, 13 May 2022 08:42:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gTvT1Njz7DvJoj6oJmGxwAJ3l74LLHxTpiRWi5YeMEs=; b=EcALLeSkYxkKn0Wiet+U+DUHYshlagRqJJCh+HvzSZcVLz7z8IA4NP2fUQJSYnCJpy M08vs5nu1mQftUPSfuHwVIfiSCia13X+PqKtF3OGygz4THbwXXcwlJjD6iPSELy1WDu8 5DG6v7UPYsfAWejFbDvJ1PUR5NPRrK5suSR48G0TGRUU8qNwQ82eMoWHMN8XAS8MDjDo Odc7x8+n2I4JW2juGndQuKmBrWFccLzYQUDBn5ii3DDZM0LdvvfF4gMYr0PXOBBPYe0P 5pf9JeGFRHon5uGvyTVgXJ7V8dvQSLT0cq9NkD3MX5lBljd/fPZpSCzdV4YfhHCR9JQC gbEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gTvT1Njz7DvJoj6oJmGxwAJ3l74LLHxTpiRWi5YeMEs=; b=ZM/htv0PHeSapQv8j7+jtw7hkjC5WBrwmVQuFcTqY2lmGH4k3tEpinZwb0Hy7pwfVa 8i7tks4yxVtkf4zL1UpBx4tmYhdEHi2Ki5uC3yZG0q9ZaRQFdJ51JwQAiR2QeDAlTm6D EDzY/NNV7V/I9nyoT3Dkck9WrJt2ErNHxiY/zIkDhNEvP996uW6zuMrDDNh1oviK+lht h5Kb1oe0Wud0il+QTGFa827wMzlmtXQ48Ox0uVV5BDJVPd2Cx4F/japAL7wyYVrpMzLL RWIru+FFOG1dWOE2Pk4405dFM2nC8QbnU1TuW9bs8DTbMa9yic9mTz8vmGK7+TFYq11s gwwg== X-Gm-Message-State: AOAM533PR8GN8WZNjGhM+QKR2pMwHLnPn1tFRWJTC4ZiK+gOEZPT/RtH m5Sd8fvxHMzOzumy8stkJKM= X-Google-Smtp-Source: ABdhPJz0Ht2W3NN/AnII61buYrRZgbAx8k4/SwrpaTpWaYlVv8nPqV9cCvl9HmYHcJwCOKWl/JjIKw== X-Received: by 2002:a17:906:6a16:b0:6f4:63ae:76c with SMTP id qw22-20020a1709066a1600b006f463ae076cmr4690738ejc.705.1652456522218; Fri, 13 May 2022 08:42:02 -0700 (PDT) Received: from octofox.metropolis ([178.134.103.46]) by smtp.gmail.com with ESMTPSA id h16-20020a1709066d9000b006f3ef214e73sm848313ejt.217.2022.05.13.08.42.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 May 2022 08:42:01 -0700 (PDT) From: Max Filippov To: linux-xtensa@linux-xtensa.org Cc: Chris Zankel , linux-kernel@vger.kernel.org, Max Filippov Subject: [PATCH 1/2] xtensa: add trap handler for division by zero Date: Fri, 13 May 2022 08:41:50 -0700 Message-Id: <20220513154151.4135905-2-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220513154151.4135905-1-jcmvbkbc@gmail.com> References: <20220513154151.4135905-1-jcmvbkbc@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add c-level handler for the division by zero exception and kill the task if it was thrown from the kernel space or send SIGFPE otherwise. Signed-off-by: Max Filippov --- arch/xtensa/kernel/traps.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index d3e91ceb0775..7c7c4c7b33bb 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -49,6 +49,7 @@ */ =20 static void do_illegal_instruction(struct pt_regs *regs); +static void do_div0(struct pt_regs *regs); static void do_interrupt(struct pt_regs *regs); #if XTENSA_FAKE_NMI static void do_nmi(struct pt_regs *regs); @@ -95,7 +96,7 @@ static dispatch_init_table_t __initdata dispatch_init_tab= le[] =3D { #ifdef SUPPORT_WINDOWED { EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, #endif -/* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ +{ EXCCAUSE_INTEGER_DIVIDE_BY_ZERO, 0, do_div0 }, /* EXCCAUSE_PRIVILEGED unhandled */ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION #ifdef CONFIG_XTENSA_UNALIGNED_USER @@ -307,6 +308,11 @@ static void do_illegal_instruction(struct pt_regs *reg= s) force_sig(SIGILL); } =20 +static void do_div0(struct pt_regs *regs) +{ + __die_if_kernel("Unhandled division by 0 in kernel", regs, SIGKILL); + force_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)regs->pc); +} =20 /* * Handle unaligned memory accesses from user space. Kill task. --=20 2.30.2 From nobody Sun May 10 09:53:16 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7440C433F5 for ; Fri, 13 May 2022 15:42:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1382161AbiEMPmS (ORCPT ); Fri, 13 May 2022 11:42:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234876AbiEMPmH (ORCPT ); Fri, 13 May 2022 11:42:07 -0400 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14C25BE21 for ; Fri, 13 May 2022 08:42:06 -0700 (PDT) Received: by mail-ej1-x62b.google.com with SMTP id i19so16970163eja.11 for ; Fri, 13 May 2022 08:42:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BOG74POVeYOfQY9afdarMF3mc0mDpcOp33/SYa9z2g4=; b=UvtK+9uXFFbJiEIXAG4TxrUr8xm6F/cK4VWAl7OwyGrIi1ROBFy+N+sMHRhWqU/+0l yF+0TlTr+37pRHCV1GZfzzUwxINR5QbfWpRTmdts4Wgy8shHcK9FbhtJ1RzR3iVucSL0 n6V8aw+UkKpK9BTfh8StIyAROhsejouLG5tZtjr+OfJC9lJXuNnR/5b/tL15D5ILZ3rx DpOj28rwvrg5UAm22hgOu9DkHyY2Pg+P52OccmCs7q5rEOepc/VC8jGSliAbWwRkXvSB LyY3ZVscMyXr0i8VCorGvS1ygKBxlEjWNE4pws1Cex+q8oq3Fg6Z2wQJjX/dGzKEQIKk B+ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BOG74POVeYOfQY9afdarMF3mc0mDpcOp33/SYa9z2g4=; b=oxPP3Q+zIUN00saHNQolQ7O2U4cWMpr8kSO5DjZlEb/hYPK8SCAwoM9yQTEIrbmrYc 1PyUbHcyikXbyP07jteVJFPKO5wdDVYsRdcdMVSR2yphrdK6NKd/yXnPGXawaMEdO6ai pgMeWlciznNYM4RBuNe4fwOkrYMDFlOQRxFp9xWYncFT6nIkUnM/5CdWYtG8JmO8vu0g mxLzI2tiK9+K2LH17df3cZRRKGdP25wiUQLQcqsPabrUUQo/ys07qxDwvaeeR0ZeNIQd abY5ul55S4NoDEhqarObIpTKHC1/l1p48wwWV8z4XhlCwEJo+a1UemqgNKIQZdPuvTYV bZeQ== X-Gm-Message-State: AOAM532hGmPyEosK+9ru4bqULcXbNbvRQmuu7rkv0WBzyTNCMsagmMic WWqUj+E7YrAJtLQTsqUqoj0= X-Google-Smtp-Source: ABdhPJxAwjcDm4BtYfBQSGIif62BWIgQHDEoMLu0Ig7Opo7ZT8E5W9XSJ198+zmltv+r4FP2nkilfQ== X-Received: by 2002:a17:906:4884:b0:6f3:a042:c1c6 with SMTP id v4-20020a170906488400b006f3a042c1c6mr4706002ejq.363.1652456523354; Fri, 13 May 2022 08:42:03 -0700 (PDT) Received: from octofox.metropolis ([178.134.103.46]) by smtp.gmail.com with ESMTPSA id h16-20020a1709066d9000b006f3ef214e73sm848313ejt.217.2022.05.13.08.42.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 May 2022 08:42:03 -0700 (PDT) From: Max Filippov To: linux-xtensa@linux-xtensa.org Cc: Chris Zankel , linux-kernel@vger.kernel.org, Max Filippov Subject: [PATCH 2/2] xtensa: support artificial division by 0 exception Date: Fri, 13 May 2022 08:41:51 -0700 Message-Id: <20220513154151.4135905-3-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220513154151.4135905-1-jcmvbkbc@gmail.com> References: <20220513154151.4135905-1-jcmvbkbc@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" On xtensa cores wihout hardware division option division support functions from libgcc react to division by 0 attempt by executing illegal instruction followed by the characters 'DIV0'. Recognize this pattern in illegal instruction exception handler and convert it to division by 0. When call0 userspace ABI support by probing is enabled instructions that cause illegal instruction exception when PS.WOE is clear are retried with PS.WOE set before calling c-level exception handler. Record user pc where PS.WOE was set in the fast exception handler and clear PS.WOE in the c-level exception handler if it was due to artificial division by 0. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/thread_info.h | 4 +++ arch/xtensa/kernel/asm-offsets.c | 3 ++ arch/xtensa/kernel/entry.S | 5 +++ arch/xtensa/kernel/traps.c | 45 +++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/as= m/thread_info.h index 52974317a6b6..326db1c1d5d8 100644 --- a/arch/xtensa/include/asm/thread_info.h +++ b/arch/xtensa/include/asm/thread_info.h @@ -56,6 +56,10 @@ struct thread_info { /* result of the most recent exclusive store */ unsigned long atomctl8; #endif +#ifdef CONFIG_USER_ABI_CALL0_PROBE + /* Address where PS.WOE was enabled by the ABI probing code */ + unsigned long ps_woe_fix_addr; +#endif =20 /* * If i-th bit is set then coprocessor state is loaded into the diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offs= ets.c index 9a1db6ffcbf4..da38de20ae59 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -88,6 +88,9 @@ int main(void) OFFSET(TI_STSTUS, thread_info, status); OFFSET(TI_CPU, thread_info, cpu); OFFSET(TI_PRE_COUNT, thread_info, preempt_count); +#ifdef CONFIG_USER_ABI_CALL0_PROBE + OFFSET(TI_PS_WOE_FIX_ADDR, thread_info, ps_woe_fix_addr); +#endif =20 /* struct thread_info (offset from start_struct) */ DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra)); diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 3224b4ceca34..e3eae648ba2e 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1056,6 +1056,11 @@ ENTRY(fast_illegal_instruction_user) movi a3, PS_WOE_MASK or a0, a0, a3 wsr a0, ps +#ifdef CONFIG_USER_ABI_CALL0_PROBE + GET_THREAD_INFO(a3, a2) + rsr a0, epc1 + s32i a0, a3, TI_PS_WOE_FIX_ADDR +#endif l32i a3, a2, PT_AREG3 l32i a0, a2, PT_AREG0 rsr a2, depc diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 7c7c4c7b33bb..d45dfa10be73 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -293,12 +293,57 @@ static void do_interrupt(struct pt_regs *regs) set_irq_regs(old_regs); } =20 +static int check_div0(struct pt_regs *regs) +{ +#if !XCHAL_HAVE_DIV32 + u8 buf[7]; + void *p; + static const u8 pattern1[] =3D {0, 0, 0, 'D', 'I', 'V', '0'}; +#if defined(__XTENSA_EB__) + static const u8 pattern2[] =3D {0xd6, 0x0f, 'D', 'I', 'V', '0'}; +#elif defined(__XTENSA_EL__) + static const u8 pattern2[] =3D {0x6d, 0xf0, 'D', 'I', 'V', '0'}; +#else +#error Unsupported Xtensa endianness +#endif + + if (user_mode(regs)) { + if (copy_from_user(buf, (void __user *)regs->pc, 7)) + return 0; + p =3D buf; + } else { + p =3D (void *)regs->pc; + } + + return memcmp(p, pattern1, sizeof(pattern1)) =3D=3D 0 || + memcmp(p, pattern2, sizeof(pattern2)) =3D=3D 0; +#else + return 0; +#endif +} + /* * Illegal instruction. Fatal if in kernel space. */ =20 static void do_illegal_instruction(struct pt_regs *regs) { + if (check_div0(regs)) { +#ifdef CONFIG_USER_ABI_CALL0_PROBE + /* + * When call0 application generates artificial division by 0 + * exception fast illegal instruction exception handler will + * attempt to set PS.WOE and retry failing instruction. + * We know that that illegal instruction was not related to + * windowed option so we clear PS.WOE here. + */ + if (regs->pc =3D=3D current_thread_info()->ps_woe_fix_addr) + regs->ps &=3D ~PS_WOE_MASK; +#endif + do_div0(regs); + return; + } + __die_if_kernel("Illegal instruction in kernel", regs, SIGKILL); =20 /* If in user mode, send SIGILL signal to current process. */ --=20 2.30.2