Message ID | 20200211174938.27809-68-maz@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: ARMv8.3/8.4 Nested Virtualization support | expand |
Hi Marc, On 2020/2/12 1:49, Marc Zyngier wrote: > Add a level-hinted TLB invalidation helper that only gets used if > ARMv8.4-TTL gets detected. > > Signed-off-by: Marc Zyngier <maz@kernel.org> > --- > arch/arm64/include/asm/tlbflush.h | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h > index bc3949064725..a3f70778a325 100644 > --- a/arch/arm64/include/asm/tlbflush.h > +++ b/arch/arm64/include/asm/tlbflush.h > @@ -10,6 +10,7 @@ > > #ifndef __ASSEMBLY__ > > +#include <linux/bitfield.h> > #include <linux/mm_types.h> > #include <linux/sched.h> > #include <asm/cputype.h> > @@ -59,6 +60,35 @@ > __ta; \ > }) > > +#define TLBI_TTL_MASK GENMASK_ULL(47, 44) > + > +#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; \ > + } \ Can we define a macro here to replace the switch? It will be more clearly and efficient. Such as: #define __TG ((PAGE_SHIFT - 12) / 2 + 1) ttl |= __TG << 2; > + \ > + arg &= ~TLBI_TTL_MASK; \ > + arg |= FIELD_PREP(TLBI_TTL_MASK, ttl); \ > + } \ > + \ > + __tlbi(op, arg); \ > + } while(0) > + > /* > * TLB Invalidation > * ================ > Thanks, Zhenyu
Zhenyu, On 2020-03-25 10:38, Zhenyu Ye wrote: > Hi Marc, > > On 2020/2/12 1:49, Marc Zyngier wrote: >> Add a level-hinted TLB invalidation helper that only gets used if >> ARMv8.4-TTL gets detected. >> >> Signed-off-by: Marc Zyngier <maz@kernel.org> >> --- >> arch/arm64/include/asm/tlbflush.h | 30 ++++++++++++++++++++++++++++++ >> 1 file changed, 30 insertions(+) >> >> diff --git a/arch/arm64/include/asm/tlbflush.h >> b/arch/arm64/include/asm/tlbflush.h >> index bc3949064725..a3f70778a325 100644 >> --- a/arch/arm64/include/asm/tlbflush.h >> +++ b/arch/arm64/include/asm/tlbflush.h >> @@ -10,6 +10,7 @@ >> >> #ifndef __ASSEMBLY__ >> >> +#include <linux/bitfield.h> >> #include <linux/mm_types.h> >> #include <linux/sched.h> >> #include <asm/cputype.h> >> @@ -59,6 +60,35 @@ >> __ta; \ >> }) >> >> +#define TLBI_TTL_MASK GENMASK_ULL(47, 44) >> + >> +#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; \ >> + } \ > > Can we define a macro here to replace the switch? It will be more > clearly and efficient. Such as: > > #define __TG ((PAGE_SHIFT - 12) / 2 + 1) > ttl |= __TG << 2; Let me rephrase this: a convoluted formula with magic numbers in it is clearer than the values documented in the specification (Table D5-53)? I have the exact opposite view. As for efficency, you do realize that the compiler always discards two third of this code on any possible configuration, right? I think the code above is the clearest way to express table D5-53, and the only missing bit is a reference to that table. Thanks, M.
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index bc3949064725..a3f70778a325 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -10,6 +10,7 @@ #ifndef __ASSEMBLY__ +#include <linux/bitfield.h> #include <linux/mm_types.h> #include <linux/sched.h> #include <asm/cputype.h> @@ -59,6 +60,35 @@ __ta; \ }) +#define TLBI_TTL_MASK GENMASK_ULL(47, 44) + +#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); \ + } \ + \ + __tlbi(op, arg); \ + } while(0) + /* * TLB Invalidation * ================
Add a level-hinted TLB invalidation helper that only gets used if ARMv8.4-TTL gets detected. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/include/asm/tlbflush.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)