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

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

Version: ~ [ linux-5.8-rc4 ] ~ [ linux-5.7.7 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.50 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.131 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.187 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.229 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.229 ] ~ [ 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  * arch/arm/mm/highmem.c -- ARM highmem support
  3  *
  4  * Author:      Nicolas Pitre
  5  * Created:     september 8, 2008
  6  * Copyright:   Marvell Semiconductors Inc.
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License version 2 as
 10  * published by the Free Software Foundation.
 11  */
 12 
 13 #include <linux/module.h>
 14 #include <linux/highmem.h>
 15 #include <linux/interrupt.h>
 16 #include <asm/fixmap.h>
 17 #include <asm/cacheflush.h>
 18 #include <asm/tlbflush.h>
 19 #include "mm.h"
 20 
 21 void *kmap(struct page *page)
 22 {
 23         might_sleep();
 24         if (!PageHighMem(page))
 25                 return page_address(page);
 26         return kmap_high(page);
 27 }
 28 EXPORT_SYMBOL(kmap);
 29 
 30 void kunmap(struct page *page)
 31 {
 32         BUG_ON(in_interrupt());
 33         if (!PageHighMem(page))
 34                 return;
 35         kunmap_high(page);
 36 }
 37 EXPORT_SYMBOL(kunmap);
 38 
 39 void *kmap_atomic(struct page *page)
 40 {
 41         unsigned int idx;
 42         unsigned long vaddr;
 43         void *kmap;
 44         int type;
 45 
 46         pagefault_disable();
 47         if (!PageHighMem(page))
 48                 return page_address(page);
 49 
 50 #ifdef CONFIG_DEBUG_HIGHMEM
 51         /*
 52          * There is no cache coherency issue when non VIVT, so force the
 53          * dedicated kmap usage for better debugging purposes in that case.
 54          */
 55         if (!cache_is_vivt())
 56                 kmap = NULL;
 57         else
 58 #endif
 59                 kmap = kmap_high_get(page);
 60         if (kmap)
 61                 return kmap;
 62 
 63         type = kmap_atomic_idx_push();
 64 
 65         idx = type + KM_TYPE_NR * smp_processor_id();
 66         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 67 #ifdef CONFIG_DEBUG_HIGHMEM
 68         /*
 69          * With debugging enabled, kunmap_atomic forces that entry to 0.
 70          * Make sure it was indeed properly unmapped.
 71          */
 72         BUG_ON(!pte_none(get_top_pte(vaddr)));
 73 #endif
 74         /*
 75          * When debugging is off, kunmap_atomic leaves the previous mapping
 76          * in place, so the contained TLB flush ensures the TLB is updated
 77          * with the new mapping.
 78          */
 79         set_top_pte(vaddr, mk_pte(page, kmap_prot));
 80 
 81         return (void *)vaddr;
 82 }
 83 EXPORT_SYMBOL(kmap_atomic);
 84 
 85 void __kunmap_atomic(void *kvaddr)
 86 {
 87         unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
 88         int idx, type;
 89 
 90         if (kvaddr >= (void *)FIXADDR_START) {
 91                 type = kmap_atomic_idx();
 92                 idx = type + KM_TYPE_NR * smp_processor_id();
 93 
 94                 if (cache_is_vivt())
 95                         __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 96 #ifdef CONFIG_DEBUG_HIGHMEM
 97                 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 98                 set_top_pte(vaddr, __pte(0));
 99 #else
100                 (void) idx;  /* to kill a warning */
101 #endif
102                 kmap_atomic_idx_pop();
103         } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
104                 /* this address was obtained through kmap_high_get() */
105                 kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
106         }
107         pagefault_enable();
108 }
109 EXPORT_SYMBOL(__kunmap_atomic);
110 
111 void *kmap_atomic_pfn(unsigned long pfn)
112 {
113         unsigned long vaddr;
114         int idx, type;
115 
116         pagefault_disable();
117 
118         type = kmap_atomic_idx_push();
119         idx = type + KM_TYPE_NR * smp_processor_id();
120         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
121 #ifdef CONFIG_DEBUG_HIGHMEM
122         BUG_ON(!pte_none(get_top_pte(vaddr)));
123 #endif
124         set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
125 
126         return (void *)vaddr;
127 }
128 
129 struct page *kmap_atomic_to_page(const void *ptr)
130 {
131         unsigned long vaddr = (unsigned long)ptr;
132 
133         if (vaddr < FIXADDR_START)
134                 return virt_to_page(ptr);
135 
136         return pte_page(get_top_pte(vaddr));
137 }
138 

~ [ 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