1
2
3
4
5
6
7
8
9
10
11#include <linux/highmem.h>
12#include <linux/module.h>
13
14void *kmap(struct page *page)
15{
16 might_sleep();
17 if (!PageHighMem(page))
18 return page_address(page);
19 return kmap_high(page);
20}
21
22EXPORT_SYMBOL(kmap);
23
24void kunmap(struct page *page)
25{
26 if (in_interrupt())
27 BUG();
28 if (!PageHighMem(page))
29 return;
30 kunmap_high(page);
31}
32
33EXPORT_SYMBOL(kunmap);
34
35struct page *kmap_atomic_to_page(void *ptr)
36{
37 return virt_to_page(ptr);
38}
39
40void *kmap_atomic(struct page *page)
41{
42 unsigned long paddr;
43 int type;
44
45 preempt_disable();
46 pagefault_disable();
47 type = kmap_atomic_idx_push();
48 paddr = page_to_phys(page);
49
50 switch (type) {
51
52
53
54 case 0: return __kmap_atomic_primary(0, paddr, 6);
55 case 1: return __kmap_atomic_primary(0, paddr, 7);
56 case 2: return __kmap_atomic_primary(0, paddr, 8);
57 case 3: return __kmap_atomic_primary(0, paddr, 9);
58 case 4: return __kmap_atomic_primary(0, paddr, 10);
59
60 case 5 ... 5 + NR_TLB_LINES - 1:
61 return __kmap_atomic_secondary(type - 5, paddr);
62
63 default:
64 BUG();
65 return NULL;
66 }
67}
68EXPORT_SYMBOL(kmap_atomic);
69
70void __kunmap_atomic(void *kvaddr)
71{
72 int type = kmap_atomic_idx();
73 switch (type) {
74 case 0: __kunmap_atomic_primary(0, 6); break;
75 case 1: __kunmap_atomic_primary(0, 7); break;
76 case 2: __kunmap_atomic_primary(0, 8); break;
77 case 3: __kunmap_atomic_primary(0, 9); break;
78 case 4: __kunmap_atomic_primary(0, 10); break;
79
80 case 5 ... 5 + NR_TLB_LINES - 1:
81 __kunmap_atomic_secondary(type - 5, kvaddr);
82 break;
83
84 default:
85 BUG();
86 }
87 kmap_atomic_idx_pop();
88 pagefault_enable();
89 preempt_enable();
90}
91EXPORT_SYMBOL(__kunmap_atomic);
92