From nobody Tue Dec 16 16:39:00 2025 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 7E5BFCD98F5 for ; Wed, 11 Oct 2023 07:28:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345425AbjJKH2m (ORCPT ); Wed, 11 Oct 2023 03:28:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345231AbjJKH2L (ORCPT ); Wed, 11 Oct 2023 03:28:11 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8F2EFB for ; Wed, 11 Oct 2023 00:28:04 -0700 (PDT) Received: from kwepemi500008.china.huawei.com (unknown [172.30.72.54]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4S545L3GPGzLq7v; Wed, 11 Oct 2023 15:24:06 +0800 (CST) Received: from huawei.com (10.67.174.55) by kwepemi500008.china.huawei.com (7.221.188.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Wed, 11 Oct 2023 15:28:01 +0800 From: Jinjie Ruan To: , , , , , , , , , , , , , , , , , , CC: Subject: [PATCH v5.10 09/15] arm64: factor insn read out of call_undef_hook() Date: Wed, 11 Oct 2023 07:26:55 +0000 Message-ID: <20231011072701.876772-10-ruanjinjie@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231011072701.876772-1-ruanjinjie@huawei.com> References: <20231011072701.876772-1-ruanjinjie@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.67.174.55] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemi500008.china.huawei.com (7.221.188.139) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Mark Rutland Subsequent patches will rework EL0 UNDEF handling, removing the need for struct undef_hook and call_undef_hook. In preparation for those changes, this patch factors the logic for reading user instructions out of call_undef_hook() and into a new user_insn_read() helper, matching the style of the existing aarch64_insn_read() helper used for reading kernel instructions. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: James Morse Cc: Joey Gouly Cc: Peter Zijlstra Cc: Will Deacon Link: https://lore.kernel.org/r/20221019144123.612388-5-mark.rutland@arm.com Signed-off-by: Will Deacon --- arch/arm64/kernel/traps.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 15d490ef7462..be9c7bb89e98 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -303,25 +303,22 @@ void unregister_undef_hook(struct undef_hook *hook) raw_spin_unlock_irqrestore(&undef_lock, flags); } =20 -static int call_undef_hook(struct pt_regs *regs) +static int user_insn_read(struct pt_regs *regs, u32 *insnp) { - struct undef_hook *hook; - unsigned long flags; u32 instr; - int (*fn)(struct pt_regs *regs, u32 instr) =3D NULL; void __user *pc =3D (void __user *)instruction_pointer(regs); =20 if (compat_thumb_mode(regs)) { /* 16-bit Thumb instruction */ __le16 instr_le; if (get_user(instr_le, (__le16 __user *)pc)) - goto exit; + return -EFAULT; instr =3D le16_to_cpu(instr_le); if (aarch32_insn_is_wide(instr)) { u32 instr2; =20 if (get_user(instr_le, (__le16 __user *)(pc + 2))) - goto exit; + return -EFAULT; instr2 =3D le16_to_cpu(instr_le); instr =3D (instr << 16) | instr2; } @@ -329,10 +326,20 @@ static int call_undef_hook(struct pt_regs *regs) /* 32-bit ARM instruction */ __le32 instr_le; if (get_user(instr_le, (__le32 __user *)pc)) - goto exit; + return -EFAULT; instr =3D le32_to_cpu(instr_le); } =20 + *insnp =3D instr; + return 0; +} + +static int call_undef_hook(struct pt_regs *regs, u32 instr) +{ + struct undef_hook *hook; + unsigned long flags; + int (*fn)(struct pt_regs *regs, u32 instr) =3D NULL; + raw_spin_lock_irqsave(&undef_lock, flags); list_for_each_entry(hook, &undef_hook, node) if ((instr & hook->instr_mask) =3D=3D hook->instr_val && @@ -340,7 +347,7 @@ static int call_undef_hook(struct pt_regs *regs) fn =3D hook->fn; =20 raw_spin_unlock_irqrestore(&undef_lock, flags); -exit: + return fn ? fn(regs, instr) : 1; } =20 @@ -392,13 +399,19 @@ void arm64_notify_segfault(unsigned long addr) =20 void do_el0_undef(struct pt_regs *regs, unsigned long esr) { + u32 insn; + /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; =20 - if (call_undef_hook(regs) =3D=3D 0) + if (user_insn_read(regs, &insn)) + goto out_err; + + if (call_undef_hook(regs, insn) =3D=3D 0) return; =20 +out_err: force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); } =20 --=20 2.34.1