diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2020-11-16 20:32:53 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-11-16 21:19:24 +0100 |
commit | 1eb0616c2df5b78c301eaa7bd2ee859f43915001 (patch) | |
tree | 402ec6ffc60b8f0e24495b78684704a4c3eeb19b /arch/xtensa/include/asm/highmem.h | |
parent | mm/highmem: Take kmap_high_get() properly into account (diff) | |
download | linux-1eb0616c2df5b78c301eaa7bd2ee859f43915001.tar.xz linux-1eb0616c2df5b78c301eaa7bd2ee859f43915001.zip |
xtensa/mm/highmem: Make generic kmap_atomic() work correctly
The conversion to the generic kmap_atomic() implementation missed the fact
that xtensa's fixmap works bottom up while all other implementations work
top down. There is no real reason why xtensa needs to work that way.
Cure it by:
- Using the generic fix_to_virt()/virt_to_fix() functions which work top
down
- Adjusting the mapping defines
- Using the generic index calculation for the non cache aliasing case
- Making the cache colour offset reverse so the effective index is correct
While at it, remove the outdated and misleading comment above the fixmap
enum which originates from the initial copy&pasta of this code from i386.
[ Max: Fixed the off by one in the index calculation ]
Fixes: 629ed3f7dad2 ("xtensa/mm/highmem: Switch to generic kmap atomic")
Reported-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Max Filippov <jcmvbkbc@gmail.com>
Link: https://lore.kernel.org/r/20201116193253.23875-1-jcmvbkbc@gmail.com
Diffstat (limited to 'arch/xtensa/include/asm/highmem.h')
-rw-r--r-- | arch/xtensa/include/asm/highmem.h | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 0fc3b1cebc56..34b8b620e7f1 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h @@ -12,6 +12,7 @@ #ifndef _XTENSA_HIGHMEM_H #define _XTENSA_HIGHMEM_H +#ifdef CONFIG_HIGHMEM #include <linux/wait.h> #include <linux/pgtable.h> #include <asm/cacheflush.h> @@ -58,6 +59,13 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) { return pkmap_map_wait_arr + color; } + +enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn); +#define arch_kmap_local_map_idx kmap_local_map_idx + +enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr); +#define arch_kmap_local_unmap_idx kmap_local_unmap_idx + #endif extern pte_t *pkmap_page_table; @@ -67,15 +75,10 @@ static inline void flush_cache_kmaps(void) flush_cache_all(); } -enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn); -#define arch_kmap_local_map_idx kmap_local_map_idx - -enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr); -#define arch_kmap_local_unmap_idx kmap_local_unmap_idx - #define arch_kmap_local_post_unmap(vaddr) \ local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE) void kmap_init(void); +#endif /* CONFIG_HIGHMEM */ #endif |