summaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-07-14 18:51:49 -0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-08-14 03:59:21 -0400
commit32544d9c10c42bac3be8b87d2fc95b0aef008795 (patch)
tree11983adf6b934cc71ba3013623d8869c867b49fd /arch/xtensa
parenta91902db2990909ea5e6b110811b448f2e8f1571 (diff)
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>
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/fixmap.h3
-rw-r--r--arch/xtensa/include/asm/page.h2
-rw-r--r--arch/xtensa/mm/highmem.c17
3 files changed, 14 insertions, 8 deletions
diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h
index a43cd5265556..62b507deea9d 100644
--- a/arch/xtensa/include/asm/fixmap.h
+++ b/arch/xtensa/include/asm/fixmap.h
@@ -38,7 +38,8 @@ enum fixed_addresses {
38#ifdef CONFIG_HIGHMEM 38#ifdef CONFIG_HIGHMEM
39 /* reserved pte's for temporary kernel mappings */ 39 /* reserved pte's for temporary kernel mappings */
40 FIX_KMAP_BEGIN, 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#endif 43#endif
43 __end_of_fixed_addresses 44 __end_of_fixed_addresses
44}; 45};
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index 11721ccd7f23..abe24c6f8b2f 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -78,7 +78,9 @@
78# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) 78# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
79#else 79#else
80# define DCACHE_ALIAS_ORDER 0 80# define DCACHE_ALIAS_ORDER 0
81# define DCACHE_ALIAS(a) ((void)(a), 0)
81#endif 82#endif
83#define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER)
82 84
83#if ICACHE_WAY_SIZE > PAGE_SIZE 85#if ICACHE_WAY_SIZE > PAGE_SIZE
84# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT) 86# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c
index 2e95a7665bf3..466abaed5382 100644
--- a/arch/xtensa/mm/highmem.c
+++ b/arch/xtensa/mm/highmem.c
@@ -14,18 +14,23 @@
14 14
15static pte_t *kmap_pte; 15static pte_t *kmap_pte;
16 16
17static 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
17void *kmap_atomic(struct page *page) 23void *kmap_atomic(struct page *page)
18{ 24{
19 enum fixed_addresses idx; 25 enum fixed_addresses idx;
20 unsigned long vaddr; 26 unsigned long vaddr;
21 int type;
22 27
23 pagefault_disable(); 28 pagefault_disable();
24 if (!PageHighMem(page)) 29 if (!PageHighMem(page))
25 return page_address(page); 30 return page_address(page);
26 31
27 type = kmap_atomic_idx_push(); 32 idx = kmap_idx(kmap_atomic_idx_push(),
28 idx = type + KM_TYPE_NR * smp_processor_id(); 33 DCACHE_ALIAS(page_to_phys(page)));
29 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 34 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
30#ifdef CONFIG_DEBUG_HIGHMEM 35#ifdef CONFIG_DEBUG_HIGHMEM
31 BUG_ON(!pte_none(*(kmap_pte + idx))); 36 BUG_ON(!pte_none(*(kmap_pte + idx)));
@@ -38,12 +43,10 @@ EXPORT_SYMBOL(kmap_atomic);
38 43
39void __kunmap_atomic(void *kvaddr) 44void __kunmap_atomic(void *kvaddr)
40{ 45{
41 int idx, type;
42
43 if (kvaddr >= (void *)FIXADDR_START && 46 if (kvaddr >= (void *)FIXADDR_START &&
44 kvaddr < (void *)FIXADDR_TOP) { 47 kvaddr < (void *)FIXADDR_TOP) {
45 type = kmap_atomic_idx(); 48 int idx = kmap_idx(kmap_atomic_idx(),
46 idx = type + KM_TYPE_NR * smp_processor_id(); 49 DCACHE_ALIAS((unsigned long)kvaddr));
47 50
48 /* 51 /*
49 * Force other mappings to Oops if they'll try to access this 52 * Force other mappings to Oops if they'll try to access this