> +#define __tlbi_level(op, addr, level) \ > + do { \ > + u64 arg = addr; \ > + \ > + if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) && \ > + level) { \ > + u64 ttl = level; \ > + \ > + switch (PAGE_SIZE) { \ > + case SZ_4K: \ > + ttl |= 1 << 2; \ > + break; \ > + case SZ_16K: \ > + ttl |= 2 << 2; \ > + break; \ > + case SZ_64K: \ > + ttl |= 3 << 2; \ > + break; \ > + } \ > + \ > + arg &= ~TLBI_TTL_MASK; \ > + arg |= FIELD_PREP(TLBI_TTL_MASK, ttl); \ Despite the spec saying both tables apply to TLB maintenance instructions that do not apply to a range of addresses I think it only means the 4-bit version (bug report to Arm, or I'm on the wrong spec). This is consistent with Table D5-53 and the macro takes a single address argument to make misuse with range based tlbi less likely. It relies on the caller to get the level right and getting it wrong could be pretty bad as the spec says all bets are off in that case. Is it worth adding a check of the level against the address (seems a bit involved), or that it is just 2 bits or adding a short doc comment to explain it? (Looks like we get some constants for the levels in a later patch that could be referenced with some form of time travel) > + } \ > + \ > + __tlbi(op, arg); \ cosmetic nit: double space in here