Re: [PATCH] x86: add 'runtime constant' infrastructure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 8 Jun 2024 at 12:43, Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> Needs more comments and testing, but it works, and has a generic
> fallback for architectures that don't support it.

.. and here is the TOTALLY UNTESTED patch to implement the arm64
version of runtime constants.

It almost certainly does not work. I'm too scared to test it.  I may
start to recognize arm64 instructions, but rewriting them on the fly
is another thing entirely, and I'm fairly sure this needs an  I$ sync
and probably modifying the instructions using another address even
during early boot.

So this is a "throw it over the fence to the actually competent arm64
people" patch.

Catalin, Will? This depends on the infrastructure that I added in

   https://lore.kernel.org/all/20240608193504.429644-2-torvalds@xxxxxxxxxxxxxxxxxxxx/

which is actually tested on the x86-64 side.

I did test that the code generation looks superficially sane, and this generates

        mov     x1, #0xcdef
        movk    x1, #0x89ab, lsl #16
        movk    x1, #0x4567, lsl #32
        movk    x1, #0x123, lsl #48
        ...
        lsr     w0, w25, #12
        ldr     x0, [x1, x0, lsl #3]

for the dcache hash lookup (those constants are obviously the ones
that get rewritten after the hash table has been allocated and the
size becomes fixed).

And honestly, I may have gotten even the simple part of instruction
rewriting wrong (ie maybe I'm filling in the wrong bit locations - I'm
reading the architecture manual, not actually *testing* anything).

Think of this patch mostly as a "look, adding another architecture
isn't *that* hard - even if the constant value is spread out in the
instructions".

                Linus
From befc3d49366fb049b65679fb37fa703fe419a7e8 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Date: Sat, 8 Jun 2024 13:22:31 -0700
Subject: [PATCH] arm64: add 'runtime const' support

Mommy mommy I'm scared
---
 arch/arm64/include/asm/runtime-const.h | 73 ++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S        |  3 ++
 2 files changed, 76 insertions(+)
 create mode 100644 arch/arm64/include/asm/runtime-const.h

diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
new file mode 100644
index 000000000000..7d402ae6d3c2
--- /dev/null
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -0,0 +1,73 @@
+/* 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("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("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, value) do {	\
+	extern s32 __start_runtime_##type##_##sym[];	\
+	extern s32 __stop_runtime_##type##_##sym[];	\
+	runtime_const_fixup(__runtime_fixup_##type,	\
+		(unsigned long)(value), 		\
+		__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;
+}
+
+static inline void __runtime_fixup_ptr(void *where, unsigned long val)
+{
+	__runtime_fixup_16(where, val);
+	__runtime_fixup_16(where+4, val >> 16);
+	__runtime_fixup_16(where+8, val >> 32);
+	__runtime_fixup_16(where+12, val >> 48);
+}
+
+// Immediate value is 5 bits starting at bit #16
+static inline void __runtime_fixup_shift(void *where, unsigned long val)
+{
+	unsigned int insn = *(unsigned int *)where;
+	insn &= 0xffc0ffff;
+	insn |= (val & 63) << 16;
+	*(unsigned int *)where = insn;
+}
+
+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


[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux