Received: by 2002:ab2:69cc:0:b0:1fd:c486:4f03 with SMTP id n12csp388344lqp; Tue, 11 Jun 2024 07:29:29 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXQzraBv6Dqco1MZrM3oB7MooWKIZ1tkH1goRQRIHt4NH3PBgpkGNYtbglxD3iDPjTsJGuaiWlzOl+VPn8yV1oAQnibPggZWq+K5fCKjQ== X-Google-Smtp-Source: AGHT+IEollXLqmVwkDamrtqEkjQ+p2R+fj/HcvIV/Ef9RFsrXkRPjxHHrnWMbzGbjyKm/juZ1Uw8 X-Received: by 2002:a17:90a:17ed:b0:2c3:cc7:5e34 with SMTP id 98e67ed59e1d1-2c30cc75ea3mr4648014a91.17.1718116169018; Tue, 11 Jun 2024 07:29:29 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718116169; cv=pass; d=google.com; s=arc-20160816; b=sBNg2z9GYDRb6QBK1cWZVW7Amp2UAZh4t4sVCl6K5UqY3vM/wqY2kZFywZQ3TMHUSB kK/jJ3UX981+ZeHT63ADO27zjqp5ZLM1l/ajj31toNqcFa5imSWyK12sah1j8BvHZAmA Oz7QwRVkTSwU2tiTRy6is+9dXoQbGvNOIbqgNp9gCYCb7QpA6XOYdHdwva4jweBe6KV3 O9IeJOWxRMptMyuqpRGyC2TxvYzOLLS7xclgahOka5aTvejfPaqA5xd0IlmmflNThdVx 4HvCcLf2lIONef61cvZN067FsDma7AGmmr3JCZeueBDm0cCN6paL7p/9r95ltmZFfvjJ ynnw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date; bh=SNJyphBely2uekQlNgGoJy4UcefMCBcmIqVSicHYgdM=; fh=pRn1dCCCDMYFjvWA3G+g8ETmqk49SnxJqcrd5w2g+yU=; b=ZlA3XDit009G0aWQF35ZeacysAEJBLhBsLxs2xHswOnO0Q+44KPmfdADOX2sKKpDD8 cUmpVG2mK4L4OjcYjRBlX731x7bsi5MlbL+zcJUb2EKQQuX6M1KyOQQeb2I+Lydd6uxn OypZfNsCZkuLnTOurv/GgXQ48F/Mx4fLtv56lVPOMGe8s/5vP2fb56yU6fSchHFEyZM6 Bd0jksNLUGP8BLNOFNt10RCrDnRd8MdNR74gyM1BEzuSODZHMQnSSCuWzcddsbpzqxmA p0PxK4LIDYy2lhO75kdrVxTVtN/U0YYUjqN8kXFbu4VXKFGP0qnZRgq2m/PlQgzmItJf gt3w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-210063-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210063-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id 98e67ed59e1d1-2c2d0e58db4si6858570a91.70.2024.06.11.07.29.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jun 2024 07:29:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-210063-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-210063-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210063-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 9CB7E282C5C for ; Tue, 11 Jun 2024 14:29:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 22FED17D8A8; Tue, 11 Jun 2024 14:29:22 +0000 (UTC) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A6E5A176FB2; Tue, 11 Jun 2024 14:29:18 +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=1718116161; cv=none; b=IbrIk81h9rhnbhd5ln1kTnu+6JDRqFRnMtfTokggKIxSx8cB2d7R/rerVa2vj+V3autXVk7G/SjHmW32RKuURldb4VHPhAZWTApPyIqCpptWJ95oacIFxnNVJAxrccAm30ZIRS+36bx/16vPgOnBD4h57HQQ35/9ipznEczAu24= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718116161; c=relaxed/simple; bh=/PyfgjbCM3XPrWdeAnwT/SZFOQdUS4uQaLHY2BwYneE=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=eHd9/hGm+y2II1VVFxT56WbjUFtAlTNTabxAzuWqiCXvhVhGY0UJJrj7pasb5QLS4OioNB4KHk4evd5N3ZmbgBuZYRF+JeYLRcQUnQmJN9vIirAM2jkMgcJDNQnhI/pG9/H6xoRr2OD4QUjbeJW33b+GUUIba3y9JOSL1FljqQ0= 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 58A28152B; Tue, 11 Jun 2024 07:29:42 -0700 (PDT) Received: from J2N7QTR9R3 (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 952273F5A1; Tue, 11 Jun 2024 07:29:15 -0700 (PDT) Date: Tue, 11 Jun 2024 15:29:09 +0100 From: Mark Rutland To: Linus Torvalds Cc: Peter Anvin , Ingo Molnar , Borislav Petkov , Thomas Gleixner , Rasmus Villemoes , Josh Poimboeuf , Catalin Marinas , Will Deacon , Linux Kernel Mailing List , the arch/x86 maintainers , linux-arm-kernel@lists.infradead.org, linux-arch Subject: Re: [PATCH 4/7] arm64: add 'runtime constant' support Message-ID: References: <20240610204821.230388-1-torvalds@linux-foundation.org> <20240610204821.230388-5-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240610204821.230388-5-torvalds@linux-foundation.org> Hi Linus, On Mon, Jun 10, 2024 at 01:48:18PM -0700, Linus Torvalds wrote: > This implements the runtime constant infrastructure for arm64, allowing > the dcache d_hash() function to be generated using as a constant for > hash table address followed by shift by a constant of the hash index. > > Signed-off-by: Linus Torvalds > --- > arch/arm64/include/asm/runtime-const.h | 75 ++++++++++++++++++++++++++ > arch/arm64/kernel/vmlinux.lds.S | 3 ++ > 2 files changed, 78 insertions(+) > create mode 100644 arch/arm64/include/asm/runtime-const.h From a quick scan I spotted a couple of issues (explained with fixes below). I haven't had the chance to test/review the whole series yet. Do we expect to use this more widely? If this only really matters for d_hash() it might be better to handle this via the alternatives framework with callbacks and avoid the need for new infrastructure. > diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h > new file mode 100644 > index 000000000000..02462b2cb6f9 > --- /dev/null > +++ b/arch/arm64/include/asm/runtime-const.h > @@ -0,0 +1,75 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef _ASM_RUNTIME_CONST_H > +#define _ASM_RUNTIME_CONST_H > + > +#define runtime_const_ptr(sym) ({ \ > + typeof(sym) __ret; \ > + asm_inline("1:\t" \ > + "movz %0, #0xcdef\n\t" \ > + "movk %0, #0x89ab, lsl #16\n\t" \ > + "movk %0, #0x4567, lsl #32\n\t" \ > + "movk %0, #0x0123, lsl #48\n\t" \ > + ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ > + ".long 1b - .\n\t" \ > + ".popsection" \ > + :"=r" (__ret)); \ > + __ret; }) > + > +#define runtime_const_shift_right_32(val, sym) ({ \ > + unsigned long __ret; \ > + asm_inline("1:\t" \ > + "lsr %w0,%w1,#12\n\t" \ > + ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \ > + ".long 1b - .\n\t" \ > + ".popsection" \ > + :"=r" (__ret) \ > + :"r" (0u+(val))); \ > + __ret; }) > + > +#define runtime_const_init(type, sym) do { \ > + extern s32 __start_runtime_##type##_##sym[]; \ > + extern s32 __stop_runtime_##type##_##sym[]; \ > + runtime_const_fixup(__runtime_fixup_##type, \ > + (unsigned long)(sym), \ > + __start_runtime_##type##_##sym, \ > + __stop_runtime_##type##_##sym); \ > +} while (0) > + > +// 16-bit immediate for wide move (movz and movk) in bits 5..20 > +static inline void __runtime_fixup_16(unsigned int *p, unsigned int val) > +{ > + unsigned int insn = *p; > + insn &= 0xffe0001f; > + insn |= (val & 0xffff) << 5; > + *p = insn; > +} As-is this will break BE kernels as instructions are always encoded little-endian regardless of data endianness. We usually handle that by using __le32 instruction pointers and using le32_to_cpu()/cpu_to_le32() when reading/writing, e.g. #include static inline void __runtime_fixup_16(__le32 *p, unsigned int val) { u32 insn = le32_to_cpu(*p); insn &= 0xffe0001f; insn |= (val & 0xffff) << 5; *p = cpu_to_le32(insn); } We have some helpers for instruction manipulation, and we can use aarch64_insn_encode_immediate() here, e.g. #include static inline void __runtime_fixup_16(__le32 *p, unsigned int val) { u32 insn = le32_to_cpu(*p); insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, val); *p = cpu_to_le32(insn); } > +static inline void __runtime_fixup_ptr(void *where, unsigned long val) > +{ > + unsigned int *p = lm_alias(where); > + __runtime_fixup_16(p, val); > + __runtime_fixup_16(p+1, val >> 16); > + __runtime_fixup_16(p+2, val >> 32); > + __runtime_fixup_16(p+3, val >> 48); > +} This is missing the necessary cache maintenance and context synchronization event. After the new values are written, we need cache maintenance (a D$ clean to PoU, then an I$ invalidate to PoU) followed by a context synchronization event (e.g. an ISB) before CPUs are guaranteed to use the new instructions rather than the old ones. Depending on how your system has been integrated, you might get away without that. If you see: Data cache clean to the PoU not required for I/D coherence ... in your dmesg, that means you only need the I$ invalidate and context synchronization event, and you might happen to get those by virtue of alternative patching running between dcache_init_early() and the use of the patched instructions. However, in general, we do need all of that. As long as this runs before secondaries are brought up, we can handle that with caches_clean_inval_pou(). Assuming the __le32 changes above, I'd expect this to be: static inline void __runtime_fixup_ptr(void *where, unsigned long val) { __le32 *p = lm_alias(where); __runtime_fixup_16(p, val); __runtime_fixup_16(p + 1, val >> 16); __runtime_fixup_16(p + 2, val >> 32); __runtime_fixup_16(p + 3, val >> 48); caches_clean_inval_pou((unsigned long)p, (unsigned long)(p + 4)); } > +// Immediate value is 5 bits starting at bit #16 > +static inline void __runtime_fixup_shift(void *where, unsigned long val) > +{ > + unsigned int *p = lm_alias(where); > + unsigned int insn = *p; > + insn &= 0xffc0ffff; > + insn |= (val & 63) << 16; > + *p = insn; > +} As with the other bits above, I'd expect this to be: static inline void __runtime_fixup_shift(void *where, unsigned long val) { __le32 *p = lm_alias(where); u32 insn = le32_to_cpu(*p); insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, val); *p = cpu_to_le32(insn); caches_clean_inval_pou((unsigned long)p, (unsigned long)(p + 1)); } Mark. > + > +static inline void runtime_const_fixup(void (*fn)(void *, unsigned long), > + unsigned long val, s32 *start, s32 *end) > +{ > + while (start < end) { > + fn(*start + (void *)start, val); > + start++; > + } > +} > + > +#endif > diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S > index 755a22d4f840..55a8e310ea12 100644 > --- a/arch/arm64/kernel/vmlinux.lds.S > +++ b/arch/arm64/kernel/vmlinux.lds.S > @@ -264,6 +264,9 @@ SECTIONS > EXIT_DATA > } > > + RUNTIME_CONST(shift, d_hash_shift) > + RUNTIME_CONST(ptr, dentry_hashtable) > + > PERCPU_SECTION(L1_CACHE_BYTES) > HYPERVISOR_PERCPU_SECTION > > -- > 2.45.1.209.gc6f12300df > >