static void kmap_remove_unused_cpu(int cpu) { int start_idx, idx, type; int need_flush = 0; pagefault_disable(); type = kmap_atomic_idx(); start_idx = type + 1 + KM_TYPE_NR * cpu; for (idx = start_idx; idx < KM_TYPE_NR + KM_TYPE_NR * cpu; idx++) { unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); pte_t ptep; ptep = get_top_pte(vaddr); if (ptep) { set_top_pte(vaddr, __pte(0)); need_flush = 1; } } pagefault_enable(); /* flush the caches and tlb if required */ if (need_flush) { local_flush_tlb_all(); flush_cache_all(); } }
struct page *kmap_atomic_to_page(const void *ptr) { unsigned long vaddr = (unsigned long)ptr; if (vaddr < FIXADDR_START) return virt_to_page(ptr); return pte_page(get_top_pte(vaddr)); }
void *kmap_atomic_pfn(unsigned long pfn) { unsigned long vaddr; int idx, type; pagefault_disable(); type = kmap_atomic_idx_push(); idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(get_top_pte(vaddr))); #endif set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); return (void *)vaddr; }
void *kmap_atomic(struct page *page) { unsigned int idx; unsigned long vaddr; void *kmap; int type; pagefault_disable(); //POS (Cheolhee Lee) if (!(PageHighMem(page) || PageNVRAM(page))) return page_address(page); #ifdef CONFIG_DEBUG_HIGHMEM /* * There is no cache coherency issue when non VIVT, so force the * dedicated kmap usage for better debugging purposes in that case. */ if (!cache_is_vivt()) kmap = NULL; else #endif kmap = kmap_high_get(page); if (kmap) return kmap; type = kmap_atomic_idx_push(); idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM /* * With debugging enabled, kunmap_atomic forces that entry to 0. * Make sure it was indeed properly unmapped. */ BUG_ON(!pte_none(get_top_pte(vaddr))); #endif /* * When debugging is off, kunmap_atomic leaves the previous mapping * in place, so the contained TLB flush ensures the TLB is updated * with the new mapping. */ set_top_pte(vaddr, mk_pte(page, kmap_prot)); return (void *)vaddr; }
static void kmap_remove_unused_cpu(int cpu) { int start_idx, idx, type; pagefault_disable(); type = kmap_atomic_idx(); start_idx = FIX_KMAP_BEGIN + type + 1 + KM_TYPE_NR * cpu; for (idx = start_idx; idx < KM_TYPE_NR + KM_TYPE_NR * cpu; idx++) { unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); pte_t ptep; ptep = get_top_pte(vaddr); if (ptep) set_top_pte(vaddr, __pte(0)); } pagefault_enable(); }