~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/mm/highmem.c

Version: ~ [ linux-5.9-rc6 ] ~ [ linux-5.8.10 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.66 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.146 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.198 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.236 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.236 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  *  But kmap_atomic() and kunmap_atomic() cannot be inlined in
 11  *  modules because they are loaded with btfixup-ped functions.
 12  */
 13 
 14 /*
 15  * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
 16  * gives a more generic (and caching) interface. But kmap_atomic can
 17  * be used in IRQ contexts, so in some (very limited) cases we need it.
 18  *
 19  * XXX This is an old text. Actually, it's good to use atomic kmaps,
 20  * provided you remember that they are atomic and not try to sleep
 21  * with a kmap taken, much like a spinlock. Non-atomic kmaps are
 22  * shared by CPUs, and so precious, and establishing them requires IPI.
 23  * Atomic kmaps are lightweight and we may have NCPUS more of them.
 24  */
 25 #include <linux/highmem.h>
 26 #include <linux/export.h>
 27 #include <linux/mm.h>
 28 
 29 #include <asm/cacheflush.h>
 30 #include <asm/tlbflush.h>
 31 #include <asm/pgalloc.h>
 32 #include <asm/vaddrs.h>
 33 
 34 pgprot_t kmap_prot;
 35 
 36 static pte_t *kmap_pte;
 37 
 38 void __init kmap_init(void)
 39 {
 40         unsigned long address;
 41         pmd_t *dir;
 42 
 43         address = __fix_to_virt(FIX_KMAP_BEGIN);
 44         dir = pmd_offset(pgd_offset_k(address), address);
 45 
 46         /* cache the first kmap pte */
 47         kmap_pte = pte_offset_kernel(dir, address);
 48         kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
 49 }
 50 
 51 void *kmap_atomic(struct page *page)
 52 {
 53         unsigned long vaddr;
 54         long idx, type;
 55 
 56         /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
 57         pagefault_disable();
 58         if (!PageHighMem(page))
 59                 return page_address(page);
 60 
 61         type = kmap_atomic_idx_push();
 62         idx = type + KM_TYPE_NR*smp_processor_id();
 63         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 64 
 65 /* XXX Fix - Anton */
 66 #if 0
 67         __flush_cache_one(vaddr);
 68 #else
 69         flush_cache_all();
 70 #endif
 71 
 72 #ifdef CONFIG_DEBUG_HIGHMEM
 73         BUG_ON(!pte_none(*(kmap_pte-idx)));
 74 #endif
 75         set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
 76 /* XXX Fix - Anton */
 77 #if 0
 78         __flush_tlb_one(vaddr);
 79 #else
 80         flush_tlb_all();
 81 #endif
 82 
 83         return (void*) vaddr;
 84 }
 85 EXPORT_SYMBOL(kmap_atomic);
 86 
 87 void __kunmap_atomic(void *kvaddr)
 88 {
 89         unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
 90         int type;
 91 
 92         if (vaddr < FIXADDR_START) { // FIXME
 93                 pagefault_enable();
 94                 return;
 95         }
 96 
 97         type = kmap_atomic_idx();
 98 
 99 #ifdef CONFIG_DEBUG_HIGHMEM
100         {
101                 unsigned long idx;
102 
103                 idx = type + KM_TYPE_NR * smp_processor_id();
104                 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
105 
106                 /* XXX Fix - Anton */
107 #if 0
108                 __flush_cache_one(vaddr);
109 #else
110                 flush_cache_all();
111 #endif
112 
113                 /*
114                  * force other mappings to Oops if they'll try to access
115                  * this pte without first remap it
116                  */
117                 pte_clear(&init_mm, vaddr, kmap_pte-idx);
118                 /* XXX Fix - Anton */
119 #if 0
120                 __flush_tlb_one(vaddr);
121 #else
122                 flush_tlb_all();
123 #endif
124         }
125 #endif
126 
127         kmap_atomic_idx_pop();
128         pagefault_enable();
129 }
130 EXPORT_SYMBOL(__kunmap_atomic);
131 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp