From: Ard Biesheuvel Date: Fri, 8 Aug 2014 11:51:40 +0000 (+0100) Subject: arm64: don't flag non-aliasing VIPT I-caches as aliasing X-Git-Tag: Ubuntu-5.13.0-19.19~19306^2~46 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=169c018de7b6d376f821f9fae0ab23dc5c7bb549;p=mirror_ubuntu-jammy-kernel.git arm64: don't flag non-aliasing VIPT I-caches as aliasing VIPT caches are non-aliasing if the index is derived from address bits that are always equal between VA and PA. Classifying these as aliasing results in unnecessary flushing which may hurt performance. Signed-off-by: Ard Biesheuvel Acked-by: Will Deacon Signed-off-by: Will Deacon --- diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index d8c5a59a5687..504fdaa8367e 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -49,8 +49,18 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) unsigned int cpu = smp_processor_id(); u32 l1ip = CTR_L1IP(info->reg_ctr); - if (l1ip != ICACHE_POLICY_PIPT) - set_bit(ICACHEF_ALIASING, &__icache_flags); + if (l1ip != ICACHE_POLICY_PIPT) { + /* + * VIPT caches are non-aliasing if the VA always equals the PA + * in all bit positions that are covered by the index. This is + * the case if the size of a way (# of sets * line size) does + * not exceed PAGE_SIZE. + */ + u32 waysize = icache_get_numsets() * icache_get_linesize(); + + if (l1ip != ICACHE_POLICY_VIPT || waysize > PAGE_SIZE) + set_bit(ICACHEF_ALIASING, &__icache_flags); + } if (l1ip == ICACHE_POLICY_AIVIVT) set_bit(ICACHEF_AIVIVT, &__icache_flags);