Re: [PATCH 06/26] arm64: Add level-hinted TLB invalidation helper

Andrew Scull
2020-05-05T17:16:39Z

> +#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