From patchwork Tue Jun 28 15:12:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 12898459 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 1638FC43334 for ; Tue, 28 Jun 2022 15:14:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=S6wQoaIDy6uuOfljheYiLFJEL2WhWhVqqsTDznIb20o=; b=oYo9+IAb6AkCme ZzAbFFpJtLQ3GvsMUpQM4oZiHzFM/TKs7lD5yeInxToPxAEx/x+9vOOMKc66CQnqLHCVnfibifo9t eTb7Cs3eKFIwtgu+otv0rNKWxzRr0bQv/lwHuzXQ0RVgm6sJKnDGwXrDSdbHy0ElkqbpHg+Md0pfs VQk0wRUaq29T0EfjLGwvERIZHidhheBKEcFDl5qvoXUmGUxdqs8klwpJIiQrNCFXX3nKOn2vuAPJP wbtr2Dyv29PDi7jZJyyd8yefbKOw2i8VFMSsdqs7MBRxEmkCc068EdjRw99Lx8SxftYenT19oZSBJ Jz1fsycXQafqObp3FSZA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o6Cty-006paa-1y; Tue, 28 Jun 2022 15:13:18 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o6Ctu-006pa0-8n for linux-arm-kernel@lists.infradead.org; Tue, 28 Jun 2022 15:13:15 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 28490B81E39; Tue, 28 Jun 2022 15:13:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8247DC3411D; Tue, 28 Jun 2022 15:13:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1656429190; bh=FPWKhxksykPqrm5K5pUo6WtVBcbCDsVOuIp4w6S2pFs=; h=From:To:Cc:Subject:Date:From; b=glzWtcHWlQOlR3r8Fj2rNX60tqwrOq+LHGSQ0Ksv6c+l/Whstqzi/QG1TKIR9Vdp5 IiIvjwAp3hNz5IoK8lIi0xK+U9H8ody+7vy2SEq6PCTTYho4nLWEq2HCG9zRrDgtQY pMZ45uwt/strnDD9TDZJNg6NMQwD7xbrUd1rMnnZDeaKNav+dcxrJ4c96PaebR4Qkk hTHIAcRBz/6Abc/50p9iC90Sq3vi2sPeHZEdDP8Zy6N1BwMgQpk/6CVzQzUVxb7r7Y vHdfRpX5heSzcVAQQYdgAZ2jruDZeluiYBtiZ30xcMfIfonwcuYL6hq3aleYOdtRXv KMdB8IDb5IqxA== From: Ard Biesheuvel To: linux@armlinux.org.uk Cc: linux-arm-kernel@lists.infradead.org, arnd@arndb.de, linus.walleij@linaro.org, Ard Biesheuvel , stable@vger.kernel.org Subject: [PATCH] ARM: alignment: advance IT state after emulating Thumb instruction Date: Tue, 28 Jun 2022 17:12:58 +0200 Message-Id: <20220628151258.2582737-1-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3641; h=from:subject; bh=FPWKhxksykPqrm5K5pUo6WtVBcbCDsVOuIp4w6S2pFs=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBiuxp2W3SFe6l7FbglahXmCUO4T5/GZimwb6Lt+Veu x956liCJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYrsadgAKCRDDTyI5ktmPJHThC/ 4ysWl5fJkI7CBELsQ4ELK47sYlgdaG8TGnqhtqn+BBXoBP3r0KQLTK9I+qyeCTv33K/HoN68aOxpIf oL6swrbIUCRD9BbQobA8Eg/mocrE8yAb5+qCuj8fMmD/P1Jkid8ONdsuTux9JXY6jooEv5rDPQmSTm pVmfPAWOJZOO36D4jvNlWLIN0S8+yyk2hR0Pqnbw5aJWfqrGHvAQqY1Iw46pIp5/wj0uNs3/sK3O7z 6oY26LzGvr5VnkRJLcIlLv4QSco3qh2IvuWWF4D11g7ynEgQPweBfiGB0J4R+yYxk7KKRbFC2T9Ttp ri8//xYJ+z3sga5QXH7UNMoLrkT9iTkhr1iokjqq/uaDbDwSAesZm4aYAf1M2I5J/P1rpEOJ7u5Rr2 AlCaI8V3t4RUNnH3YDU9ftq/HTbHregDDR0bmmH/sOTD0NNQdLuDPeo/3fL1UVxdK6Y9sIdvot5+ix W6b2qJAskoq9cImjqa/0jCWLWdQ1UH1bFYB1VKx+B0SbI= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220628_081314_638253_C3201B00 X-CRM114-Status: GOOD ( 20.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org After emulating a misaligned load or store issued in Thumb mode, we have to advance the IT state by hand, or it will get out of sync with the actual instruction stream, which means we'll end up applying the wrong condition code to subsequent instructions. This might corrupt the program state rather catastrophically. So borrow the it_advance() helper from the probing code, and use it on CPSR if the emulated instruction is Thumb. Cc: Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij --- arch/arm/include/asm/ptrace.h | 26 ++++++++++++++++++++++++++ arch/arm/mm/alignment.c | 3 +++ arch/arm/probes/decode.h | 26 +------------------------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 93051e2f402c..1408a6a15d0e 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -163,5 +163,31 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs) ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \ }) + +/* + * Update ITSTATE after normal execution of an IT block instruction. + * + * The 8 IT state bits are split into two parts in CPSR: + * ITSTATE<1:0> are in CPSR<26:25> + * ITSTATE<7:2> are in CPSR<15:10> + */ +static inline unsigned long it_advance(unsigned long cpsr) +{ + if ((cpsr & 0x06000400) == 0) { + /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ + cpsr &= ~PSR_IT_MASK; + } else { + /* We need to shift left ITSTATE<4:0> */ + const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ + unsigned long it = cpsr & mask; + it <<= 1; + it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ + it &= mask; + cpsr &= ~mask; + cpsr |= it; + } + return cpsr; +} + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 6f499559d193..f8dd0b3cc8e0 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -935,6 +935,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (type == TYPE_LDST) do_alignment_finish_ldst(addr, instr, regs, offset); + if (thumb_mode(regs)) + regs->ARM_cpsr = it_advance(regs->ARM_cpsr); + return 0; bad_or_fault: diff --git a/arch/arm/probes/decode.h b/arch/arm/probes/decode.h index 973173598992..facc889d05ee 100644 --- a/arch/arm/probes/decode.h +++ b/arch/arm/probes/decode.h @@ -14,6 +14,7 @@ #include #include #include +#include #include void __init arm_probes_decode_init(void); @@ -35,31 +36,6 @@ void __init find_str_pc_offset(void); #endif -/* - * Update ITSTATE after normal execution of an IT block instruction. - * - * The 8 IT state bits are split into two parts in CPSR: - * ITSTATE<1:0> are in CPSR<26:25> - * ITSTATE<7:2> are in CPSR<15:10> - */ -static inline unsigned long it_advance(unsigned long cpsr) - { - if ((cpsr & 0x06000400) == 0) { - /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ - cpsr &= ~PSR_IT_MASK; - } else { - /* We need to shift left ITSTATE<4:0> */ - const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ - unsigned long it = cpsr & mask; - it <<= 1; - it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ - it &= mask; - cpsr &= ~mask; - cpsr |= it; - } - return cpsr; -} - static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) { long cpsr = regs->ARM_cpsr;