On Tue, Jun 11, 2024 at 10:20:10AM -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 <torvalds@xxxxxxxxxxxxxxxxxxxx> > --- > v2: updates as per Mark Rutland Sorry, I just realised I got the cache maintenance slightly wrong below. > +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)); > +} We need to do the I$ maintenance on the VA that'll be executed (to handle systems with a VIPT I$), so we'll need to use 'where' rather than 'p', e.g. caches_clean_inval_pou((unsigned long)where, (unsigned long)where + 4 * AARCH64_INSN_SIZE); Note: the D$ and I$ maintenance instruction (DC CVAU and IC IVAU) only require read permissions, so those can be used on the kernel's executable alias even though that's mapped without write permissions. > +/* Immediate value is 6 bits starting at bit #16 */ > +static inline void __runtime_fixup_shift(void *where, unsigned long val) > +{ > + __le32 *p = lm_alias(where); > + u32 insn = le32_to_cpu(*p); > + insn &= 0xffc0ffff; > + insn |= (val & 63) << 16; > + *p = cpu_to_le32(insn); > + caches_clean_inval_pou((unsigned long)p, (unsigned long)(p + 1)); > +} Likewise: caches_clean_inval_pou((unsigned long)where, (unsigned long)where + AARCH64_INSN_SIZE); Mark.