diff options
Diffstat (limited to 'include/linux/highmem.h')
-rw-r--r-- | include/linux/highmem.h | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 1fcb0033179e..7dcbc82f3b7b 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -68,8 +68,6 @@ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) | |||
68 | void *addr = kmap_atomic(page, KM_USER0); | 68 | void *addr = kmap_atomic(page, KM_USER0); |
69 | clear_user_page(addr, vaddr, page); | 69 | clear_user_page(addr, vaddr, page); |
70 | kunmap_atomic(addr, KM_USER0); | 70 | kunmap_atomic(addr, KM_USER0); |
71 | /* Make sure this page is cleared on other CPU's too before using it */ | ||
72 | smp_wmb(); | ||
73 | } | 71 | } |
74 | 72 | ||
75 | #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | 73 | #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE |
@@ -124,28 +122,40 @@ static inline void clear_highpage(struct page *page) | |||
124 | kunmap_atomic(kaddr, KM_USER0); | 122 | kunmap_atomic(kaddr, KM_USER0); |
125 | } | 123 | } |
126 | 124 | ||
127 | /* | 125 | static inline void zero_user_segments(struct page *page, |
128 | * Same but also flushes aliased cache contents to RAM. | 126 | unsigned start1, unsigned end1, |
129 | * | 127 | unsigned start2, unsigned end2) |
130 | * This must be a macro because KM_USER0 and friends aren't defined if | 128 | { |
131 | * !CONFIG_HIGHMEM | 129 | void *kaddr = kmap_atomic(page, KM_USER0); |
132 | */ | 130 | |
133 | #define zero_user_page(page, offset, size, km_type) \ | 131 | BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE); |
134 | do { \ | 132 | |
135 | void *kaddr; \ | 133 | if (end1 > start1) |
136 | \ | 134 | memset(kaddr + start1, 0, end1 - start1); |
137 | BUG_ON((offset) + (size) > PAGE_SIZE); \ | 135 | |
138 | \ | 136 | if (end2 > start2) |
139 | kaddr = kmap_atomic(page, km_type); \ | 137 | memset(kaddr + start2, 0, end2 - start2); |
140 | memset((char *)kaddr + (offset), 0, (size)); \ | 138 | |
141 | flush_dcache_page(page); \ | 139 | kunmap_atomic(kaddr, KM_USER0); |
142 | kunmap_atomic(kaddr, (km_type)); \ | 140 | flush_dcache_page(page); |
143 | } while (0) | 141 | } |
142 | |||
143 | static inline void zero_user_segment(struct page *page, | ||
144 | unsigned start, unsigned end) | ||
145 | { | ||
146 | zero_user_segments(page, start, end, 0, 0); | ||
147 | } | ||
148 | |||
149 | static inline void zero_user(struct page *page, | ||
150 | unsigned start, unsigned size) | ||
151 | { | ||
152 | zero_user_segments(page, start, start + size, 0, 0); | ||
153 | } | ||
144 | 154 | ||
145 | static inline void __deprecated memclear_highpage_flush(struct page *page, | 155 | static inline void __deprecated memclear_highpage_flush(struct page *page, |
146 | unsigned int offset, unsigned int size) | 156 | unsigned int offset, unsigned int size) |
147 | { | 157 | { |
148 | zero_user_page(page, offset, size, KM_USER0); | 158 | zero_user(page, offset, size); |
149 | } | 159 | } |
150 | 160 | ||
151 | #ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE | 161 | #ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE |
@@ -160,8 +170,6 @@ static inline void copy_user_highpage(struct page *to, struct page *from, | |||
160 | copy_user_page(vto, vfrom, vaddr, to); | 170 | copy_user_page(vto, vfrom, vaddr, to); |
161 | kunmap_atomic(vfrom, KM_USER0); | 171 | kunmap_atomic(vfrom, KM_USER0); |
162 | kunmap_atomic(vto, KM_USER1); | 172 | kunmap_atomic(vto, KM_USER1); |
163 | /* Make sure this page is cleared on other CPU's too before using it */ | ||
164 | smp_wmb(); | ||
165 | } | 173 | } |
166 | 174 | ||
167 | #endif | 175 | #endif |