1 /* 2 * highmem.c: virtual kernel memory mappings for high memory 3 * 4 * Provides kernel-static versions of atomic kmap functions originally 5 * found as inlines in include/asm-sparc/highmem.h. These became 6 * needed as kmap_atomic() and kunmap_atomic() started getting 7 * called from within modules. 8 * -- Tomas Szepe <szepe@pinerecords.com>, September 2002 9 */ 10 11 #include <linux/mm.h> 12 #include <linux/highmem.h> 13 #include <asm/pgalloc.h> 14 15 /* 16 * The use of kmap_atomic/kunmap_atomic is discouraged -- kmap()/kunmap() 17 * gives a more generic (and caching) interface. But kmap_atomic() can 18 * be used in IRQ contexts, so in some (very limited) cases we need it. 19 */ kmap_atomic(struct page * page,enum km_type type)20void *kmap_atomic(struct page *page, enum km_type type) 21 { 22 unsigned long idx; 23 unsigned long vaddr; 24 25 if (page < highmem_start_page) 26 return page_address(page); 27 28 idx = type + KM_TYPE_NR * smp_processor_id(); 29 vaddr = fix_kmap_begin + idx * PAGE_SIZE; 30 31 /* XXX Fix - Anton */ 32 #if 0 33 __flush_cache_one(vaddr); 34 #else 35 flush_cache_all(); 36 #endif 37 38 #if HIGHMEM_DEBUG 39 if (!pte_none(*(kmap_pte + idx))) 40 BUG(); 41 #endif 42 set_pte(kmap_pte + idx, mk_pte(page, kmap_prot)); 43 /* XXX Fix - Anton */ 44 #if 0 45 __flush_tlb_one(vaddr); 46 #else 47 flush_tlb_all(); 48 #endif 49 50 return (void *) vaddr; 51 } 52 kunmap_atomic(void * kvaddr,enum km_type type)53void kunmap_atomic(void *kvaddr, enum km_type type) 54 { 55 unsigned long vaddr = (unsigned long) kvaddr; 56 unsigned long idx = type + KM_TYPE_NR * smp_processor_id(); 57 58 if (vaddr < fix_kmap_begin) /* FIXME */ 59 return; 60 61 if (vaddr != fix_kmap_begin + idx * PAGE_SIZE) 62 BUG(); 63 64 /* XXX Fix - Anton */ 65 #if 0 66 __flush_cache_one(vaddr); 67 #else 68 flush_cache_all(); 69 #endif 70 71 #ifdef HIGHMEM_DEBUG 72 /* 73 * Force other mappings to oops if they try to access 74 * this pte without first remapping it. 75 */ 76 pte_clear(kmap_pte + idx); 77 /* XXX Fix - Anton */ 78 #if 0 79 __flush_tlb_one(vaddr); 80 #else 81 flush_tlb_all(); 82 #endif 83 #endif 84 } 85