Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xtensa: support aliasing cache in k[un]map_atomic

Map high memory pages at virtual addresses with color that match color
of their physical address. Existing cache alias management mechanisms
may be used with such pages.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>

+14 -8
+2 -1
arch/xtensa/include/asm/fixmap.h
··· 38 38 #ifdef CONFIG_HIGHMEM 39 39 /* reserved pte's for temporary kernel mappings */ 40 40 FIX_KMAP_BEGIN, 41 - FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, 41 + FIX_KMAP_END = FIX_KMAP_BEGIN + 42 + (KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1, 42 43 #endif 43 44 __end_of_fixed_addresses 44 45 };
+2
arch/xtensa/include/asm/page.h
··· 78 78 # define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) 79 79 #else 80 80 # define DCACHE_ALIAS_ORDER 0 81 + # define DCACHE_ALIAS(a) ((void)(a), 0) 81 82 #endif 83 + #define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER) 82 84 83 85 #if ICACHE_WAY_SIZE > PAGE_SIZE 84 86 # define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
+10 -7
arch/xtensa/mm/highmem.c
··· 14 14 15 15 static pte_t *kmap_pte; 16 16 17 + static inline enum fixed_addresses kmap_idx(int type, unsigned long color) 18 + { 19 + return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS + 20 + color; 21 + } 22 + 17 23 void *kmap_atomic(struct page *page) 18 24 { 19 25 enum fixed_addresses idx; 20 26 unsigned long vaddr; 21 - int type; 22 27 23 28 pagefault_disable(); 24 29 if (!PageHighMem(page)) 25 30 return page_address(page); 26 31 27 - type = kmap_atomic_idx_push(); 28 - idx = type + KM_TYPE_NR * smp_processor_id(); 32 + idx = kmap_idx(kmap_atomic_idx_push(), 33 + DCACHE_ALIAS(page_to_phys(page))); 29 34 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 30 35 #ifdef CONFIG_DEBUG_HIGHMEM 31 36 BUG_ON(!pte_none(*(kmap_pte + idx))); ··· 43 38 44 39 void __kunmap_atomic(void *kvaddr) 45 40 { 46 - int idx, type; 47 - 48 41 if (kvaddr >= (void *)FIXADDR_START && 49 42 kvaddr < (void *)FIXADDR_TOP) { 50 - type = kmap_atomic_idx(); 51 - idx = type + KM_TYPE_NR * smp_processor_id(); 43 + int idx = kmap_idx(kmap_atomic_idx(), 44 + DCACHE_ALIAS((unsigned long)kvaddr)); 52 45 53 46 /* 54 47 * Force other mappings to Oops if they'll try to access this