18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#include <linux/highmem.h> 38c2ecf20Sopenharmony_ci#include <linux/export.h> 48c2ecf20Sopenharmony_ci#include <linux/swap.h> /* for totalram_pages */ 58c2ecf20Sopenharmony_ci#include <linux/memblock.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_civoid *kmap_atomic_high_prot(struct page *page, pgprot_t prot) 88c2ecf20Sopenharmony_ci{ 98c2ecf20Sopenharmony_ci unsigned long vaddr; 108c2ecf20Sopenharmony_ci int idx, type; 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci type = kmap_atomic_idx_push(); 138c2ecf20Sopenharmony_ci idx = type + KM_TYPE_NR*smp_processor_id(); 148c2ecf20Sopenharmony_ci vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 158c2ecf20Sopenharmony_ci BUG_ON(!pte_none(*(kmap_pte-idx))); 168c2ecf20Sopenharmony_ci set_pte(kmap_pte-idx, mk_pte(page, prot)); 178c2ecf20Sopenharmony_ci arch_flush_lazy_mmu_mode(); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci return (void *)vaddr; 208c2ecf20Sopenharmony_ci} 218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmap_atomic_high_prot); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* 248c2ecf20Sopenharmony_ci * This is the same as kmap_atomic() but can map memory that doesn't 258c2ecf20Sopenharmony_ci * have a struct page associated with it. 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_civoid *kmap_atomic_pfn(unsigned long pfn) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci return kmap_atomic_prot_pfn(pfn, kmap_prot); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmap_atomic_pfn); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_civoid kunmap_atomic_high(void *kvaddr) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (vaddr >= __fix_to_virt(FIX_KMAP_END) && 388c2ecf20Sopenharmony_ci vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { 398c2ecf20Sopenharmony_ci int idx, type; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci type = kmap_atomic_idx(); 428c2ecf20Sopenharmony_ci idx = type + KM_TYPE_NR * smp_processor_id(); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_HIGHMEM 458c2ecf20Sopenharmony_ci WARN_ON_ONCE(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); 468c2ecf20Sopenharmony_ci#endif 478c2ecf20Sopenharmony_ci /* 488c2ecf20Sopenharmony_ci * Force other mappings to Oops if they'll try to access this 498c2ecf20Sopenharmony_ci * pte without first remap it. Keeping stale mappings around 508c2ecf20Sopenharmony_ci * is a bad idea also, in case the page changes cacheability 518c2ecf20Sopenharmony_ci * attributes or becomes a protected page in a hypervisor. 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_ci kpte_clear_flush(kmap_pte-idx, vaddr); 548c2ecf20Sopenharmony_ci kmap_atomic_idx_pop(); 558c2ecf20Sopenharmony_ci arch_flush_lazy_mmu_mode(); 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_HIGHMEM 588c2ecf20Sopenharmony_ci else { 598c2ecf20Sopenharmony_ci BUG_ON(vaddr < PAGE_OFFSET); 608c2ecf20Sopenharmony_ci BUG_ON(vaddr >= (unsigned long)high_memory); 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci#endif 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kunmap_atomic_high); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_civoid __init set_highmem_pages_init(void) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct zone *zone; 698c2ecf20Sopenharmony_ci int nid; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* 728c2ecf20Sopenharmony_ci * Explicitly reset zone->managed_pages because set_highmem_pages_init() 738c2ecf20Sopenharmony_ci * is invoked before memblock_free_all() 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci reset_all_zones_managed_pages(); 768c2ecf20Sopenharmony_ci for_each_zone(zone) { 778c2ecf20Sopenharmony_ci unsigned long zone_start_pfn, zone_end_pfn; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (!is_highmem(zone)) 808c2ecf20Sopenharmony_ci continue; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci zone_start_pfn = zone->zone_start_pfn; 838c2ecf20Sopenharmony_ci zone_end_pfn = zone_start_pfn + zone->spanned_pages; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci nid = zone_to_nid(zone); 868c2ecf20Sopenharmony_ci printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n", 878c2ecf20Sopenharmony_ci zone->name, nid, zone_start_pfn, zone_end_pfn); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci add_highpages_with_active_regions(nid, zone_start_pfn, 908c2ecf20Sopenharmony_ci zone_end_pfn); 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci} 93