diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-10-26 17:21:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 19:52:08 -0400 |
commit | 3e4d3af501cccdc8a8cca41bdbe57d54ad7e7e73 (patch) | |
tree | 2ce507f7ec7275563653e52f18606aba4f99b7f1 | |
parent | 61ecdb801ef2cd28e32442383106d7837d76deac (diff) |
mm: stack based kmap_atomic()
Keep the current interface but ignore the KM_type and use a stack based
approach.
The advantage is that we get rid of crappy code like:
#define __KM_PTE \
(in_nmi() ? KM_NMI_PTE : \
in_irq() ? KM_IRQ_PTE : \
KM_PTE0)
and in general can stop worrying about what context we're in and what kmap
slots might be appropriate for that.
The downside is that FRV kmap_atomic() gets more expensive.
For now we use a CPP trick suggested by Andrew:
#define kmap_atomic(page, args...) __kmap_atomic(page)
to avoid having to touch all kmap_atomic() users in a single patch.
[ not compiled on:
- mn10300: the arch doesn't actually build with highmem to begin with ]
[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: fix up drivers/gpu/drm/i915/intel_overlay.c]
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: David Miller <davem@davemloft.net>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
28 files changed, 367 insertions, 372 deletions
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 5aff58126602..1fc684e70ab6 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h | |||
@@ -35,9 +35,9 @@ extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); | |||
35 | #ifdef CONFIG_HIGHMEM | 35 | #ifdef CONFIG_HIGHMEM |
36 | extern void *kmap(struct page *page); | 36 | extern void *kmap(struct page *page); |
37 | extern void kunmap(struct page *page); | 37 | extern void kunmap(struct page *page); |
38 | extern void *kmap_atomic(struct page *page, enum km_type type); | 38 | extern void *__kmap_atomic(struct page *page); |
39 | extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | 39 | extern void __kunmap_atomic(void *kvaddr); |
40 | extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 40 | extern void *kmap_atomic_pfn(unsigned long pfn); |
41 | extern struct page *kmap_atomic_to_page(const void *ptr); | 41 | extern struct page *kmap_atomic_to_page(const void *ptr); |
42 | #endif | 42 | #endif |
43 | 43 | ||
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 1fbdb55bfd1b..c00f119babbf 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c | |||
@@ -36,18 +36,17 @@ void kunmap(struct page *page) | |||
36 | } | 36 | } |
37 | EXPORT_SYMBOL(kunmap); | 37 | EXPORT_SYMBOL(kunmap); |
38 | 38 | ||
39 | void *kmap_atomic(struct page *page, enum km_type type) | 39 | void *__kmap_atomic(struct page *page) |
40 | { | 40 | { |
41 | unsigned int idx; | 41 | unsigned int idx; |
42 | unsigned long vaddr; | 42 | unsigned long vaddr; |
43 | void *kmap; | 43 | void *kmap; |
44 | int type; | ||
44 | 45 | ||
45 | pagefault_disable(); | 46 | pagefault_disable(); |
46 | if (!PageHighMem(page)) | 47 | if (!PageHighMem(page)) |
47 | return page_address(page); | 48 | return page_address(page); |
48 | 49 | ||
49 | debug_kmap_atomic(type); | ||
50 | |||
51 | #ifdef CONFIG_DEBUG_HIGHMEM | 50 | #ifdef CONFIG_DEBUG_HIGHMEM |
52 | /* | 51 | /* |
53 | * There is no cache coherency issue when non VIVT, so force the | 52 | * There is no cache coherency issue when non VIVT, so force the |
@@ -61,6 +60,8 @@ void *kmap_atomic(struct page *page, enum km_type type) | |||
61 | if (kmap) | 60 | if (kmap) |
62 | return kmap; | 61 | return kmap; |
63 | 62 | ||
63 | type = kmap_atomic_idx_push(); | ||
64 | |||
64 | idx = type + KM_TYPE_NR * smp_processor_id(); | 65 | idx = type + KM_TYPE_NR * smp_processor_id(); |
65 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 66 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
66 | #ifdef CONFIG_DEBUG_HIGHMEM | 67 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -80,14 +81,17 @@ void *kmap_atomic(struct page *page, enum km_type type) | |||
80 | 81 | ||
81 | return (void *)vaddr; | 82 | return (void *)vaddr; |
82 | } | 83 | } |
83 | EXPORT_SYMBOL(kmap_atomic); | 84 | EXPORT_SYMBOL(__kmap_atomic); |
84 | 85 | ||
85 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 86 | void __kunmap_atomic(void *kvaddr) |
86 | { | 87 | { |
87 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 88 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
88 | unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); | 89 | int idx, type; |
89 | 90 | ||
90 | if (kvaddr >= (void *)FIXADDR_START) { | 91 | if (kvaddr >= (void *)FIXADDR_START) { |
92 | type = kmap_atomic_idx_pop(); | ||
93 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
94 | |||
91 | if (cache_is_vivt()) | 95 | if (cache_is_vivt()) |
92 | __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); | 96 | __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); |
93 | #ifdef CONFIG_DEBUG_HIGHMEM | 97 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -103,15 +107,16 @@ void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | |||
103 | } | 107 | } |
104 | pagefault_enable(); | 108 | pagefault_enable(); |
105 | } | 109 | } |
106 | EXPORT_SYMBOL(kunmap_atomic_notypecheck); | 110 | EXPORT_SYMBOL(__kunmap_atomic); |
107 | 111 | ||
108 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | 112 | void *kmap_atomic_pfn(unsigned long pfn) |
109 | { | 113 | { |
110 | unsigned int idx; | ||
111 | unsigned long vaddr; | 114 | unsigned long vaddr; |
115 | int idx, type; | ||
112 | 116 | ||
113 | pagefault_disable(); | 117 | pagefault_disable(); |
114 | 118 | ||
119 | type = kmap_atomic_idx_push(); | ||
115 | idx = type + KM_TYPE_NR * smp_processor_id(); | 120 | idx = type + KM_TYPE_NR * smp_processor_id(); |
116 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 121 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
117 | #ifdef CONFIG_DEBUG_HIGHMEM | 122 | #ifdef CONFIG_DEBUG_HIGHMEM |
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h index cb4c317eaecc..a8d6565d415d 100644 --- a/arch/frv/include/asm/highmem.h +++ b/arch/frv/include/asm/highmem.h | |||
@@ -112,12 +112,11 @@ extern struct page *kmap_atomic_to_page(void *ptr); | |||
112 | (void *) damlr; \ | 112 | (void *) damlr; \ |
113 | }) | 113 | }) |
114 | 114 | ||
115 | static inline void *kmap_atomic(struct page *page, enum km_type type) | 115 | static inline void *kmap_atomic_primary(struct page *page, enum km_type type) |
116 | { | 116 | { |
117 | unsigned long paddr; | 117 | unsigned long paddr; |
118 | 118 | ||
119 | pagefault_disable(); | 119 | pagefault_disable(); |
120 | debug_kmap_atomic(type); | ||
121 | paddr = page_to_phys(page); | 120 | paddr = page_to_phys(page); |
122 | 121 | ||
123 | switch (type) { | 122 | switch (type) { |
@@ -125,14 +124,6 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) | |||
125 | case 1: return __kmap_atomic_primary(1, paddr, 3); | 124 | case 1: return __kmap_atomic_primary(1, paddr, 3); |
126 | case 2: return __kmap_atomic_primary(2, paddr, 4); | 125 | case 2: return __kmap_atomic_primary(2, paddr, 4); |
127 | case 3: return __kmap_atomic_primary(3, paddr, 5); | 126 | case 3: return __kmap_atomic_primary(3, paddr, 5); |
128 | case 4: return __kmap_atomic_primary(4, paddr, 6); | ||
129 | case 5: return __kmap_atomic_primary(5, paddr, 7); | ||
130 | case 6: return __kmap_atomic_primary(6, paddr, 8); | ||
131 | case 7: return __kmap_atomic_primary(7, paddr, 9); | ||
132 | case 8: return __kmap_atomic_primary(8, paddr, 10); | ||
133 | |||
134 | case 9 ... 9 + NR_TLB_LINES - 1: | ||
135 | return __kmap_atomic_secondary(type - 9, paddr); | ||
136 | 127 | ||
137 | default: | 128 | default: |
138 | BUG(); | 129 | BUG(); |
@@ -152,22 +143,13 @@ do { \ | |||
152 | asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ | 143 | asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ |
153 | } while(0) | 144 | } while(0) |
154 | 145 | ||
155 | static inline void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 146 | static inline void kunmap_atomic_primary(void *kvaddr, enum km_type type) |
156 | { | 147 | { |
157 | switch (type) { | 148 | switch (type) { |
158 | case 0: __kunmap_atomic_primary(0, 2); break; | 149 | case 0: __kunmap_atomic_primary(0, 2); break; |
159 | case 1: __kunmap_atomic_primary(1, 3); break; | 150 | case 1: __kunmap_atomic_primary(1, 3); break; |
160 | case 2: __kunmap_atomic_primary(2, 4); break; | 151 | case 2: __kunmap_atomic_primary(2, 4); break; |
161 | case 3: __kunmap_atomic_primary(3, 5); break; | 152 | case 3: __kunmap_atomic_primary(3, 5); break; |
162 | case 4: __kunmap_atomic_primary(4, 6); break; | ||
163 | case 5: __kunmap_atomic_primary(5, 7); break; | ||
164 | case 6: __kunmap_atomic_primary(6, 8); break; | ||
165 | case 7: __kunmap_atomic_primary(7, 9); break; | ||
166 | case 8: __kunmap_atomic_primary(8, 10); break; | ||
167 | |||
168 | case 9 ... 9 + NR_TLB_LINES - 1: | ||
169 | __kunmap_atomic_secondary(type - 9, kvaddr); | ||
170 | break; | ||
171 | 153 | ||
172 | default: | 154 | default: |
173 | BUG(); | 155 | BUG(); |
@@ -175,6 +157,9 @@ static inline void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | |||
175 | pagefault_enable(); | 157 | pagefault_enable(); |
176 | } | 158 | } |
177 | 159 | ||
160 | void *__kmap_atomic(struct page *page); | ||
161 | void __kunmap_atomic(void *kvaddr); | ||
162 | |||
178 | #endif /* !__ASSEMBLY__ */ | 163 | #endif /* !__ASSEMBLY__ */ |
179 | 164 | ||
180 | #endif /* __KERNEL__ */ | 165 | #endif /* __KERNEL__ */ |
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 85d110b71cf7..41098a3803a2 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c | |||
@@ -61,14 +61,14 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
61 | dampr2 = __get_DAMPR(2); | 61 | dampr2 = __get_DAMPR(2); |
62 | 62 | ||
63 | for (i = 0; i < nents; i++) { | 63 | for (i = 0; i < nents; i++) { |
64 | vaddr = kmap_atomic(sg_page(&sg[i]), __KM_CACHE); | 64 | vaddr = kmap_atomic_primary(sg_page(&sg[i]), __KM_CACHE); |
65 | 65 | ||
66 | frv_dcache_writeback((unsigned long) vaddr, | 66 | frv_dcache_writeback((unsigned long) vaddr, |
67 | (unsigned long) vaddr + PAGE_SIZE); | 67 | (unsigned long) vaddr + PAGE_SIZE); |
68 | 68 | ||
69 | } | 69 | } |
70 | 70 | ||
71 | kunmap_atomic(vaddr, __KM_CACHE); | 71 | kunmap_atomic_primary(vaddr, __KM_CACHE); |
72 | if (dampr2) { | 72 | if (dampr2) { |
73 | __set_DAMPR(2, dampr2); | 73 | __set_DAMPR(2, dampr2); |
74 | __set_IAMPR(2, dampr2); | 74 | __set_IAMPR(2, dampr2); |
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c index 0261cbe153b5..b24ade27a0f0 100644 --- a/arch/frv/mm/cache-page.c +++ b/arch/frv/mm/cache-page.c | |||
@@ -26,11 +26,11 @@ void flush_dcache_page(struct page *page) | |||
26 | 26 | ||
27 | dampr2 = __get_DAMPR(2); | 27 | dampr2 = __get_DAMPR(2); |
28 | 28 | ||
29 | vaddr = kmap_atomic(page, __KM_CACHE); | 29 | vaddr = kmap_atomic_primary(page, __KM_CACHE); |
30 | 30 | ||
31 | frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE); | 31 | frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE); |
32 | 32 | ||
33 | kunmap_atomic(vaddr, __KM_CACHE); | 33 | kunmap_atomic_primary(vaddr, __KM_CACHE); |
34 | 34 | ||
35 | if (dampr2) { | 35 | if (dampr2) { |
36 | __set_DAMPR(2, dampr2); | 36 | __set_DAMPR(2, dampr2); |
@@ -54,12 +54,12 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | |||
54 | 54 | ||
55 | dampr2 = __get_DAMPR(2); | 55 | dampr2 = __get_DAMPR(2); |
56 | 56 | ||
57 | vaddr = kmap_atomic(page, __KM_CACHE); | 57 | vaddr = kmap_atomic_primary(page, __KM_CACHE); |
58 | 58 | ||
59 | start = (start & ~PAGE_MASK) | (unsigned long) vaddr; | 59 | start = (start & ~PAGE_MASK) | (unsigned long) vaddr; |
60 | frv_cache_wback_inv(start, start + len); | 60 | frv_cache_wback_inv(start, start + len); |
61 | 61 | ||
62 | kunmap_atomic(vaddr, __KM_CACHE); | 62 | kunmap_atomic_primary(vaddr, __KM_CACHE); |
63 | 63 | ||
64 | if (dampr2) { | 64 | if (dampr2) { |
65 | __set_DAMPR(2, dampr2); | 65 | __set_DAMPR(2, dampr2); |
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c index eadd07658075..61088dcc1594 100644 --- a/arch/frv/mm/highmem.c +++ b/arch/frv/mm/highmem.c | |||
@@ -36,3 +36,53 @@ struct page *kmap_atomic_to_page(void *ptr) | |||
36 | { | 36 | { |
37 | return virt_to_page(ptr); | 37 | return virt_to_page(ptr); |
38 | } | 38 | } |
39 | |||
40 | void *__kmap_atomic(struct page *page) | ||
41 | { | ||
42 | unsigned long paddr; | ||
43 | int type; | ||
44 | |||
45 | pagefault_disable(); | ||
46 | type = kmap_atomic_idx_push(); | ||
47 | paddr = page_to_phys(page); | ||
48 | |||
49 | switch (type) { | ||
50 | /* | ||
51 | * The first 4 primary maps are reserved for architecture code | ||
52 | */ | ||
53 | case 0: return __kmap_atomic_primary(4, paddr, 6); | ||
54 | case 1: return __kmap_atomic_primary(5, paddr, 7); | ||
55 | case 2: return __kmap_atomic_primary(6, paddr, 8); | ||
56 | case 3: return __kmap_atomic_primary(7, paddr, 9); | ||
57 | case 4: return __kmap_atomic_primary(8, paddr, 10); | ||
58 | |||
59 | case 5 ... 5 + NR_TLB_LINES - 1: | ||
60 | return __kmap_atomic_secondary(type - 5, paddr); | ||
61 | |||
62 | default: | ||
63 | BUG(); | ||
64 | return NULL; | ||
65 | } | ||
66 | } | ||
67 | EXPORT_SYMBOL(__kmap_atomic); | ||
68 | |||
69 | void __kunmap_atomic(void *kvaddr) | ||
70 | { | ||
71 | int type = kmap_atomic_idx_pop(); | ||
72 | switch (type) { | ||
73 | case 0: __kunmap_atomic_primary(4, 6); break; | ||
74 | case 1: __kunmap_atomic_primary(5, 7); break; | ||
75 | case 2: __kunmap_atomic_primary(6, 8); break; | ||
76 | case 3: __kunmap_atomic_primary(7, 9); break; | ||
77 | case 4: __kunmap_atomic_primary(8, 10); break; | ||
78 | |||
79 | case 5 ... 5 + NR_TLB_LINES - 1: | ||
80 | __kunmap_atomic_secondary(type - 5, kvaddr); | ||
81 | break; | ||
82 | |||
83 | default: | ||
84 | BUG(); | ||
85 | } | ||
86 | pagefault_enable(); | ||
87 | } | ||
88 | EXPORT_SYMBOL(__kunmap_atomic); | ||
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 75753ca73bfd..77e644082a3b 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h | |||
@@ -45,18 +45,12 @@ extern pte_t *pkmap_page_table; | |||
45 | extern void * kmap_high(struct page *page); | 45 | extern void * kmap_high(struct page *page); |
46 | extern void kunmap_high(struct page *page); | 46 | extern void kunmap_high(struct page *page); |
47 | 47 | ||
48 | extern void *__kmap(struct page *page); | 48 | extern void *kmap(struct page *page); |
49 | extern void __kunmap(struct page *page); | 49 | extern void kunmap(struct page *page); |
50 | extern void *__kmap_atomic(struct page *page, enum km_type type); | 50 | extern void *__kmap_atomic(struct page *page); |
51 | extern void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | 51 | extern void __kunmap_atomic(void *kvaddr); |
52 | extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 52 | extern void *kmap_atomic_pfn(unsigned long pfn); |
53 | extern struct page *__kmap_atomic_to_page(void *ptr); | 53 | extern struct page *kmap_atomic_to_page(void *ptr); |
54 | |||
55 | #define kmap __kmap | ||
56 | #define kunmap __kunmap | ||
57 | #define kmap_atomic __kmap_atomic | ||
58 | #define kunmap_atomic_notypecheck __kunmap_atomic_notypecheck | ||
59 | #define kmap_atomic_to_page __kmap_atomic_to_page | ||
60 | 54 | ||
61 | #define flush_cache_kmaps() flush_cache_all() | 55 | #define flush_cache_kmaps() flush_cache_all() |
62 | 56 | ||
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 6a2b1bf9ef11..1e69b1fb4b85 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c | |||
@@ -9,7 +9,7 @@ static pte_t *kmap_pte; | |||
9 | 9 | ||
10 | unsigned long highstart_pfn, highend_pfn; | 10 | unsigned long highstart_pfn, highend_pfn; |
11 | 11 | ||
12 | void *__kmap(struct page *page) | 12 | void *kmap(struct page *page) |
13 | { | 13 | { |
14 | void *addr; | 14 | void *addr; |
15 | 15 | ||
@@ -21,16 +21,16 @@ void *__kmap(struct page *page) | |||
21 | 21 | ||
22 | return addr; | 22 | return addr; |
23 | } | 23 | } |
24 | EXPORT_SYMBOL(__kmap); | 24 | EXPORT_SYMBOL(kmap); |
25 | 25 | ||
26 | void __kunmap(struct page *page) | 26 | void kunmap(struct page *page) |
27 | { | 27 | { |
28 | BUG_ON(in_interrupt()); | 28 | BUG_ON(in_interrupt()); |
29 | if (!PageHighMem(page)) | 29 | if (!PageHighMem(page)) |
30 | return; | 30 | return; |
31 | kunmap_high(page); | 31 | kunmap_high(page); |
32 | } | 32 | } |
33 | EXPORT_SYMBOL(__kunmap); | 33 | EXPORT_SYMBOL(kunmap); |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because | 36 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because |
@@ -41,17 +41,17 @@ EXPORT_SYMBOL(__kunmap); | |||
41 | * kmaps are appropriate for short, tight code paths only. | 41 | * kmaps are appropriate for short, tight code paths only. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | void *__kmap_atomic(struct page *page, enum km_type type) | 44 | void *__kmap_atomic(struct page *page) |
45 | { | 45 | { |
46 | enum fixed_addresses idx; | ||
47 | unsigned long vaddr; | 46 | unsigned long vaddr; |
47 | int idx, type; | ||
48 | 48 | ||
49 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | 49 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ |
50 | pagefault_disable(); | 50 | pagefault_disable(); |
51 | if (!PageHighMem(page)) | 51 | if (!PageHighMem(page)) |
52 | return page_address(page); | 52 | return page_address(page); |
53 | 53 | ||
54 | debug_kmap_atomic(type); | 54 | type = kmap_atomic_idx_push(); |
55 | idx = type + KM_TYPE_NR*smp_processor_id(); | 55 | idx = type + KM_TYPE_NR*smp_processor_id(); |
56 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 56 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
57 | #ifdef CONFIG_DEBUG_HIGHMEM | 57 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -64,43 +64,47 @@ void *__kmap_atomic(struct page *page, enum km_type type) | |||
64 | } | 64 | } |
65 | EXPORT_SYMBOL(__kmap_atomic); | 65 | EXPORT_SYMBOL(__kmap_atomic); |
66 | 66 | ||
67 | void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 67 | void __kunmap_atomic(void *kvaddr) |
68 | { | 68 | { |
69 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
70 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 69 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
71 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | 70 | int type; |
72 | 71 | ||
73 | if (vaddr < FIXADDR_START) { // FIXME | 72 | if (vaddr < FIXADDR_START) { // FIXME |
74 | pagefault_enable(); | 73 | pagefault_enable(); |
75 | return; | 74 | return; |
76 | } | 75 | } |
77 | 76 | ||
78 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | 77 | type = kmap_atomic_idx_pop(); |
78 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
79 | { | ||
80 | int idx = type + KM_TYPE_NR * smp_processor_id(); | ||
79 | 81 | ||
80 | /* | 82 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); |
81 | * force other mappings to Oops if they'll try to access | ||
82 | * this pte without first remap it | ||
83 | */ | ||
84 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | ||
85 | local_flush_tlb_one(vaddr); | ||
86 | #endif | ||
87 | 83 | ||
84 | /* | ||
85 | * force other mappings to Oops if they'll try to access | ||
86 | * this pte without first remap it | ||
87 | */ | ||
88 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | ||
89 | local_flush_tlb_one(vaddr); | ||
90 | } | ||
91 | #endif | ||
88 | pagefault_enable(); | 92 | pagefault_enable(); |
89 | } | 93 | } |
90 | EXPORT_SYMBOL(__kunmap_atomic_notypecheck); | 94 | EXPORT_SYMBOL(__kunmap_atomic); |
91 | 95 | ||
92 | /* | 96 | /* |
93 | * This is the same as kmap_atomic() but can map memory that doesn't | 97 | * This is the same as kmap_atomic() but can map memory that doesn't |
94 | * have a struct page associated with it. | 98 | * have a struct page associated with it. |
95 | */ | 99 | */ |
96 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | 100 | void *kmap_atomic_pfn(unsigned long pfn) |
97 | { | 101 | { |
98 | enum fixed_addresses idx; | ||
99 | unsigned long vaddr; | 102 | unsigned long vaddr; |
103 | int idx, type; | ||
100 | 104 | ||
101 | pagefault_disable(); | 105 | pagefault_disable(); |
102 | 106 | ||
103 | debug_kmap_atomic(type); | 107 | type = kmap_atomic_idx_push(); |
104 | idx = type + KM_TYPE_NR*smp_processor_id(); | 108 | idx = type + KM_TYPE_NR*smp_processor_id(); |
105 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 109 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
106 | set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL)); | 110 | set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL)); |
@@ -109,7 +113,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | |||
109 | return (void*) vaddr; | 113 | return (void*) vaddr; |
110 | } | 114 | } |
111 | 115 | ||
112 | struct page *__kmap_atomic_to_page(void *ptr) | 116 | struct page *kmap_atomic_to_page(void *ptr) |
113 | { | 117 | { |
114 | unsigned long idx, vaddr = (unsigned long)ptr; | 118 | unsigned long idx, vaddr = (unsigned long)ptr; |
115 | pte_t *pte; | 119 | pte_t *pte; |
diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h index b0b187a29b88..f577ba2268ca 100644 --- a/arch/mn10300/include/asm/highmem.h +++ b/arch/mn10300/include/asm/highmem.h | |||
@@ -70,15 +70,16 @@ static inline void kunmap(struct page *page) | |||
70 | * be used in IRQ contexts, so in some (very limited) cases we need | 70 | * be used in IRQ contexts, so in some (very limited) cases we need |
71 | * it. | 71 | * it. |
72 | */ | 72 | */ |
73 | static inline unsigned long kmap_atomic(struct page *page, enum km_type type) | 73 | static inline unsigned long __kmap_atomic(struct page *page) |
74 | { | 74 | { |
75 | enum fixed_addresses idx; | ||
76 | unsigned long vaddr; | 75 | unsigned long vaddr; |
76 | int idx, type; | ||
77 | 77 | ||
78 | pagefault_disable(); | ||
78 | if (page < highmem_start_page) | 79 | if (page < highmem_start_page) |
79 | return page_address(page); | 80 | return page_address(page); |
80 | 81 | ||
81 | debug_kmap_atomic(type); | 82 | type = kmap_atomic_idx_push(); |
82 | idx = type + KM_TYPE_NR * smp_processor_id(); | 83 | idx = type + KM_TYPE_NR * smp_processor_id(); |
83 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 84 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
84 | #if HIGHMEM_DEBUG | 85 | #if HIGHMEM_DEBUG |
@@ -91,26 +92,35 @@ static inline unsigned long kmap_atomic(struct page *page, enum km_type type) | |||
91 | return vaddr; | 92 | return vaddr; |
92 | } | 93 | } |
93 | 94 | ||
94 | static inline void kunmap_atomic_notypecheck(unsigned long vaddr, enum km_type type) | 95 | static inline void __kunmap_atomic(unsigned long vaddr) |
95 | { | 96 | { |
96 | #if HIGHMEM_DEBUG | 97 | int type; |
97 | enum fixed_addresses idx = type + KM_TYPE_NR * smp_processor_id(); | ||
98 | 98 | ||
99 | if (vaddr < FIXADDR_START) /* FIXME */ | 99 | if (vaddr < FIXADDR_START) { /* FIXME */ |
100 | pagefault_enable(); | ||
100 | return; | 101 | return; |
102 | } | ||
101 | 103 | ||
102 | if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)) | 104 | type = kmap_atomic_idx_pop(); |
103 | BUG(); | ||
104 | 105 | ||
105 | /* | 106 | #if HIGHMEM_DEBUG |
106 | * force other mappings to Oops if they'll try to access | 107 | { |
107 | * this pte without first remap it | 108 | unsigned int idx; |
108 | */ | 109 | idx = type + KM_TYPE_NR * smp_processor_id(); |
109 | pte_clear(kmap_pte - idx); | 110 | |
110 | __flush_tlb_one(vaddr); | 111 | if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)) |
112 | BUG(); | ||
113 | |||
114 | /* | ||
115 | * force other mappings to Oops if they'll try to access | ||
116 | * this pte without first remap it | ||
117 | */ | ||
118 | pte_clear(kmap_pte - idx); | ||
119 | __flush_tlb_one(vaddr); | ||
120 | } | ||
111 | #endif | 121 | #endif |
122 | pagefault_enable(); | ||
112 | } | 123 | } |
113 | |||
114 | #endif /* __KERNEL__ */ | 124 | #endif /* __KERNEL__ */ |
115 | 125 | ||
116 | #endif /* _ASM_HIGHMEM_H */ | 126 | #endif /* _ASM_HIGHMEM_H */ |
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index d10d64a4be38..dbc264010d0b 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h | |||
@@ -60,9 +60,8 @@ extern pte_t *pkmap_page_table; | |||
60 | 60 | ||
61 | extern void *kmap_high(struct page *page); | 61 | extern void *kmap_high(struct page *page); |
62 | extern void kunmap_high(struct page *page); | 62 | extern void kunmap_high(struct page *page); |
63 | extern void *kmap_atomic_prot(struct page *page, enum km_type type, | 63 | extern void *kmap_atomic_prot(struct page *page, pgprot_t prot); |
64 | pgprot_t prot); | 64 | extern void __kunmap_atomic(void *kvaddr); |
65 | extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | ||
66 | 65 | ||
67 | static inline void *kmap(struct page *page) | 66 | static inline void *kmap(struct page *page) |
68 | { | 67 | { |
@@ -80,9 +79,9 @@ static inline void kunmap(struct page *page) | |||
80 | kunmap_high(page); | 79 | kunmap_high(page); |
81 | } | 80 | } |
82 | 81 | ||
83 | static inline void *kmap_atomic(struct page *page, enum km_type type) | 82 | static inline void *__kmap_atomic(struct page *page) |
84 | { | 83 | { |
85 | return kmap_atomic_prot(page, type, kmap_prot); | 84 | return kmap_atomic_prot(page, kmap_prot); |
86 | } | 85 | } |
87 | 86 | ||
88 | static inline struct page *kmap_atomic_to_page(void *ptr) | 87 | static inline struct page *kmap_atomic_to_page(void *ptr) |
diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c index 857d4173f9c6..b0848b462bbc 100644 --- a/arch/powerpc/mm/highmem.c +++ b/arch/powerpc/mm/highmem.c | |||
@@ -29,17 +29,17 @@ | |||
29 | * be used in IRQ contexts, so in some (very limited) cases we need | 29 | * be used in IRQ contexts, so in some (very limited) cases we need |
30 | * it. | 30 | * it. |
31 | */ | 31 | */ |
32 | 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) |
33 | { | 33 | { |
34 | unsigned int idx; | ||
35 | unsigned long vaddr; | 34 | unsigned long vaddr; |
35 | int idx, type; | ||
36 | 36 | ||
37 | /* 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 */ |
38 | pagefault_disable(); | 38 | pagefault_disable(); |
39 | if (!PageHighMem(page)) | 39 | if (!PageHighMem(page)) |
40 | return page_address(page); | 40 | return page_address(page); |
41 | 41 | ||
42 | debug_kmap_atomic(type); | 42 | type = kmap_atomic_idx_push(); |
43 | idx = type + KM_TYPE_NR*smp_processor_id(); | 43 | idx = type + KM_TYPE_NR*smp_processor_id(); |
44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
45 | #ifdef CONFIG_DEBUG_HIGHMEM | 45 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -52,26 +52,33 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
52 | } | 52 | } |
53 | EXPORT_SYMBOL(kmap_atomic_prot); | 53 | EXPORT_SYMBOL(kmap_atomic_prot); |
54 | 54 | ||
55 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 55 | void __kunmap_atomic(void *kvaddr) |
56 | { | 56 | { |
57 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
58 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 57 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
59 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | 58 | int type; |
60 | 59 | ||
61 | if (vaddr < __fix_to_virt(FIX_KMAP_END)) { | 60 | if (vaddr < __fix_to_virt(FIX_KMAP_END)) { |
62 | pagefault_enable(); | 61 | pagefault_enable(); |
63 | return; | 62 | return; |
64 | } | 63 | } |
65 | 64 | ||
66 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | 65 | type = kmap_atomic_idx_pop(); |
67 | 66 | ||
68 | /* | 67 | #ifdef CONFIG_DEBUG_HIGHMEM |
69 | * force other mappings to Oops if they'll try to access | 68 | { |
70 | * this pte without first remap it | 69 | unsigned int idx; |
71 | */ | 70 | |
72 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | 71 | idx = type + KM_TYPE_NR * smp_processor_id(); |
73 | local_flush_tlb_page(NULL, vaddr); | 72 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); |
73 | |||
74 | /* | ||
75 | * force other mappings to Oops if they'll try to access | ||
76 | * this pte without first remap it | ||
77 | */ | ||
78 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | ||
79 | local_flush_tlb_page(NULL, vaddr); | ||
80 | } | ||
74 | #endif | 81 | #endif |
75 | pagefault_enable(); | 82 | pagefault_enable(); |
76 | } | 83 | } |
77 | EXPORT_SYMBOL(kunmap_atomic_notypecheck); | 84 | EXPORT_SYMBOL(__kunmap_atomic); |
diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index ec23b0a87b98..3d7afbb7f4bb 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h | |||
@@ -70,8 +70,8 @@ static inline void kunmap(struct page *page) | |||
70 | kunmap_high(page); | 70 | kunmap_high(page); |
71 | } | 71 | } |
72 | 72 | ||
73 | extern void *kmap_atomic(struct page *page, enum km_type type); | 73 | extern void *__kmap_atomic(struct page *page); |
74 | extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | 74 | extern void __kunmap_atomic(void *kvaddr); |
75 | extern struct page *kmap_atomic_to_page(void *vaddr); | 75 | extern struct page *kmap_atomic_to_page(void *vaddr); |
76 | 76 | ||
77 | #define flush_cache_kmaps() flush_cache_all() | 77 | #define flush_cache_kmaps() flush_cache_all() |
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index e139e9cbf5f7..5e50c09b7dce 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c | |||
@@ -29,17 +29,17 @@ | |||
29 | #include <asm/tlbflush.h> | 29 | #include <asm/tlbflush.h> |
30 | #include <asm/fixmap.h> | 30 | #include <asm/fixmap.h> |
31 | 31 | ||
32 | void *kmap_atomic(struct page *page, enum km_type type) | 32 | void *__kmap_atomic(struct page *page) |
33 | { | 33 | { |
34 | unsigned long idx; | ||
35 | unsigned long vaddr; | 34 | unsigned long vaddr; |
35 | long idx, type; | ||
36 | 36 | ||
37 | /* 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 */ |
38 | pagefault_disable(); | 38 | pagefault_disable(); |
39 | if (!PageHighMem(page)) | 39 | if (!PageHighMem(page)) |
40 | return page_address(page); | 40 | return page_address(page); |
41 | 41 | ||
42 | debug_kmap_atomic(type); | 42 | type = kmap_atomic_idx_push(); |
43 | idx = type + KM_TYPE_NR*smp_processor_id(); | 43 | idx = type + KM_TYPE_NR*smp_processor_id(); |
44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
45 | 45 | ||
@@ -63,44 +63,50 @@ void *kmap_atomic(struct page *page, enum km_type type) | |||
63 | 63 | ||
64 | return (void*) vaddr; | 64 | return (void*) vaddr; |
65 | } | 65 | } |
66 | EXPORT_SYMBOL(kmap_atomic); | 66 | EXPORT_SYMBOL(__kmap_atomic); |
67 | 67 | ||
68 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 68 | void __kunmap_atomic(void *kvaddr) |
69 | { | 69 | { |
70 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
71 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 70 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
72 | unsigned long idx = type + KM_TYPE_NR*smp_processor_id(); | 71 | int type; |
73 | 72 | ||
74 | if (vaddr < FIXADDR_START) { // FIXME | 73 | if (vaddr < FIXADDR_START) { // FIXME |
75 | pagefault_enable(); | 74 | pagefault_enable(); |
76 | return; | 75 | return; |
77 | } | 76 | } |
78 | 77 | ||
79 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)); | 78 | type = kmap_atomic_idx_pop(); |
80 | 79 | ||
81 | /* XXX Fix - Anton */ | 80 | #ifdef CONFIG_DEBUG_HIGHMEM |
81 | { | ||
82 | unsigned long idx; | ||
83 | |||
84 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
85 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)); | ||
86 | |||
87 | /* XXX Fix - Anton */ | ||
82 | #if 0 | 88 | #if 0 |
83 | __flush_cache_one(vaddr); | 89 | __flush_cache_one(vaddr); |
84 | #else | 90 | #else |
85 | flush_cache_all(); | 91 | flush_cache_all(); |
86 | #endif | 92 | #endif |
87 | 93 | ||
88 | /* | 94 | /* |
89 | * force other mappings to Oops if they'll try to access | 95 | * force other mappings to Oops if they'll try to access |
90 | * this pte without first remap it | 96 | * this pte without first remap it |
91 | */ | 97 | */ |
92 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | 98 | pte_clear(&init_mm, vaddr, kmap_pte-idx); |
93 | /* XXX Fix - Anton */ | 99 | /* XXX Fix - Anton */ |
94 | #if 0 | 100 | #if 0 |
95 | __flush_tlb_one(vaddr); | 101 | __flush_tlb_one(vaddr); |
96 | #else | 102 | #else |
97 | flush_tlb_all(); | 103 | flush_tlb_all(); |
98 | #endif | 104 | #endif |
105 | } | ||
99 | #endif | 106 | #endif |
100 | |||
101 | pagefault_enable(); | 107 | pagefault_enable(); |
102 | } | 108 | } |
103 | EXPORT_SYMBOL(kunmap_atomic_notypecheck); | 109 | EXPORT_SYMBOL(__kunmap_atomic); |
104 | 110 | ||
105 | /* We may be fed a pagetable here by ptep_to_xxx and others. */ | 111 | /* We may be fed a pagetable here by ptep_to_xxx and others. */ |
106 | struct page *kmap_atomic_to_page(void *ptr) | 112 | struct page *kmap_atomic_to_page(void *ptr) |
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h index d155db6fa9bd..e0f7ee186721 100644 --- a/arch/tile/include/asm/highmem.h +++ b/arch/tile/include/asm/highmem.h | |||
@@ -60,12 +60,12 @@ void *kmap_fix_kpte(struct page *page, int finished); | |||
60 | /* This macro is used only in map_new_virtual() to map "page". */ | 60 | /* This macro is used only in map_new_virtual() to map "page". */ |
61 | #define kmap_prot page_to_kpgprot(page) | 61 | #define kmap_prot page_to_kpgprot(page) |
62 | 62 | ||
63 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | 63 | void *__kmap_atomic(struct page *page); |
64 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 64 | void __kunmap_atomic(void *kvaddr); |
65 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); | 65 | void *kmap_atomic_pfn(unsigned long pfn); |
66 | void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot); | ||
66 | struct page *kmap_atomic_to_page(void *ptr); | 67 | struct page *kmap_atomic_to_page(void *ptr); |
67 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); | 68 | void *kmap_atomic_prot(struct page *page, pgprot_t prot); |
68 | void *kmap_atomic(struct page *page, enum km_type type); | ||
69 | void kmap_atomic_fix_kpte(struct page *page, int finished); | 69 | void kmap_atomic_fix_kpte(struct page *page, int finished); |
70 | 70 | ||
71 | #define flush_cache_kmaps() do { } while (0) | 71 | #define flush_cache_kmaps() do { } while (0) |
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index 12ab137e7d4f..8ef6595e162c 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c | |||
@@ -56,50 +56,6 @@ void kunmap(struct page *page) | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL(kunmap); | 57 | EXPORT_SYMBOL(kunmap); |
58 | 58 | ||
59 | static void debug_kmap_atomic_prot(enum km_type type) | ||
60 | { | ||
61 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
62 | static unsigned warn_count = 10; | ||
63 | |||
64 | if (unlikely(warn_count == 0)) | ||
65 | return; | ||
66 | |||
67 | if (unlikely(in_interrupt())) { | ||
68 | if (in_irq()) { | ||
69 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
70 | type != KM_BIO_SRC_IRQ && | ||
71 | /* type != KM_BIO_DST_IRQ && */ | ||
72 | type != KM_BOUNCE_READ) { | ||
73 | WARN_ON(1); | ||
74 | warn_count--; | ||
75 | } | ||
76 | } else if (!irqs_disabled()) { /* softirq */ | ||
77 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
78 | type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && | ||
79 | type != KM_SKB_SUNRPC_DATA && | ||
80 | type != KM_SKB_DATA_SOFTIRQ && | ||
81 | type != KM_BOUNCE_READ) { | ||
82 | WARN_ON(1); | ||
83 | warn_count--; | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || | ||
89 | type == KM_BIO_SRC_IRQ /* || type == KM_BIO_DST_IRQ */) { | ||
90 | if (!irqs_disabled()) { | ||
91 | WARN_ON(1); | ||
92 | warn_count--; | ||
93 | } | ||
94 | } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { | ||
95 | if (irq_count() == 0 && !irqs_disabled()) { | ||
96 | WARN_ON(1); | ||
97 | warn_count--; | ||
98 | } | ||
99 | } | ||
100 | #endif | ||
101 | } | ||
102 | |||
103 | /* | 59 | /* |
104 | * Describe a single atomic mapping of a page on a given cpu at a | 60 | * Describe a single atomic mapping of a page on a given cpu at a |
105 | * given address, and allow it to be linked into a list. | 61 | * given address, and allow it to be linked into a list. |
@@ -240,10 +196,10 @@ void kmap_atomic_fix_kpte(struct page *page, int finished) | |||
240 | * When holding an atomic kmap is is not legal to sleep, so atomic | 196 | * When holding an atomic kmap is is not legal to sleep, so atomic |
241 | * kmaps are appropriate for short, tight code paths only. | 197 | * kmaps are appropriate for short, tight code paths only. |
242 | */ | 198 | */ |
243 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | 199 | void *kmap_atomic_prot(struct page *page, pgprot_t prot) |
244 | { | 200 | { |
245 | enum fixed_addresses idx; | ||
246 | unsigned long vaddr; | 201 | unsigned long vaddr; |
202 | int idx, type; | ||
247 | pte_t *pte; | 203 | pte_t *pte; |
248 | 204 | ||
249 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | 205 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ |
@@ -255,8 +211,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
255 | if (!PageHighMem(page)) | 211 | if (!PageHighMem(page)) |
256 | return page_address(page); | 212 | return page_address(page); |
257 | 213 | ||
258 | debug_kmap_atomic_prot(type); | 214 | type = kmap_atomic_idx_push(); |
259 | |||
260 | idx = type + KM_TYPE_NR*smp_processor_id(); | 215 | idx = type + KM_TYPE_NR*smp_processor_id(); |
261 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 216 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
262 | pte = kmap_get_pte(vaddr); | 217 | pte = kmap_get_pte(vaddr); |
@@ -269,25 +224,31 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
269 | } | 224 | } |
270 | EXPORT_SYMBOL(kmap_atomic_prot); | 225 | EXPORT_SYMBOL(kmap_atomic_prot); |
271 | 226 | ||
272 | void *kmap_atomic(struct page *page, enum km_type type) | 227 | void *__kmap_atomic(struct page *page) |
273 | { | 228 | { |
274 | /* PAGE_NONE is a magic value that tells us to check immutability. */ | 229 | /* PAGE_NONE is a magic value that tells us to check immutability. */ |
275 | return kmap_atomic_prot(page, type, PAGE_NONE); | 230 | return kmap_atomic_prot(page, type, PAGE_NONE); |
276 | } | 231 | } |
277 | EXPORT_SYMBOL(kmap_atomic); | 232 | EXPORT_SYMBOL(__kmap_atomic); |
278 | 233 | ||
279 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | 234 | void __kunmap_atomic(void *kvaddr) |
280 | { | 235 | { |
281 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 236 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
282 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
283 | 237 | ||
284 | /* | 238 | if (vaddr >= __fix_to_virt(FIX_KMAP_END) && |
285 | * Force other mappings to Oops if they try to access this pte without | 239 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { |
286 | * first remapping it. Keeping stale mappings around is a bad idea. | ||
287 | */ | ||
288 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) { | ||
289 | pte_t *pte = kmap_get_pte(vaddr); | 240 | pte_t *pte = kmap_get_pte(vaddr); |
290 | pte_t pteval = *pte; | 241 | pte_t pteval = *pte; |
242 | int idx, type; | ||
243 | |||
244 | type = kmap_atomic_idx_pop(); | ||
245 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
246 | |||
247 | /* | ||
248 | * Force other mappings to Oops if they try to access this pte | ||
249 | * without first remapping it. Keeping stale mappings around | ||
250 | * is a bad idea. | ||
251 | */ | ||
291 | BUG_ON(!pte_present(pteval) && !pte_migrating(pteval)); | 252 | BUG_ON(!pte_present(pteval) && !pte_migrating(pteval)); |
292 | kmap_atomic_unregister(pte_page(pteval), vaddr); | 253 | kmap_atomic_unregister(pte_page(pteval), vaddr); |
293 | kpte_clear_flush(pte, vaddr); | 254 | kpte_clear_flush(pte, vaddr); |
@@ -300,19 +261,19 @@ void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) | |||
300 | arch_flush_lazy_mmu_mode(); | 261 | arch_flush_lazy_mmu_mode(); |
301 | pagefault_enable(); | 262 | pagefault_enable(); |
302 | } | 263 | } |
303 | EXPORT_SYMBOL(kunmap_atomic_notypecheck); | 264 | EXPORT_SYMBOL(__kunmap_atomic); |
304 | 265 | ||
305 | /* | 266 | /* |
306 | * This API is supposed to allow us to map memory without a "struct page". | 267 | * This API is supposed to allow us to map memory without a "struct page". |
307 | * Currently we don't support this, though this may change in the future. | 268 | * Currently we don't support this, though this may change in the future. |
308 | */ | 269 | */ |
309 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | 270 | void *kmap_atomic_pfn(unsigned long pfn) |
310 | { | 271 | { |
311 | return kmap_atomic(pfn_to_page(pfn), type); | 272 | return kmap_atomic(pfn_to_page(pfn)); |
312 | } | 273 | } |
313 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | 274 | void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) |
314 | { | 275 | { |
315 | return kmap_atomic_prot(pfn_to_page(pfn), type, prot); | 276 | return kmap_atomic_prot(pfn_to_page(pfn), prot); |
316 | } | 277 | } |
317 | 278 | ||
318 | struct page *kmap_atomic_to_page(void *ptr) | 279 | struct page *kmap_atomic_to_page(void *ptr) |
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h index 8caac76ac324..3bd04022fd0c 100644 --- a/arch/x86/include/asm/highmem.h +++ b/arch/x86/include/asm/highmem.h | |||
@@ -59,11 +59,12 @@ extern void kunmap_high(struct page *page); | |||
59 | 59 | ||
60 | void *kmap(struct page *page); | 60 | void *kmap(struct page *page); |
61 | void kunmap(struct page *page); | 61 | void kunmap(struct page *page); |
62 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); | 62 | |
63 | void *kmap_atomic(struct page *page, enum km_type type); | 63 | void *kmap_atomic_prot(struct page *page, pgprot_t prot); |
64 | void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); | 64 | void *__kmap_atomic(struct page *page); |
65 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 65 | void __kunmap_atomic(void *kvaddr); |
66 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); | 66 | void *kmap_atomic_pfn(unsigned long pfn); |
67 | void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot); | ||
67 | struct page *kmap_atomic_to_page(void *ptr); | 68 | struct page *kmap_atomic_to_page(void *ptr); |
68 | 69 | ||
69 | #define flush_cache_kmaps() do { } while (0) | 70 | #define flush_cache_kmaps() do { } while (0) |
diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h index c4191b3b7056..363e33eb6ec1 100644 --- a/arch/x86/include/asm/iomap.h +++ b/arch/x86/include/asm/iomap.h | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <asm/tlbflush.h> | 27 | #include <asm/tlbflush.h> |
28 | 28 | ||
29 | void __iomem * | 29 | void __iomem * |
30 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); | 30 | iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot); |
31 | 31 | ||
32 | void | 32 | void |
33 | iounmap_atomic(void __iomem *kvaddr, enum km_type type); | 33 | iounmap_atomic(void __iomem *kvaddr); |
34 | 34 | ||
35 | int | 35 | int |
36 | iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot); | 36 | iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot); |
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index 67414550c3cc..d5cd13945d5a 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c | |||
@@ -61,7 +61,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
61 | if (!is_crashed_pfn_valid(pfn)) | 61 | if (!is_crashed_pfn_valid(pfn)) |
62 | return -EFAULT; | 62 | return -EFAULT; |
63 | 63 | ||
64 | vaddr = kmap_atomic_pfn(pfn, KM_PTE0); | 64 | vaddr = kmap_atomic_pfn(pfn); |
65 | 65 | ||
66 | if (!userbuf) { | 66 | if (!userbuf) { |
67 | memcpy(buf, (vaddr + offset), csize); | 67 | memcpy(buf, (vaddr + offset), csize); |
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 5e8fa12ef861..d723e369003c 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,56 @@ 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_pop(); |
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 | } |
70 | #ifdef CONFIG_DEBUG_HIGHMEM | 91 | #ifdef CONFIG_DEBUG_HIGHMEM |
92 | else { | ||
71 | BUG_ON(vaddr < PAGE_OFFSET); | 93 | BUG_ON(vaddr < PAGE_OFFSET); |
72 | BUG_ON(vaddr >= (unsigned long)high_memory); | 94 | BUG_ON(vaddr >= (unsigned long)high_memory); |
73 | #endif | ||
74 | } | 95 | } |
96 | #endif | ||
75 | 97 | ||
76 | pagefault_enable(); | 98 | pagefault_enable(); |
77 | } | 99 | } |
78 | 100 | 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 | 101 | ||
89 | struct page *kmap_atomic_to_page(void *ptr) | 102 | struct page *kmap_atomic_to_page(void *ptr) |
90 | { | 103 | { |
@@ -98,12 +111,6 @@ struct page *kmap_atomic_to_page(void *ptr) | |||
98 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); | 111 | pte = kmap_pte - (idx - FIX_KMAP_BEGIN); |
99 | return pte_page(*pte); | 112 | return pte_page(*pte); |
100 | } | 113 | } |
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); | 114 | EXPORT_SYMBOL(kmap_atomic_to_page); |
108 | 115 | ||
109 | void __init set_highmem_pages_init(void) | 116 | void __init set_highmem_pages_init(void) |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 72fc70cf6184..75a3d7f24a2c 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c | |||
@@ -48,21 +48,20 @@ int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot) | |||
48 | } | 48 | } |
49 | EXPORT_SYMBOL_GPL(iomap_create_wc); | 49 | EXPORT_SYMBOL_GPL(iomap_create_wc); |
50 | 50 | ||
51 | void | 51 | void iomap_free(resource_size_t base, unsigned long size) |
52 | iomap_free(resource_size_t base, unsigned long size) | ||
53 | { | 52 | { |
54 | io_free_memtype(base, base + size); | 53 | io_free_memtype(base, base + size); |
55 | } | 54 | } |
56 | EXPORT_SYMBOL_GPL(iomap_free); | 55 | EXPORT_SYMBOL_GPL(iomap_free); |
57 | 56 | ||
58 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | 57 | void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) |
59 | { | 58 | { |
60 | enum fixed_addresses idx; | ||
61 | unsigned long vaddr; | 59 | unsigned long vaddr; |
60 | int idx, type; | ||
62 | 61 | ||
63 | pagefault_disable(); | 62 | pagefault_disable(); |
64 | 63 | ||
65 | debug_kmap_atomic(type); | 64 | type = kmap_atomic_idx_push(); |
66 | idx = type + KM_TYPE_NR * smp_processor_id(); | 65 | idx = type + KM_TYPE_NR * smp_processor_id(); |
67 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 66 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
68 | set_pte(kmap_pte - idx, pfn_pte(pfn, prot)); | 67 | set_pte(kmap_pte - idx, pfn_pte(pfn, prot)); |
@@ -72,10 +71,10 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | |||
72 | } | 71 | } |
73 | 72 | ||
74 | /* | 73 | /* |
75 | * Map 'pfn' using fixed map 'type' and protections 'prot' | 74 | * Map 'pfn' using protections 'prot' |
76 | */ | 75 | */ |
77 | void __iomem * | 76 | void __iomem * |
78 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | 77 | iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) |
79 | { | 78 | { |
80 | /* | 79 | /* |
81 | * For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS. | 80 | * For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS. |
@@ -86,24 +85,33 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | |||
86 | if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) | 85 | if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) |
87 | prot = PAGE_KERNEL_UC_MINUS; | 86 | prot = PAGE_KERNEL_UC_MINUS; |
88 | 87 | ||
89 | return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, type, prot); | 88 | return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, prot); |
90 | } | 89 | } |
91 | EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); | 90 | EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); |
92 | 91 | ||
93 | void | 92 | void |
94 | iounmap_atomic(void __iomem *kvaddr, enum km_type type) | 93 | iounmap_atomic(void __iomem *kvaddr) |
95 | { | 94 | { |
96 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 95 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
97 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
98 | 96 | ||
99 | /* | 97 | if (vaddr >= __fix_to_virt(FIX_KMAP_END) && |
100 | * Force other mappings to Oops if they'll try to access this pte | 98 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { |
101 | * without first remap it. Keeping stale mappings around is a bad idea | 99 | int idx, type; |
102 | * also, in case the page changes cacheability attributes or becomes | 100 | |
103 | * a protected page in a hypervisor. | 101 | type = kmap_atomic_idx_pop(); |
104 | */ | 102 | idx = type + KM_TYPE_NR * smp_processor_id(); |
105 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | 103 | |
104 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
105 | WARN_ON_ONCE(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | ||
106 | #endif | ||
107 | /* | ||
108 | * Force other mappings to Oops if they'll try to access this | ||
109 | * pte without first remap it. Keeping stale mappings around | ||
110 | * is a bad idea also, in case the page changes cacheability | ||
111 | * attributes or becomes a protected page in a hypervisor. | ||
112 | */ | ||
106 | kpte_clear_flush(kmap_pte-idx, vaddr); | 113 | kpte_clear_flush(kmap_pte-idx, vaddr); |
114 | } | ||
107 | 115 | ||
108 | pagefault_enable(); | 116 | pagefault_enable(); |
109 | } | 117 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 90b1d6753b9d..eb6c473c6d1b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -155,11 +155,11 @@ fast_shmem_read(struct page **pages, | |||
155 | char __iomem *vaddr; | 155 | char __iomem *vaddr; |
156 | int unwritten; | 156 | int unwritten; |
157 | 157 | ||
158 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); | 158 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); |
159 | if (vaddr == NULL) | 159 | if (vaddr == NULL) |
160 | return -ENOMEM; | 160 | return -ENOMEM; |
161 | unwritten = __copy_to_user_inatomic(data, vaddr + page_offset, length); | 161 | unwritten = __copy_to_user_inatomic(data, vaddr + page_offset, length); |
162 | kunmap_atomic(vaddr, KM_USER0); | 162 | kunmap_atomic(vaddr); |
163 | 163 | ||
164 | if (unwritten) | 164 | if (unwritten) |
165 | return -EFAULT; | 165 | return -EFAULT; |
@@ -509,10 +509,10 @@ fast_user_write(struct io_mapping *mapping, | |||
509 | char *vaddr_atomic; | 509 | char *vaddr_atomic; |
510 | unsigned long unwritten; | 510 | unsigned long unwritten; |
511 | 511 | ||
512 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base, KM_USER0); | 512 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); |
513 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, | 513 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, |
514 | user_data, length); | 514 | user_data, length); |
515 | io_mapping_unmap_atomic(vaddr_atomic, KM_USER0); | 515 | io_mapping_unmap_atomic(vaddr_atomic); |
516 | if (unwritten) | 516 | if (unwritten) |
517 | return -EFAULT; | 517 | return -EFAULT; |
518 | return 0; | 518 | return 0; |
@@ -551,11 +551,11 @@ fast_shmem_write(struct page **pages, | |||
551 | char __iomem *vaddr; | 551 | char __iomem *vaddr; |
552 | unsigned long unwritten; | 552 | unsigned long unwritten; |
553 | 553 | ||
554 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); | 554 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); |
555 | if (vaddr == NULL) | 555 | if (vaddr == NULL) |
556 | return -ENOMEM; | 556 | return -ENOMEM; |
557 | unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length); | 557 | unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length); |
558 | kunmap_atomic(vaddr, KM_USER0); | 558 | kunmap_atomic(vaddr); |
559 | 559 | ||
560 | if (unwritten) | 560 | if (unwritten) |
561 | return -EFAULT; | 561 | return -EFAULT; |
@@ -3346,8 +3346,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3346 | reloc_offset = obj_priv->gtt_offset + reloc->offset; | 3346 | reloc_offset = obj_priv->gtt_offset + reloc->offset; |
3347 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 3347 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
3348 | (reloc_offset & | 3348 | (reloc_offset & |
3349 | ~(PAGE_SIZE - 1)), | 3349 | ~(PAGE_SIZE - 1))); |
3350 | KM_USER0); | ||
3351 | reloc_entry = (uint32_t __iomem *)(reloc_page + | 3350 | reloc_entry = (uint32_t __iomem *)(reloc_page + |
3352 | (reloc_offset & (PAGE_SIZE - 1))); | 3351 | (reloc_offset & (PAGE_SIZE - 1))); |
3353 | reloc_val = target_obj_priv->gtt_offset + reloc->delta; | 3352 | reloc_val = target_obj_priv->gtt_offset + reloc->delta; |
@@ -3358,7 +3357,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3358 | readl(reloc_entry), reloc_val); | 3357 | readl(reloc_entry), reloc_val); |
3359 | #endif | 3358 | #endif |
3360 | writel(reloc_val, reloc_entry); | 3359 | writel(reloc_val, reloc_entry); |
3361 | io_mapping_unmap_atomic(reloc_page, KM_USER0); | 3360 | io_mapping_unmap_atomic(reloc_page); |
3362 | 3361 | ||
3363 | /* The updated presumed offset for this entry will be | 3362 | /* The updated presumed offset for this entry will be |
3364 | * copied back out to the user. | 3363 | * copied back out to the user. |
@@ -4772,11 +4771,11 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
4772 | page_count = obj->size / PAGE_SIZE; | 4771 | page_count = obj->size / PAGE_SIZE; |
4773 | 4772 | ||
4774 | for (i = 0; i < page_count; i++) { | 4773 | for (i = 0; i < page_count; i++) { |
4775 | char *dst = kmap_atomic(obj_priv->pages[i], KM_USER0); | 4774 | char *dst = kmap_atomic(obj_priv->pages[i]); |
4776 | char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); | 4775 | char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); |
4777 | 4776 | ||
4778 | memcpy(dst, src, PAGE_SIZE); | 4777 | memcpy(dst, src, PAGE_SIZE); |
4779 | kunmap_atomic(dst, KM_USER0); | 4778 | kunmap_atomic(dst); |
4780 | } | 4779 | } |
4781 | drm_clflush_pages(obj_priv->pages, page_count); | 4780 | drm_clflush_pages(obj_priv->pages, page_count); |
4782 | drm_agp_chipset_flush(dev); | 4781 | drm_agp_chipset_flush(dev); |
@@ -4833,11 +4832,11 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4833 | page_count = obj->size / PAGE_SIZE; | 4832 | page_count = obj->size / PAGE_SIZE; |
4834 | 4833 | ||
4835 | for (i = 0; i < page_count; i++) { | 4834 | for (i = 0; i < page_count; i++) { |
4836 | char *src = kmap_atomic(obj_priv->pages[i], KM_USER0); | 4835 | char *src = kmap_atomic(obj_priv->pages[i]); |
4837 | char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); | 4836 | char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); |
4838 | 4837 | ||
4839 | memcpy(dst, src, PAGE_SIZE); | 4838 | memcpy(dst, src, PAGE_SIZE); |
4840 | kunmap_atomic(src, KM_USER0); | 4839 | kunmap_atomic(src); |
4841 | } | 4840 | } |
4842 | 4841 | ||
4843 | i915_gem_object_put_pages(obj); | 4842 | i915_gem_object_put_pages(obj); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 744225ebb4b2..b80010f0c4c9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -456,10 +456,9 @@ i915_error_object_create(struct drm_device *dev, | |||
456 | 456 | ||
457 | local_irq_save(flags); | 457 | local_irq_save(flags); |
458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
459 | reloc_offset, | 459 | reloc_offset); |
460 | KM_IRQ0); | ||
461 | memcpy_fromio(d, s, PAGE_SIZE); | 460 | memcpy_fromio(d, s, PAGE_SIZE); |
462 | io_mapping_unmap_atomic(s, KM_IRQ0); | 461 | io_mapping_unmap_atomic(s); |
463 | local_irq_restore(flags); | 462 | local_irq_restore(flags); |
464 | 463 | ||
465 | dst->pages[page] = d; | 464 | dst->pages[page] = d; |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 1d306a458be6..3264bbd47e65 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -187,8 +187,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over | |||
187 | 187 | ||
188 | if (OVERLAY_NONPHYSICAL(overlay->dev)) { | 188 | if (OVERLAY_NONPHYSICAL(overlay->dev)) { |
189 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 189 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
190 | overlay->reg_bo->gtt_offset, | 190 | overlay->reg_bo->gtt_offset); |
191 | KM_USER0); | ||
192 | 191 | ||
193 | if (!regs) { | 192 | if (!regs) { |
194 | DRM_ERROR("failed to map overlay regs in GTT\n"); | 193 | DRM_ERROR("failed to map overlay regs in GTT\n"); |
@@ -203,7 +202,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over | |||
203 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) | 202 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) |
204 | { | 203 | { |
205 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | 204 | if (OVERLAY_NONPHYSICAL(overlay->dev)) |
206 | io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0); | 205 | io_mapping_unmap_atomic(overlay->virt_addr); |
207 | 206 | ||
208 | overlay->virt_addr = NULL; | 207 | overlay->virt_addr = NULL; |
209 | 208 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 974b0f8ae048..8fa339600fe3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -2167,11 +2167,11 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2167 | 2167 | ||
2168 | if (off < pci_resource_len(dev->pdev, 1)) { | 2168 | if (off < pci_resource_len(dev->pdev, 1)) { |
2169 | uint8_t __iomem *p = | 2169 | uint8_t __iomem *p = |
2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK); |
2171 | 2171 | ||
2172 | val = ioread32(p + (off & ~PAGE_MASK)); | 2172 | val = ioread32(p + (off & ~PAGE_MASK)); |
2173 | 2173 | ||
2174 | io_mapping_unmap_atomic(p, KM_USER0); | 2174 | io_mapping_unmap_atomic(p); |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | return val; | 2177 | return val; |
@@ -2183,12 +2183,12 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2183 | { | 2183 | { |
2184 | if (off < pci_resource_len(dev->pdev, 1)) { | 2184 | if (off < pci_resource_len(dev->pdev, 1)) { |
2185 | uint8_t __iomem *p = | 2185 | uint8_t __iomem *p = |
2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK); |
2187 | 2187 | ||
2188 | iowrite32(val, p + (off & ~PAGE_MASK)); | 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); |
2189 | wmb(); | 2189 | wmb(); |
2190 | 2190 | ||
2191 | io_mapping_unmap_atomic(p, KM_USER0); | 2191 | io_mapping_unmap_atomic(p); |
2192 | } | 2192 | } |
2193 | } | 2193 | } |
2194 | 2194 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3451a82adba7..e8a73e65da69 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -170,7 +170,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | |||
170 | src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); | 170 | src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); |
171 | 171 | ||
172 | #ifdef CONFIG_X86 | 172 | #ifdef CONFIG_X86 |
173 | dst = kmap_atomic_prot(d, KM_USER0, prot); | 173 | dst = kmap_atomic_prot(d, prot); |
174 | #else | 174 | #else |
175 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) | 175 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
176 | dst = vmap(&d, 1, 0, prot); | 176 | dst = vmap(&d, 1, 0, prot); |
@@ -183,7 +183,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | |||
183 | memcpy_fromio(dst, src, PAGE_SIZE); | 183 | memcpy_fromio(dst, src, PAGE_SIZE); |
184 | 184 | ||
185 | #ifdef CONFIG_X86 | 185 | #ifdef CONFIG_X86 |
186 | kunmap_atomic(dst, KM_USER0); | 186 | kunmap_atomic(dst); |
187 | #else | 187 | #else |
188 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) | 188 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
189 | vunmap(dst); | 189 | vunmap(dst); |
@@ -206,7 +206,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
206 | 206 | ||
207 | dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); | 207 | dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); |
208 | #ifdef CONFIG_X86 | 208 | #ifdef CONFIG_X86 |
209 | src = kmap_atomic_prot(s, KM_USER0, prot); | 209 | src = kmap_atomic_prot(s, prot); |
210 | #else | 210 | #else |
211 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) | 211 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
212 | src = vmap(&s, 1, 0, prot); | 212 | src = vmap(&s, 1, 0, prot); |
@@ -219,7 +219,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
219 | memcpy_toio(dst, src, PAGE_SIZE); | 219 | memcpy_toio(dst, src, PAGE_SIZE); |
220 | 220 | ||
221 | #ifdef CONFIG_X86 | 221 | #ifdef CONFIG_X86 |
222 | kunmap_atomic(src, KM_USER0); | 222 | kunmap_atomic(src); |
223 | #else | 223 | #else |
224 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) | 224 | if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) |
225 | vunmap(src); | 225 | vunmap(src); |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 283cd47bb34c..8a85ec109a3a 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -28,18 +28,6 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) | |||
28 | 28 | ||
29 | #include <asm/kmap_types.h> | 29 | #include <asm/kmap_types.h> |
30 | 30 | ||
31 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
32 | |||
33 | void debug_kmap_atomic(enum km_type type); | ||
34 | |||
35 | #else | ||
36 | |||
37 | static inline void debug_kmap_atomic(enum km_type type) | ||
38 | { | ||
39 | } | ||
40 | |||
41 | #endif | ||
42 | |||
43 | #ifdef CONFIG_HIGHMEM | 31 | #ifdef CONFIG_HIGHMEM |
44 | #include <asm/highmem.h> | 32 | #include <asm/highmem.h> |
45 | 33 | ||
@@ -49,6 +37,27 @@ extern unsigned long totalhigh_pages; | |||
49 | 37 | ||
50 | void kmap_flush_unused(void); | 38 | void kmap_flush_unused(void); |
51 | 39 | ||
40 | DECLARE_PER_CPU(int, __kmap_atomic_idx); | ||
41 | |||
42 | static inline int kmap_atomic_idx_push(void) | ||
43 | { | ||
44 | int idx = __get_cpu_var(__kmap_atomic_idx)++; | ||
45 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
46 | WARN_ON_ONCE(in_irq() && !irqs_disabled()); | ||
47 | BUG_ON(idx > KM_TYPE_NR); | ||
48 | #endif | ||
49 | return idx; | ||
50 | } | ||
51 | |||
52 | static inline int kmap_atomic_idx_pop(void) | ||
53 | { | ||
54 | int idx = --__get_cpu_var(__kmap_atomic_idx); | ||
55 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
56 | BUG_ON(idx < 0); | ||
57 | #endif | ||
58 | return idx; | ||
59 | } | ||
60 | |||
52 | #else /* CONFIG_HIGHMEM */ | 61 | #else /* CONFIG_HIGHMEM */ |
53 | 62 | ||
54 | static inline unsigned int nr_free_highpages(void) { return 0; } | 63 | static inline unsigned int nr_free_highpages(void) { return 0; } |
@@ -66,19 +75,19 @@ static inline void kunmap(struct page *page) | |||
66 | { | 75 | { |
67 | } | 76 | } |
68 | 77 | ||
69 | static inline void *kmap_atomic(struct page *page, enum km_type idx) | 78 | static inline void *__kmap_atomic(struct page *page) |
70 | { | 79 | { |
71 | pagefault_disable(); | 80 | pagefault_disable(); |
72 | return page_address(page); | 81 | return page_address(page); |
73 | } | 82 | } |
74 | #define kmap_atomic_prot(page, idx, prot) kmap_atomic(page, idx) | 83 | #define kmap_atomic_prot(page, prot) __kmap_atomic(page) |
75 | 84 | ||
76 | static inline void kunmap_atomic_notypecheck(void *addr, enum km_type idx) | 85 | static inline void __kunmap_atomic(void *addr) |
77 | { | 86 | { |
78 | pagefault_enable(); | 87 | pagefault_enable(); |
79 | } | 88 | } |
80 | 89 | ||
81 | #define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) | 90 | #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn)) |
82 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) | 91 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) |
83 | 92 | ||
84 | #define kmap_flush_unused() do {} while(0) | 93 | #define kmap_flush_unused() do {} while(0) |
@@ -86,12 +95,20 @@ static inline void kunmap_atomic_notypecheck(void *addr, enum km_type idx) | |||
86 | 95 | ||
87 | #endif /* CONFIG_HIGHMEM */ | 96 | #endif /* CONFIG_HIGHMEM */ |
88 | 97 | ||
89 | /* Prevent people trying to call kunmap_atomic() as if it were kunmap() */ | 98 | /* |
90 | /* kunmap_atomic() should get the return value of kmap_atomic, not the page. */ | 99 | * Make both: kmap_atomic(page, idx) and kmap_atomic(page) work. |
91 | #define kunmap_atomic(addr, idx) do { \ | 100 | */ |
92 | BUILD_BUG_ON(__same_type((addr), struct page *)); \ | 101 | #define kmap_atomic(page, args...) __kmap_atomic(page) |
93 | kunmap_atomic_notypecheck((addr), (idx)); \ | 102 | |
94 | } while (0) | 103 | /* |
104 | * Prevent people trying to call kunmap_atomic() as if it were kunmap() | ||
105 | * kunmap_atomic() should get the return value of kmap_atomic, not the page. | ||
106 | */ | ||
107 | #define kunmap_atomic(addr, args...) \ | ||
108 | do { \ | ||
109 | BUILD_BUG_ON(__same_type((addr), struct page *)); \ | ||
110 | __kunmap_atomic(addr); \ | ||
111 | } while (0) | ||
95 | 112 | ||
96 | /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ | 113 | /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ |
97 | #ifndef clear_user_highpage | 114 | #ifndef clear_user_highpage |
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 7fb592793738..8cdcc2a199ad 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h | |||
@@ -81,8 +81,7 @@ io_mapping_free(struct io_mapping *mapping) | |||
81 | /* Atomic map/unmap */ | 81 | /* Atomic map/unmap */ |
82 | static inline void __iomem * | 82 | static inline void __iomem * |
83 | io_mapping_map_atomic_wc(struct io_mapping *mapping, | 83 | io_mapping_map_atomic_wc(struct io_mapping *mapping, |
84 | unsigned long offset, | 84 | unsigned long offset) |
85 | int slot) | ||
86 | { | 85 | { |
87 | resource_size_t phys_addr; | 86 | resource_size_t phys_addr; |
88 | unsigned long pfn; | 87 | unsigned long pfn; |
@@ -90,13 +89,13 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, | |||
90 | BUG_ON(offset >= mapping->size); | 89 | BUG_ON(offset >= mapping->size); |
91 | phys_addr = mapping->base + offset; | 90 | phys_addr = mapping->base + offset; |
92 | pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); | 91 | pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); |
93 | return iomap_atomic_prot_pfn(pfn, slot, mapping->prot); | 92 | return iomap_atomic_prot_pfn(pfn, mapping->prot); |
94 | } | 93 | } |
95 | 94 | ||
96 | static inline void | 95 | static inline void |
97 | io_mapping_unmap_atomic(void __iomem *vaddr, int slot) | 96 | io_mapping_unmap_atomic(void __iomem *vaddr) |
98 | { | 97 | { |
99 | iounmap_atomic(vaddr, slot); | 98 | iounmap_atomic(vaddr); |
100 | } | 99 | } |
101 | 100 | ||
102 | static inline void __iomem * | 101 | static inline void __iomem * |
@@ -137,14 +136,13 @@ io_mapping_free(struct io_mapping *mapping) | |||
137 | /* Atomic map/unmap */ | 136 | /* Atomic map/unmap */ |
138 | static inline void __iomem * | 137 | static inline void __iomem * |
139 | io_mapping_map_atomic_wc(struct io_mapping *mapping, | 138 | io_mapping_map_atomic_wc(struct io_mapping *mapping, |
140 | unsigned long offset, | 139 | unsigned long offset) |
141 | int slot) | ||
142 | { | 140 | { |
143 | return ((char __force __iomem *) mapping) + offset; | 141 | return ((char __force __iomem *) mapping) + offset; |
144 | } | 142 | } |
145 | 143 | ||
146 | static inline void | 144 | static inline void |
147 | io_mapping_unmap_atomic(void __iomem *vaddr, int slot) | 145 | io_mapping_unmap_atomic(void __iomem *vaddr) |
148 | { | 146 | { |
149 | } | 147 | } |
150 | 148 | ||
diff --git a/mm/highmem.c b/mm/highmem.c index 7a0aa1be4993..781e754a75ac 100644 --- a/mm/highmem.c +++ b/mm/highmem.c | |||
@@ -42,6 +42,10 @@ | |||
42 | unsigned long totalhigh_pages __read_mostly; | 42 | unsigned long totalhigh_pages __read_mostly; |
43 | EXPORT_SYMBOL(totalhigh_pages); | 43 | EXPORT_SYMBOL(totalhigh_pages); |
44 | 44 | ||
45 | |||
46 | DEFINE_PER_CPU(int, __kmap_atomic_idx); | ||
47 | EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx); | ||
48 | |||
45 | unsigned int nr_free_highpages (void) | 49 | unsigned int nr_free_highpages (void) |
46 | { | 50 | { |
47 | pg_data_t *pgdat; | 51 | pg_data_t *pgdat; |
@@ -422,61 +426,3 @@ void __init page_address_init(void) | |||
422 | } | 426 | } |
423 | 427 | ||
424 | #endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ | 428 | #endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ |
425 | |||
426 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
427 | |||
428 | void debug_kmap_atomic(enum km_type type) | ||
429 | { | ||
430 | static int warn_count = 10; | ||
431 | |||
432 | if (unlikely(warn_count < 0)) | ||
433 | return; | ||
434 | |||
435 | if (unlikely(in_interrupt())) { | ||
436 | if (in_nmi()) { | ||
437 | if (type != KM_NMI && type != KM_NMI_PTE) { | ||
438 | WARN_ON(1); | ||
439 | warn_count--; | ||
440 | } | ||
441 | } else if (in_irq()) { | ||
442 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
443 | type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && | ||
444 | type != KM_BOUNCE_READ && type != KM_IRQ_PTE) { | ||
445 | WARN_ON(1); | ||
446 | warn_count--; | ||
447 | } | ||
448 | } else if (!irqs_disabled()) { /* softirq */ | ||
449 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
450 | type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && | ||
451 | type != KM_SKB_SUNRPC_DATA && | ||
452 | type != KM_SKB_DATA_SOFTIRQ && | ||
453 | type != KM_BOUNCE_READ) { | ||
454 | WARN_ON(1); | ||
455 | warn_count--; | ||
456 | } | ||
457 | } | ||
458 | } | ||
459 | |||
460 | if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || | ||
461 | type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ || | ||
462 | type == KM_IRQ_PTE || type == KM_NMI || | ||
463 | type == KM_NMI_PTE ) { | ||
464 | if (!irqs_disabled()) { | ||
465 | WARN_ON(1); | ||
466 | warn_count--; | ||
467 | } | ||
468 | } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { | ||
469 | if (irq_count() == 0 && !irqs_disabled()) { | ||
470 | WARN_ON(1); | ||
471 | warn_count--; | ||
472 | } | ||
473 | } | ||
474 | #ifdef CONFIG_KGDB_KDB | ||
475 | if (unlikely(type == KM_KDB && atomic_read(&kgdb_active) == -1)) { | ||
476 | WARN_ON(1); | ||
477 | warn_count--; | ||
478 | } | ||
479 | #endif /* CONFIG_KGDB_KDB */ | ||
480 | } | ||
481 | |||
482 | #endif | ||