diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-07-14 18:51:49 -0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-08-14 03:59:21 -0400 |
commit | 32544d9c10c42bac3be8b87d2fc95b0aef008795 (patch) | |
tree | 11983adf6b934cc71ba3013623d8869c867b49fd /arch/xtensa | |
parent | a91902db2990909ea5e6b110811b448f2e8f1571 (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.h | 3 | ||||
-rw-r--r-- | arch/xtensa/include/asm/page.h | 2 | ||||
-rw-r--r-- | arch/xtensa/mm/highmem.c | 17 |
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 | ||
15 | static pte_t *kmap_pte; | 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 | void *kmap_atomic(struct page *page) | 23 | void *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 | ||
39 | void __kunmap_atomic(void *kvaddr) | 44 | void __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 |