diff options
Diffstat (limited to 'arch/x86/mm/highmem_32.c')
-rw-r--r-- | arch/x86/mm/highmem_32.c | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 5e8fa12ef861..b49962662101 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -9,6 +9,7 @@ void *kmap(struct page *page) | |||
9 | return page_address(page); | 9 | return page_address(page); |
10 | return kmap_high(page); | 10 | return kmap_high(page); |
11 | } | 11 | } |
12 | EXPORT_SYMBOL(kmap); | ||
12 | 13 | ||
13 | void kunmap(struct page *page) | 14 | void kunmap(struct page *page) |
14 | { | 15 | { |
@@ -18,6 +19,7 @@ void kunmap(struct page *page) | |||
18 | return; | 19 | return; |
19 | kunmap_high(page); | 20 | kunmap_high(page); |
20 | } | 21 | } |
22 | EXPORT_SYMBOL(kunmap); | ||
21 | 23 | ||
22 | /* | 24 | /* |
23 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because | 25 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because |
@@ -27,10 +29,10 @@ void kunmap(struct page *page) | |||
27 | * However when holding an atomic kmap it is not legal to sleep, so atomic | 29 | * However when holding an atomic kmap it is not legal to sleep, so atomic |
28 | * kmaps are appropriate for short, tight code paths only. | 30 | * kmaps are appropriate for short, tight code paths only. |
29 | */ | 31 | */ |
30 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | 32 | void *kmap_atomic_prot(struct page *page, pgprot_t prot) |
31 | { | 33 | { |
32 | enum fixed_addresses idx; | ||
33 | unsigned long vaddr; | 34 | unsigned long vaddr; |
35 | int idx, type; | ||
34 | 36 | ||
35 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | 37 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ |
36 | pagefault_disable(); | 38 | pagefault_disable(); |
@@ -38,8 +40,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
38 | if (!PageHighMem(page)) | 40 | if (!PageHighMem(page)) |
39 | return page_address(page); | 41 | return page_address(page); |
40 | 42 | ||
41 | debug_kmap_atomic(type); | 43 | type = kmap_atomic_idx_push(); |
42 | |||
43 | idx = type + KM_TYPE_NR*smp_processor_id(); | 44 | idx = type + KM_TYPE_NR*smp_processor_id(); |
44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 45 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
45 | BUG_ON(!pte_none(*(kmap_pte-idx))); | 46 | BUG_ON(!pte_none(*(kmap_pte-idx))); |
@@ -47,44 +48,57 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
47 | 48 | ||
48 | return (void *)vaddr; | 49 | return (void *)vaddr; |
49 | } | 50 | } |
51 | EXPORT_SYMBOL(kmap_atomic_prot); | ||
52 | |||
53 | void *__kmap_atomic(struct page *page) | ||
54 | { | ||
55 | return kmap_atomic_prot(page, kmap_prot); | ||
56 | } | ||
57 | EXPORT_SYMBOL(__kmap_atomic); | ||
50 | 58 | ||
51 | void *kmap_atomic(struct page *page, enum km_type type) | 59 | /* |
60 | * This is the same as kmap_atomic() but can map memory that doesn't | ||
61 | * have a struct page associated with it. | ||
62 | */ | ||
63 | void *kmap_atomic_pfn(unsigned long pfn) | ||
52 | { | 64 | { |
53 | return kmap_atomic_prot(page, type, kmap_prot); | 65 | return kmap_atomic_prot_pfn(pfn, kmap_prot); |
54 | } | 66 | } |
67 | EXPORT_SYMBOL_GPL(kmap_atomic_pfn); | ||
55 | 68 | ||
56 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 69 | void __kunmap_atomic(void *kvaddr) |
57 | { | 70 | { |
58 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 71 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
59 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | 72 | |
60 | 73 | if (vaddr >= __fix_to_virt(FIX_KMAP_END) && | |
61 | /* | 74 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { |
62 | * Force other mappings to Oops if they'll try to access this pte | 75 | int idx, type; |
63 | * without first remap it. Keeping stale mappings around is a bad idea | 76 | |
64 | * also, in case the page changes cacheability attributes or becomes | 77 | type = kmap_atomic_idx(); |
65 | * a protected page in a hypervisor. | 78 | idx = type + KM_TYPE_NR * smp_processor_id(); |
66 | */ | 79 | |
67 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | 80 | #ifdef CONFIG_DEBUG_HIGHMEM |
81 | WARN_ON_ONCE(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | ||
82 | #endif | ||
83 | /* | ||
84 | * Force other mappings to Oops if they'll try to access this | ||
85 | * pte without first remap it. Keeping stale mappings around | ||
86 | * is a bad idea also, in case the page changes cacheability | ||
87 | * attributes or becomes a protected page in a hypervisor. | ||
88 | */ | ||
68 | kpte_clear_flush(kmap_pte-idx, vaddr); | 89 | kpte_clear_flush(kmap_pte-idx, vaddr); |
69 | else { | 90 | kmap_atomic_idx_pop(); |
91 | } | ||
70 | #ifdef CONFIG_DEBUG_HIGHMEM | 92 | #ifdef CONFIG_DEBUG_HIGHMEM |
93 | else { | ||
71 | BUG_ON(vaddr < PAGE_OFFSET); | 94 | BUG_ON(vaddr < PAGE_OFFSET); |
72 | BUG_ON(vaddr >= (unsigned long)high_memory); | 95 | BUG_ON(vaddr >= (unsigned long)high_memory); |
73 | #endif | ||
74 | } | 96 | } |
97 | #endif | ||
75 | 98 | ||
76 | pagefault_enable(); | 99 | pagefault_enable(); |
77 | } | 100 | } |
78 | 101 | EXPORT_SYMBOL(__kunmap_atomic); | |
79 | /* | ||
80 | * This is the same as kmap_atomic() but can map memory that doesn't | ||
81 | * have a struct page associated with it. | ||
82 | */ | ||
83 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | ||
84 | { | ||
85 | return kmap_atomic_prot_pfn(pfn, type, kmap_prot); | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ | ||
88 | 102 | ||
89 | struct page *kmap_atomic_to_page(void *ptr) | 103 | struct page *kmap_atomic_to_page(void *ptr) |
90 | { | 104 | { |
@@ -98,12 +112,6 @@ struct page *kmap_atomic_to_page(void *ptr) | |||
98 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); | 112 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); |
99 | return pte_page(*pte); | 113 | return pte_page(*pte); |
100 | } | 114 | } |
101 | |||
102 | EXPORT_SYMBOL(kmap); | ||
103 | EXPORT_SYMBOL(kunmap); | ||
104 | EXPORT_SYMBOL(kmap_atomic); | ||
105 | EXPORT_SYMBOL(kunmap_atomic_notypecheck); | ||
106 | EXPORT_SYMBOL(kmap_atomic_prot); | ||
107 | EXPORT_SYMBOL(kmap_atomic_to_page); | 115 | EXPORT_SYMBOL(kmap_atomic_to_page); |
108 | 116 | ||
109 | void __init set_highmem_pages_init(void) | 117 | void __init set_highmem_pages_init(void) |