From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794225937; b=hEQ1Hn6AJvlrR8PFutPSU4xju/EBa2qersXrCpbVkffjfAHfRSxasy8I2A6RQfCsHtq2 69K05Alu5LOLswiAz8oHIZmG6nFOQiUNiC4lO5b9drzkJxbC6ngRn3b7ydOdtMk3pwBGd nD+EGfnaZBk3sWiTDEILULKgLvh0/cM72MfR4Ws51yrRlTJlPAwDt0AlXrne2ukOfA4uB o3AcviPq9ljeIhrOTOuLFb2KcQJf4CwXQv0cDZmhxLKo7dsiaPGqG6z6W/jXMQmJBajrQ h61Kkv5Kj4kmP1G719tEUc9PtbxlhfpImYzCA+2WWSjLAQr/k+B1Q7pKtnt3P5hBjKw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794225937; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:Content-Transfer-Encoding; bh=mb6zscB9xA65zKWgADOGhrqsQ/nGHmGTb9eOGjPV3Qo=; b=R0Ir8GOsHKlYhNiGdz0P/4s0HHHv6rdLkS7rqOBpWZqt+msLernP+KorRygkpYw1FuE/ 1mEHMcbrboyMKoOezgvI5uEaSTlOQimqaqD7VhUF8Y8vvjG+ADykl5sza21p5y+UlB4F2 V6xjQ8JxZJELPT9iPFcCyKwU0wEGfM5jjcpRUoLmaeRdA9ugwMGjC2XTTcbp4wt3AGOjS eGwjBOT8CWa/C0DQLbXwkoDmyvr7Zh9KMZ78fQbCbzXBItvISgb6hg1aiqRMaNFsEjNbm 2qn+sCG1k3AbCQVj0si+omoLqVva9iVXVm8X/kDAZSkRsZf38WkFFfGn2/GJymnpVhw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=RfxHncTq; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C475C606A322 for ; Mon, 9 Nov 2026 12:05:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=RfxHncTq Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26BA01F008A3; Mon, 9 Nov 2026 12:05:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794225936; bh=mb6zscB9xA65zKWgADOGhrqsQ/nGHmGTb9eOGjPV3Qo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=RfxHncTqGmZ8TCef+6tWTgry+fmHYOt1r113jnwW6tvWLT75/HuVzVwwM0rnYytjo YPyJowg1fiHxzT8NeyDJYnOgIvo9zkbN16X/iwJFDxb9lkdl2UXbNfnJw7CsxuLAhO 6itAed9ea0+YQtKEGy/bcDnpws+CE01M/oVcdNG7IW4QzRZeB9b32E30RnzaeAy374 34I+0+Hf4xVLb7QfnBaxFyVBHwynjfKxOpio5H/vyMD4IrX5cBHysT5Oxprv0cPb0G tFmSopTnbOnb8IkL5sezYF0q18gOBkkkrTFV04DBcvb1lzGRBJEo09Nwql+8wY4Nmt Ogrx3vqVJ1xhQ== From: Jisheng Zhang To: Catalin Marinas , Will Deacon , Mark Rutland , Andrey Ryabinin , Alexander Potapenko , Andrey Konovalov , Dmitry Vyukov , Vincenzo Frascino , Tejun Heo , Dennis Zhou , Christoph Lameter Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org Subject: [PATCH v2 6/6] arm64: alternatives: Make branch and ADRP offset helpers noinst Date: Mon, 9 Nov 2026 19:44:59 +0800 Message-ID: <20261109114500.20298-7-jszhang@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261109114500.20298-1-jszhang@kernel.org> References: <20261109114500.20298-1-jszhang@kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit patch_alternative() must avoid instrumented code while alternatives are being modified, before cache maintenance completes. However, its branch and ADRP offset helpers are instrumentable. A GCC build with function tracing enabled emitted ftrace patchable entries for these helpers. Mark the four offset helpers noinstr. Introduce private __always_inline immediate encoding and decoding implementations for their use, and force inline the immediate mask helper. The offset helpers pass constant encoding types, allowing the compiler to eliminate invalid-type diagnostic paths. Keep the public immediate helpers as wrappers to preserve diagnostics for other callers. Signed-off-by: Jisheng Zhang Assisted-by: LLM --- arch/arm64/lib/insn.c | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c index e70ac0238515..b98610fcab32 100644 --- a/arch/arm64/lib/insn.c +++ b/arch/arm64/lib/insn.c @@ -21,7 +21,7 @@ #define AARCH64_INSN_N_BIT BIT(22) #define AARCH64_INSN_LSL_12 BIT(22) -static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type, +static __always_inline int aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type, u32 *maskp, int *shiftp) { u32 mask; @@ -86,7 +86,12 @@ static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type, #define ADR_IMM_LOSHIFT 29 #define ADR_IMM_HISHIFT 5 -u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) +/* + * Keep the immediate helpers inline so noinstr callers using constant encoding + * types do not call instrumentable code, including the invalid-type diagnostics. + */ +static __always_inline u64 +__aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) { u32 immlo, immhi, mask; int shift; @@ -101,8 +106,8 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) break; default: if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { - pr_err("%s: unknown immediate encoding %d\n", __func__, - type); + pr_err("%s: unknown immediate encoding %d\n", + "aarch64_insn_decode_immediate", type); return 0; } } @@ -110,8 +115,14 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) return (insn >> shift) & mask; } -u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, - u32 insn, u64 imm) +u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) +{ + return __aarch64_insn_decode_immediate(type, insn); +} + +static __always_inline u32 +__aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, + u32 insn, u64 imm) { u32 immlo, immhi, mask; int shift; @@ -131,8 +142,8 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, break; default: if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { - pr_err("%s: unknown immediate encoding %d\n", __func__, - type); + pr_err("%s: unknown immediate encoding %d\n", + "aarch64_insn_encode_immediate", type); return AARCH64_BREAK_FAULT; } } @@ -144,6 +155,12 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, return insn; } +u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, + u32 insn, u64 imm) +{ + return __aarch64_insn_encode_immediate(type, insn, imm); +} + u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type, u32 insn) { @@ -1299,23 +1316,23 @@ u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr, * signed value (so it can be used when computing a new branch * target). */ -s32 aarch64_get_branch_offset(u32 insn) +s32 noinstr aarch64_get_branch_offset(u32 insn) { s32 imm; if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) { - imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn); + imm = __aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn); return (imm << 6) >> 4; } if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || aarch64_insn_is_bcond(insn)) { - imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn); + imm = __aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn); return (imm << 13) >> 11; } if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) { - imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn); + imm = __aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn); return (imm << 18) >> 16; } @@ -1327,35 +1344,35 @@ s32 aarch64_get_branch_offset(u32 insn) * Encode the displacement of a branch in the imm field and return the * updated instruction. */ -u32 aarch64_set_branch_offset(u32 insn, s32 offset) +u32 noinstr aarch64_set_branch_offset(u32 insn, s32 offset) { if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) - return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, + return __aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, offset >> 2); if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || aarch64_insn_is_bcond(insn)) - return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, + return __aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, offset >> 2); if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) - return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn, + return __aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn, offset >> 2); /* Unhandled instruction */ BUG(); } -s32 aarch64_insn_adrp_get_offset(u32 insn) +s32 noinstr aarch64_insn_adrp_get_offset(u32 insn) { BUG_ON(!aarch64_insn_is_adrp(insn)); - return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12; + return __aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12; } -u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset) +u32 noinstr aarch64_insn_adrp_set_offset(u32 insn, s32 offset) { BUG_ON(!aarch64_insn_is_adrp(insn)); - return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, + return __aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset >> 12); } -- 2.55.0