| From 08fe007968b2b45e831daf74899f79a54d73f773 Mon Sep 17 00:00:00 2001 |
| From: Vineet Gupta <vgupta@synopsys.com> |
| Date: Mon, 19 Dec 2016 11:38:38 -0800 |
| Subject: ARC: mm: arc700: Don't assume 2 colours for aliasing VIPT dcache |
| |
| From: Vineet Gupta <vgupta@synopsys.com> |
| |
| commit 08fe007968b2b45e831daf74899f79a54d73f773 upstream. |
| |
| An ARC700 customer reported linux boot crashes when upgrading to bigger |
| L1 dcache (64K from 32K). Turns out they had an aliasing VIPT config and |
| current code only assumed 2 colours, while theirs had 4. So default to 4 |
| colours and complain if there are fewer. Ideally this needs to be a |
| Kconfig option, but heck that's too much of hassle for a single user. |
| |
| Signed-off-by: Vineet Gupta <vgupta@synopsys.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arc/include/asm/cacheflush.h | 6 ++++-- |
| arch/arc/mm/cache.c | 11 ++++++++--- |
| 2 files changed, 12 insertions(+), 5 deletions(-) |
| |
| --- a/arch/arc/include/asm/cacheflush.h |
| +++ b/arch/arc/include/asm/cacheflush.h |
| @@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_stru |
| */ |
| #define PG_dc_clean PG_arch_1 |
| |
| +#define CACHE_COLORS_NUM 4 |
| +#define CACHE_COLORS_MSK (CACHE_COLORS_NUM - 1) |
| +#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & CACHE_COLORS_MSK) |
| + |
| /* |
| * Simple wrapper over config option |
| * Bootup code ensures that hardware matches kernel configuration |
| @@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing |
| return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); |
| } |
| |
| -#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1) |
| - |
| /* |
| * checks if two addresses (after page aligning) index into same cache set |
| */ |
| --- a/arch/arc/mm/cache.c |
| +++ b/arch/arc/mm/cache.c |
| @@ -967,11 +967,16 @@ void arc_cache_init(void) |
| /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ |
| if (is_isa_arcompact()) { |
| int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); |
| + int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE); |
| |
| - if (dc->alias && !handled) |
| - panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); |
| - else if (!dc->alias && handled) |
| + if (dc->alias) { |
| + if (!handled) |
| + panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); |
| + if (CACHE_COLORS_NUM != num_colors) |
| + panic("CACHE_COLORS_NUM not optimized for config\n"); |
| + } else if (!dc->alias && handled) { |
| panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); |
| + } |
| } |
| } |
| |