From nobody Thu Oct 2 03:36:21 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D44452BE65B for ; Tue, 23 Sep 2025 17:49:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758649778; cv=none; b=R5tFEk0/42RguptoyMk+EFO0y3G0dhl9IPuoUkkEQul8/3zyrBqoRArJNmWdWtztRjhfwMx6euZ9Bi22n3yvr/1cBb4EYAt4X5q10FUpSPvIqL5BE4uiTT3FMU1dqclJaZr5sAdFGBFn5p/fLqkq0fVlqfv7R+nRMFKZ34muhE0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758649778; c=relaxed/simple; bh=utee+C1D9MBTxnYgylcBivUsPRX2koBM0Ut2XMYDZkU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oHGg/J9VZlHVSbXrBkBEh92zENc9tyGtNxq9t0PWpCz/xPVury49EtuDBt1k1yOTVYbCeau90Je0sBbAnD6AkRI6+VIGaAIFwtLhCl8sDg3gvWgz9g5F+iKOuifgms2uzEH8ucajQxunxkWRnaMaM4LmiWr7YGQxu8FAw6/pg98= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5738B25E0; Tue, 23 Sep 2025 10:49:27 -0700 (PDT) Received: from e137867.cambridge.arm.com (e137867.arm.com [10.1.30.204]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DB98A3F5A1; Tue, 23 Sep 2025 10:49:31 -0700 (PDT) From: Ada Couprie Diaz To: linux-arm-kernel@lists.infradead.org Cc: Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Ard Biesheuvel , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, kasan-dev@googlegroups.com, Mark Rutland , Ada Couprie Diaz Subject: [RFC PATCH 05/16] arm64/insn: always inline aarch64_insn_encode_immediate() Date: Tue, 23 Sep 2025 18:48:52 +0100 Message-ID: <20250923174903.76283-6-ada.coupriediaz@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250923174903.76283-1-ada.coupriediaz@arm.com> References: <20250923174903.76283-1-ada.coupriediaz@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As type is passed dynamically at runtime we cannot check at compile time that is valid. However, in practice this should not happen and will still result in a fault BRK, so remove the error print. Pull `aarch64_get_imm_shift_mask()` in the header as well and make it `__always_inline` as it is needed for `aarch64_insn_encode_immediate()` and is already safe to inline. This is a change of visibility, so make sure to check the input pointers in case it is used in other places. Current callers do not care about -EINVAL, they just check for an error, so change the return to a boolean. This makes `aarch64_insn_encode_immediate()` safe for inlining and usage from patching callbacks. As both functions are now `__always_inline`, they do not need their `__kprobes` annotation anymore. Signed-off-by: Ada Couprie Diaz --- arch/arm64/include/asm/insn.h | 103 +++++++++++++++++++++++++++++++++- arch/arm64/lib/insn.c | 102 +-------------------------------- 2 files changed, 102 insertions(+), 103 deletions(-) diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 90f271483e5b..5f5f6a125b4e 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -9,6 +9,7 @@ #define __ASM_INSN_H #include #include +#include #include =20 #include @@ -555,10 +556,108 @@ static __always_inline bool aarch64_insn_uses_litera= l(u32 insn) aarch64_insn_is_prfm_lit(insn); } =20 +static __always_inline bool aarch64_get_imm_shift_mask( + enum aarch64_insn_imm_type type, u32 *maskp, int *shiftp) +{ + u32 mask; + int shift; + + if (maskp =3D=3D NULL || shiftp =3D=3D NULL) + return false; + + switch (type) { + case AARCH64_INSN_IMM_26: + mask =3D BIT(26) - 1; + shift =3D 0; + break; + case AARCH64_INSN_IMM_19: + mask =3D BIT(19) - 1; + shift =3D 5; + break; + case AARCH64_INSN_IMM_16: + mask =3D BIT(16) - 1; + shift =3D 5; + break; + case AARCH64_INSN_IMM_14: + mask =3D BIT(14) - 1; + shift =3D 5; + break; + case AARCH64_INSN_IMM_12: + mask =3D BIT(12) - 1; + shift =3D 10; + break; + case AARCH64_INSN_IMM_9: + mask =3D BIT(9) - 1; + shift =3D 12; + break; + case AARCH64_INSN_IMM_7: + mask =3D BIT(7) - 1; + shift =3D 15; + break; + case AARCH64_INSN_IMM_6: + case AARCH64_INSN_IMM_S: + mask =3D BIT(6) - 1; + shift =3D 10; + break; + case AARCH64_INSN_IMM_R: + mask =3D BIT(6) - 1; + shift =3D 16; + break; + case AARCH64_INSN_IMM_N: + mask =3D 1; + shift =3D 22; + break; + default: + return false; + } + + *maskp =3D mask; + *shiftp =3D shift; + + return true; +} + +#define ADR_IMM_HILOSPLIT 2 +#define ADR_IMM_SIZE SZ_2M +#define ADR_IMM_LOMASK ((1 << ADR_IMM_HILOSPLIT) - 1) +#define ADR_IMM_HIMASK ((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1) +#define ADR_IMM_LOSHIFT 29 +#define ADR_IMM_HISHIFT 5 + enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 ins= n); -u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, - u32 insn, u64 imm); + +static __always_inline u32 aarch64_insn_encode_immediate( + enum aarch64_insn_imm_type type, u32 insn, u64 imm) +{ + u32 immlo, immhi, mask; + int shift; + + if (insn =3D=3D AARCH64_BREAK_FAULT) + return AARCH64_BREAK_FAULT; + + switch (type) { + case AARCH64_INSN_IMM_ADR: + shift =3D 0; + immlo =3D (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT; + imm >>=3D ADR_IMM_HILOSPLIT; + immhi =3D (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT; + imm =3D immlo | immhi; + mask =3D ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) | + (ADR_IMM_HIMASK << ADR_IMM_HISHIFT)); + break; + default: + if (aarch64_get_imm_shift_mask(type, &mask, &shift) =3D=3D false) { + return AARCH64_BREAK_FAULT; + } + } + + /* Update the immediate field. */ + insn &=3D ~(mask << shift); + insn |=3D (imm & mask) << shift; + + return insn; +} static __always_inline u32 aarch64_insn_encode_register( enum aarch64_insn_register_type type, u32 insn, diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c index 1810e1ea64a7..d77aef7f84f1 100644 --- a/arch/arm64/lib/insn.c +++ b/arch/arm64/lib/insn.c @@ -13,7 +13,6 @@ #include =20 #include -#include #include #include =20 @@ -21,71 +20,6 @@ #define AARCH64_INSN_N_BIT BIT(22) #define AARCH64_INSN_LSL_12 BIT(22) =20 -static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type= type, - u32 *maskp, int *shiftp) -{ - u32 mask; - int shift; - - switch (type) { - case AARCH64_INSN_IMM_26: - mask =3D BIT(26) - 1; - shift =3D 0; - break; - case AARCH64_INSN_IMM_19: - mask =3D BIT(19) - 1; - shift =3D 5; - break; - case AARCH64_INSN_IMM_16: - mask =3D BIT(16) - 1; - shift =3D 5; - break; - case AARCH64_INSN_IMM_14: - mask =3D BIT(14) - 1; - shift =3D 5; - break; - case AARCH64_INSN_IMM_12: - mask =3D BIT(12) - 1; - shift =3D 10; - break; - case AARCH64_INSN_IMM_9: - mask =3D BIT(9) - 1; - shift =3D 12; - break; - case AARCH64_INSN_IMM_7: - mask =3D BIT(7) - 1; - shift =3D 15; - break; - case AARCH64_INSN_IMM_6: - case AARCH64_INSN_IMM_S: - mask =3D BIT(6) - 1; - shift =3D 10; - break; - case AARCH64_INSN_IMM_R: - mask =3D BIT(6) - 1; - shift =3D 16; - break; - case AARCH64_INSN_IMM_N: - mask =3D 1; - shift =3D 22; - break; - default: - return -EINVAL; - } - - *maskp =3D mask; - *shiftp =3D shift; - - return 0; -} - -#define ADR_IMM_HILOSPLIT 2 -#define ADR_IMM_SIZE SZ_2M -#define ADR_IMM_LOMASK ((1 << ADR_IMM_HILOSPLIT) - 1) -#define ADR_IMM_HIMASK ((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1) -#define ADR_IMM_LOSHIFT 29 -#define ADR_IMM_HISHIFT 5 - u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 ins= n) { u32 immlo, immhi, mask; @@ -100,7 +34,7 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_= type type, u32 insn) mask =3D ADR_IMM_SIZE - 1; break; default: - if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { + if (aarch64_get_imm_shift_mask(type, &mask, &shift) =3D=3D false) { pr_err("%s: unknown immediate encoding %d\n", __func__, type); return 0; @@ -110,40 +44,6 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm= _type type, u32 insn) return (insn >> shift) & mask; } =20 -u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type typ= e, - u32 insn, u64 imm) -{ - u32 immlo, immhi, mask; - int shift; - - if (insn =3D=3D AARCH64_BREAK_FAULT) - return AARCH64_BREAK_FAULT; - - switch (type) { - case AARCH64_INSN_IMM_ADR: - shift =3D 0; - immlo =3D (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT; - imm >>=3D ADR_IMM_HILOSPLIT; - immhi =3D (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT; - imm =3D immlo | immhi; - mask =3D ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) | - (ADR_IMM_HIMASK << ADR_IMM_HISHIFT)); - break; - default: - if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { - pr_err("%s: unknown immediate encoding %d\n", __func__, - type); - return AARCH64_BREAK_FAULT; - } - } - - /* Update the immediate field. */ - insn &=3D ~(mask << shift); - insn |=3D (imm & mask) << shift; - - return insn; -} - static const u32 aarch64_insn_ldst_size[] =3D { [AARCH64_INSN_SIZE_8] =3D 0, [AARCH64_INSN_SIZE_16] =3D 1, --=20 2.43.0