1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2d73cd428SNicolas Pitre #ifndef _ASM_HIGHMEM_H 3d73cd428SNicolas Pitre #define _ASM_HIGHMEM_H 4d73cd428SNicolas Pitre 5*2a15ba82SThomas Gleixner #include <asm/fixmap.h> 6d73cd428SNicolas Pitre 7d73cd428SNicolas Pitre #define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE) 8d73cd428SNicolas Pitre #define LAST_PKMAP PTRS_PER_PTE 9d73cd428SNicolas Pitre #define LAST_PKMAP_MASK (LAST_PKMAP - 1) 10d73cd428SNicolas Pitre #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) 11d73cd428SNicolas Pitre #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) 12d73cd428SNicolas Pitre 137e5a69e8SNicolas Pitre #define flush_cache_kmaps() \ 147e5a69e8SNicolas Pitre do { \ 157e5a69e8SNicolas Pitre if (cache_is_vivt()) \ 167e5a69e8SNicolas Pitre flush_cache_all(); \ 177e5a69e8SNicolas Pitre } while (0) 18d73cd428SNicolas Pitre 19d73cd428SNicolas Pitre extern pte_t *pkmap_page_table; 20d73cd428SNicolas Pitre 217e5a69e8SNicolas Pitre /* 22aaa50048SNicolas Pitre * The reason for kmap_high_get() is to ensure that the currently kmap'd 23aaa50048SNicolas Pitre * page usage count does not decrease to zero while we're using its 24aaa50048SNicolas Pitre * existing virtual mapping in an atomic context. With a VIVT cache this 25aaa50048SNicolas Pitre * is essential to do, but with a VIPT cache this is only an optimization 26aaa50048SNicolas Pitre * so not to pay the price of establishing a second mapping if an existing 27aaa50048SNicolas Pitre * one can be used. However, on platforms without hardware TLB maintenance 28aaa50048SNicolas Pitre * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since 29aaa50048SNicolas Pitre * the locking involved must also disable IRQs which is incompatible with 30aaa50048SNicolas Pitre * the IPI mechanism used by global TLB operations. 31aaa50048SNicolas Pitre */ 32aaa50048SNicolas Pitre #define ARCH_NEEDS_KMAP_HIGH_GET 33aaa50048SNicolas Pitre #if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6) 34aaa50048SNicolas Pitre #undef ARCH_NEEDS_KMAP_HIGH_GET 35aaa50048SNicolas Pitre #if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT) 36aaa50048SNicolas Pitre #error "The sum of features in your kernel config cannot be supported together" 37aaa50048SNicolas Pitre #endif 38aaa50048SNicolas Pitre #endif 39aaa50048SNicolas Pitre 4093dc6887SCatalin Marinas /* 4193dc6887SCatalin Marinas * Needed to be able to broadcast the TLB invalidation for kmap. 4293dc6887SCatalin Marinas */ 4393dc6887SCatalin Marinas #ifdef CONFIG_ARM_ERRATA_798181 4493dc6887SCatalin Marinas #undef ARCH_NEEDS_KMAP_HIGH_GET 4593dc6887SCatalin Marinas #endif 4693dc6887SCatalin Marinas 47aaa50048SNicolas Pitre #ifdef ARCH_NEEDS_KMAP_HIGH_GET 48aaa50048SNicolas Pitre extern void *kmap_high_get(struct page *page); 49*2a15ba82SThomas Gleixner 50*2a15ba82SThomas Gleixner static inline void *arch_kmap_local_high_get(struct page *page) 51*2a15ba82SThomas Gleixner { 52*2a15ba82SThomas Gleixner if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt()) 53*2a15ba82SThomas Gleixner return NULL; 54*2a15ba82SThomas Gleixner return kmap_high_get(page); 55*2a15ba82SThomas Gleixner } 56*2a15ba82SThomas Gleixner #define arch_kmap_local_high_get arch_kmap_local_high_get 57*2a15ba82SThomas Gleixner 58*2a15ba82SThomas Gleixner #else /* ARCH_NEEDS_KMAP_HIGH_GET */ 59aaa50048SNicolas Pitre static inline void *kmap_high_get(struct page *page) 60aaa50048SNicolas Pitre { 61aaa50048SNicolas Pitre return NULL; 62aaa50048SNicolas Pitre } 63*2a15ba82SThomas Gleixner #endif /* !ARCH_NEEDS_KMAP_HIGH_GET */ 64aaa50048SNicolas Pitre 65*2a15ba82SThomas Gleixner #define arch_kmap_local_post_map(vaddr, pteval) \ 66*2a15ba82SThomas Gleixner local_flush_tlb_kernel_page(vaddr) 67*2a15ba82SThomas Gleixner 68*2a15ba82SThomas Gleixner #define arch_kmap_local_pre_unmap(vaddr) \ 69*2a15ba82SThomas Gleixner do { \ 70*2a15ba82SThomas Gleixner if (cache_is_vivt()) \ 71*2a15ba82SThomas Gleixner __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); \ 72*2a15ba82SThomas Gleixner } while (0) 73*2a15ba82SThomas Gleixner 74*2a15ba82SThomas Gleixner #define arch_kmap_local_post_unmap(vaddr) \ 75*2a15ba82SThomas Gleixner local_flush_tlb_kernel_page(vaddr) 76d73cd428SNicolas Pitre 77d73cd428SNicolas Pitre #endif 78