diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 1 | ||||
-rw-r--r-- | lib/iommu-common.c | 6 | ||||
-rw-r--r-- | lib/rhashtable.c | 5 | ||||
-rw-r--r-- | lib/string.c | 89 | ||||
-rw-r--r-- | lib/string_helpers.c | 6 |
5 files changed, 99 insertions, 8 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 2e491ac15622..f0df318104e7 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -220,6 +220,7 @@ config ZLIB_INFLATE | |||
220 | 220 | ||
221 | config ZLIB_DEFLATE | 221 | config ZLIB_DEFLATE |
222 | tristate | 222 | tristate |
223 | select BITREVERSE | ||
223 | 224 | ||
224 | config LZO_COMPRESS | 225 | config LZO_COMPRESS |
225 | tristate | 226 | tristate |
diff --git a/lib/iommu-common.c b/lib/iommu-common.c index ff19f66d3f7f..b1c93e94ca7a 100644 --- a/lib/iommu-common.c +++ b/lib/iommu-common.c | |||
@@ -21,8 +21,7 @@ static DEFINE_PER_CPU(unsigned int, iommu_hash_common); | |||
21 | 21 | ||
22 | static inline bool need_flush(struct iommu_map_table *iommu) | 22 | static inline bool need_flush(struct iommu_map_table *iommu) |
23 | { | 23 | { |
24 | return (iommu->lazy_flush != NULL && | 24 | return ((iommu->flags & IOMMU_NEED_FLUSH) != 0); |
25 | (iommu->flags & IOMMU_NEED_FLUSH) != 0); | ||
26 | } | 25 | } |
27 | 26 | ||
28 | static inline void set_flush(struct iommu_map_table *iommu) | 27 | static inline void set_flush(struct iommu_map_table *iommu) |
@@ -211,7 +210,8 @@ unsigned long iommu_tbl_range_alloc(struct device *dev, | |||
211 | goto bail; | 210 | goto bail; |
212 | } | 211 | } |
213 | } | 212 | } |
214 | if (n < pool->hint || need_flush(iommu)) { | 213 | if (iommu->lazy_flush && |
214 | (n < pool->hint || need_flush(iommu))) { | ||
215 | clear_flush(iommu); | 215 | clear_flush(iommu); |
216 | iommu->lazy_flush(iommu); | 216 | iommu->lazy_flush(iommu); |
217 | } | 217 | } |
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index cc0c69710dcf..a54ff8949f91 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -187,10 +187,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht, unsigned int old_hash) | |||
187 | head = rht_dereference_bucket(new_tbl->buckets[new_hash], | 187 | head = rht_dereference_bucket(new_tbl->buckets[new_hash], |
188 | new_tbl, new_hash); | 188 | new_tbl, new_hash); |
189 | 189 | ||
190 | if (rht_is_a_nulls(head)) | 190 | RCU_INIT_POINTER(entry->next, head); |
191 | INIT_RHT_NULLS_HEAD(entry->next, ht, new_hash); | ||
192 | else | ||
193 | RCU_INIT_POINTER(entry->next, head); | ||
194 | 191 | ||
195 | rcu_assign_pointer(new_tbl->buckets[new_hash], entry); | 192 | rcu_assign_pointer(new_tbl->buckets[new_hash], entry); |
196 | spin_unlock(new_bucket_lock); | 193 | spin_unlock(new_bucket_lock); |
diff --git a/lib/string.c b/lib/string.c index 13d1e84ddb80..84775ba873b9 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #include <linux/bug.h> | 27 | #include <linux/bug.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | 29 | ||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/word-at-a-time.h> | ||
32 | #include <asm/page.h> | ||
33 | |||
30 | #ifndef __HAVE_ARCH_STRNCASECMP | 34 | #ifndef __HAVE_ARCH_STRNCASECMP |
31 | /** | 35 | /** |
32 | * strncasecmp - Case insensitive, length-limited string comparison | 36 | * strncasecmp - Case insensitive, length-limited string comparison |
@@ -146,6 +150,91 @@ size_t strlcpy(char *dest, const char *src, size_t size) | |||
146 | EXPORT_SYMBOL(strlcpy); | 150 | EXPORT_SYMBOL(strlcpy); |
147 | #endif | 151 | #endif |
148 | 152 | ||
153 | #ifndef __HAVE_ARCH_STRSCPY | ||
154 | /** | ||
155 | * strscpy - Copy a C-string into a sized buffer | ||
156 | * @dest: Where to copy the string to | ||
157 | * @src: Where to copy the string from | ||
158 | * @count: Size of destination buffer | ||
159 | * | ||
160 | * Copy the string, or as much of it as fits, into the dest buffer. | ||
161 | * The routine returns the number of characters copied (not including | ||
162 | * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. | ||
163 | * The behavior is undefined if the string buffers overlap. | ||
164 | * The destination buffer is always NUL terminated, unless it's zero-sized. | ||
165 | * | ||
166 | * Preferred to strlcpy() since the API doesn't require reading memory | ||
167 | * from the src string beyond the specified "count" bytes, and since | ||
168 | * the return value is easier to error-check than strlcpy()'s. | ||
169 | * In addition, the implementation is robust to the string changing out | ||
170 | * from underneath it, unlike the current strlcpy() implementation. | ||
171 | * | ||
172 | * Preferred to strncpy() since it always returns a valid string, and | ||
173 | * doesn't unnecessarily force the tail of the destination buffer to be | ||
174 | * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() | ||
175 | * with an overflow test, then just memset() the tail of the dest buffer. | ||
176 | */ | ||
177 | ssize_t strscpy(char *dest, const char *src, size_t count) | ||
178 | { | ||
179 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; | ||
180 | size_t max = count; | ||
181 | long res = 0; | ||
182 | |||
183 | if (count == 0) | ||
184 | return -E2BIG; | ||
185 | |||
186 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
187 | /* | ||
188 | * If src is unaligned, don't cross a page boundary, | ||
189 | * since we don't know if the next page is mapped. | ||
190 | */ | ||
191 | if ((long)src & (sizeof(long) - 1)) { | ||
192 | size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); | ||
193 | if (limit < max) | ||
194 | max = limit; | ||
195 | } | ||
196 | #else | ||
197 | /* If src or dest is unaligned, don't do word-at-a-time. */ | ||
198 | if (((long) dest | (long) src) & (sizeof(long) - 1)) | ||
199 | max = 0; | ||
200 | #endif | ||
201 | |||
202 | while (max >= sizeof(unsigned long)) { | ||
203 | unsigned long c, data; | ||
204 | |||
205 | c = *(unsigned long *)(src+res); | ||
206 | if (has_zero(c, &data, &constants)) { | ||
207 | data = prep_zero_mask(c, data, &constants); | ||
208 | data = create_zero_mask(data); | ||
209 | *(unsigned long *)(dest+res) = c & zero_bytemask(data); | ||
210 | return res + find_zero(data); | ||
211 | } | ||
212 | *(unsigned long *)(dest+res) = c; | ||
213 | res += sizeof(unsigned long); | ||
214 | count -= sizeof(unsigned long); | ||
215 | max -= sizeof(unsigned long); | ||
216 | } | ||
217 | |||
218 | while (count) { | ||
219 | char c; | ||
220 | |||
221 | c = src[res]; | ||
222 | dest[res] = c; | ||
223 | if (!c) | ||
224 | return res; | ||
225 | res++; | ||
226 | count--; | ||
227 | } | ||
228 | |||
229 | /* Hit buffer length without finding a NUL; force NUL-termination. */ | ||
230 | if (res) | ||
231 | dest[res-1] = '\0'; | ||
232 | |||
233 | return -E2BIG; | ||
234 | } | ||
235 | EXPORT_SYMBOL(strscpy); | ||
236 | #endif | ||
237 | |||
149 | #ifndef __HAVE_ARCH_STRCAT | 238 | #ifndef __HAVE_ARCH_STRCAT |
150 | /** | 239 | /** |
151 | * strcat - Append one %NUL-terminated string to another | 240 | * strcat - Append one %NUL-terminated string to another |
diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 54036ce2e2dd..5939f63d90cd 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c | |||
@@ -59,7 +59,11 @@ void string_get_size(u64 size, u64 blk_size, const enum string_size_units units, | |||
59 | } | 59 | } |
60 | 60 | ||
61 | exp = divisor[units] / (u32)blk_size; | 61 | exp = divisor[units] / (u32)blk_size; |
62 | if (size >= exp) { | 62 | /* |
63 | * size must be strictly greater than exp here to ensure that remainder | ||
64 | * is greater than divisor[units] coming out of the if below. | ||
65 | */ | ||
66 | if (size > exp) { | ||
63 | remainder = do_div(size, divisor[units]); | 67 | remainder = do_div(size, divisor[units]); |
64 | remainder *= blk_size; | 68 | remainder *= blk_size; |
65 | i++; | 69 | i++; |