diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ioremap.c | 39 | ||||
-rw-r--r-- | lib/iov_iter.c | 4 | ||||
-rw-r--r-- | lib/radix-tree.c | 4 | ||||
-rw-r--r-- | lib/refcount.c | 14 |
4 files changed, 47 insertions, 14 deletions
diff --git a/lib/ioremap.c b/lib/ioremap.c index a3e14ce92a56..4bb30206b942 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | 15 | ||
16 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP | 16 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP |
17 | static int __read_mostly ioremap_p4d_capable; | ||
17 | static int __read_mostly ioremap_pud_capable; | 18 | static int __read_mostly ioremap_pud_capable; |
18 | static int __read_mostly ioremap_pmd_capable; | 19 | static int __read_mostly ioremap_pmd_capable; |
19 | static int __read_mostly ioremap_huge_disabled; | 20 | static int __read_mostly ioremap_huge_disabled; |
@@ -35,6 +36,11 @@ void __init ioremap_huge_init(void) | |||
35 | } | 36 | } |
36 | } | 37 | } |
37 | 38 | ||
39 | static inline int ioremap_p4d_enabled(void) | ||
40 | { | ||
41 | return ioremap_p4d_capable; | ||
42 | } | ||
43 | |||
38 | static inline int ioremap_pud_enabled(void) | 44 | static inline int ioremap_pud_enabled(void) |
39 | { | 45 | { |
40 | return ioremap_pud_capable; | 46 | return ioremap_pud_capable; |
@@ -46,6 +52,7 @@ static inline int ioremap_pmd_enabled(void) | |||
46 | } | 52 | } |
47 | 53 | ||
48 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ | 54 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ |
55 | static inline int ioremap_p4d_enabled(void) { return 0; } | ||
49 | static inline int ioremap_pud_enabled(void) { return 0; } | 56 | static inline int ioremap_pud_enabled(void) { return 0; } |
50 | static inline int ioremap_pmd_enabled(void) { return 0; } | 57 | static inline int ioremap_pmd_enabled(void) { return 0; } |
51 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ | 58 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ |
@@ -94,14 +101,14 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, | |||
94 | return 0; | 101 | return 0; |
95 | } | 102 | } |
96 | 103 | ||
97 | static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr, | 104 | static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr, |
98 | unsigned long end, phys_addr_t phys_addr, pgprot_t prot) | 105 | unsigned long end, phys_addr_t phys_addr, pgprot_t prot) |
99 | { | 106 | { |
100 | pud_t *pud; | 107 | pud_t *pud; |
101 | unsigned long next; | 108 | unsigned long next; |
102 | 109 | ||
103 | phys_addr -= addr; | 110 | phys_addr -= addr; |
104 | pud = pud_alloc(&init_mm, pgd, addr); | 111 | pud = pud_alloc(&init_mm, p4d, addr); |
105 | if (!pud) | 112 | if (!pud) |
106 | return -ENOMEM; | 113 | return -ENOMEM; |
107 | do { | 114 | do { |
@@ -120,6 +127,32 @@ static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr, | |||
120 | return 0; | 127 | return 0; |
121 | } | 128 | } |
122 | 129 | ||
130 | static inline int ioremap_p4d_range(pgd_t *pgd, unsigned long addr, | ||
131 | unsigned long end, phys_addr_t phys_addr, pgprot_t prot) | ||
132 | { | ||
133 | p4d_t *p4d; | ||
134 | unsigned long next; | ||
135 | |||
136 | phys_addr -= addr; | ||
137 | p4d = p4d_alloc(&init_mm, pgd, addr); | ||
138 | if (!p4d) | ||
139 | return -ENOMEM; | ||
140 | do { | ||
141 | next = p4d_addr_end(addr, end); | ||
142 | |||
143 | if (ioremap_p4d_enabled() && | ||
144 | ((next - addr) == P4D_SIZE) && | ||
145 | IS_ALIGNED(phys_addr + addr, P4D_SIZE)) { | ||
146 | if (p4d_set_huge(p4d, phys_addr + addr, prot)) | ||
147 | continue; | ||
148 | } | ||
149 | |||
150 | if (ioremap_pud_range(p4d, addr, next, phys_addr + addr, prot)) | ||
151 | return -ENOMEM; | ||
152 | } while (p4d++, addr = next, addr != end); | ||
153 | return 0; | ||
154 | } | ||
155 | |||
123 | int ioremap_page_range(unsigned long addr, | 156 | int ioremap_page_range(unsigned long addr, |
124 | unsigned long end, phys_addr_t phys_addr, pgprot_t prot) | 157 | unsigned long end, phys_addr_t phys_addr, pgprot_t prot) |
125 | { | 158 | { |
@@ -135,7 +168,7 @@ int ioremap_page_range(unsigned long addr, | |||
135 | pgd = pgd_offset_k(addr); | 168 | pgd = pgd_offset_k(addr); |
136 | do { | 169 | do { |
137 | next = pgd_addr_end(addr, end); | 170 | next = pgd_addr_end(addr, end); |
138 | err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, prot); | 171 | err = ioremap_p4d_range(pgd, addr, next, phys_addr+addr, prot); |
139 | if (err) | 172 | if (err) |
140 | break; | 173 | break; |
141 | } while (pgd++, addr = next, addr != end); | 174 | } while (pgd++, addr = next, addr != end); |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 97db876c6862..672c32f9f960 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -604,7 +604,7 @@ size_t copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i) | |||
604 | return 0; | 604 | return 0; |
605 | } | 605 | } |
606 | iterate_and_advance(i, bytes, v, | 606 | iterate_and_advance(i, bytes, v, |
607 | __copy_from_user_nocache((to += v.iov_len) - v.iov_len, | 607 | __copy_from_user_inatomic_nocache((to += v.iov_len) - v.iov_len, |
608 | v.iov_base, v.iov_len), | 608 | v.iov_base, v.iov_len), |
609 | memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page, | 609 | memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page, |
610 | v.bv_offset, v.bv_len), | 610 | v.bv_offset, v.bv_len), |
@@ -625,7 +625,7 @@ bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i) | |||
625 | if (unlikely(i->count < bytes)) | 625 | if (unlikely(i->count < bytes)) |
626 | return false; | 626 | return false; |
627 | iterate_all_kinds(i, bytes, v, ({ | 627 | iterate_all_kinds(i, bytes, v, ({ |
628 | if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len, | 628 | if (__copy_from_user_inatomic_nocache((to += v.iov_len) - v.iov_len, |
629 | v.iov_base, v.iov_len)) | 629 | v.iov_base, v.iov_len)) |
630 | return false; | 630 | return false; |
631 | 0;}), | 631 | 0;}), |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 5ed506d648c4..691a9ad48497 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -2129,8 +2129,8 @@ int ida_pre_get(struct ida *ida, gfp_t gfp) | |||
2129 | struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); | 2129 | struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); |
2130 | if (!bitmap) | 2130 | if (!bitmap) |
2131 | return 0; | 2131 | return 0; |
2132 | bitmap = this_cpu_cmpxchg(ida_bitmap, NULL, bitmap); | 2132 | if (this_cpu_cmpxchg(ida_bitmap, NULL, bitmap)) |
2133 | kfree(bitmap); | 2133 | kfree(bitmap); |
2134 | } | 2134 | } |
2135 | 2135 | ||
2136 | return 1; | 2136 | return 1; |
diff --git a/lib/refcount.c b/lib/refcount.c index 1d33366189d1..aa09ad3c30b0 100644 --- a/lib/refcount.c +++ b/lib/refcount.c | |||
@@ -58,7 +58,7 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r) | |||
58 | val = old; | 58 | val = old; |
59 | } | 59 | } |
60 | 60 | ||
61 | WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); | 61 | WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); |
62 | 62 | ||
63 | return true; | 63 | return true; |
64 | } | 64 | } |
@@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(refcount_add_not_zero); | |||
66 | 66 | ||
67 | void refcount_add(unsigned int i, refcount_t *r) | 67 | void refcount_add(unsigned int i, refcount_t *r) |
68 | { | 68 | { |
69 | WARN(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n"); | 69 | WARN_ONCE(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n"); |
70 | } | 70 | } |
71 | EXPORT_SYMBOL_GPL(refcount_add); | 71 | EXPORT_SYMBOL_GPL(refcount_add); |
72 | 72 | ||
@@ -97,7 +97,7 @@ bool refcount_inc_not_zero(refcount_t *r) | |||
97 | val = old; | 97 | val = old; |
98 | } | 98 | } |
99 | 99 | ||
100 | WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); | 100 | WARN_ONCE(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); |
101 | 101 | ||
102 | return true; | 102 | return true; |
103 | } | 103 | } |
@@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(refcount_inc_not_zero); | |||
111 | */ | 111 | */ |
112 | void refcount_inc(refcount_t *r) | 112 | void refcount_inc(refcount_t *r) |
113 | { | 113 | { |
114 | WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n"); | 114 | WARN_ONCE(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n"); |
115 | } | 115 | } |
116 | EXPORT_SYMBOL_GPL(refcount_inc); | 116 | EXPORT_SYMBOL_GPL(refcount_inc); |
117 | 117 | ||
@@ -125,7 +125,7 @@ bool refcount_sub_and_test(unsigned int i, refcount_t *r) | |||
125 | 125 | ||
126 | new = val - i; | 126 | new = val - i; |
127 | if (new > val) { | 127 | if (new > val) { |
128 | WARN(new > val, "refcount_t: underflow; use-after-free.\n"); | 128 | WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n"); |
129 | return false; | 129 | return false; |
130 | } | 130 | } |
131 | 131 | ||
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(refcount_dec_and_test); | |||
164 | 164 | ||
165 | void refcount_dec(refcount_t *r) | 165 | void refcount_dec(refcount_t *r) |
166 | { | 166 | { |
167 | WARN(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n"); | 167 | WARN_ONCE(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n"); |
168 | } | 168 | } |
169 | EXPORT_SYMBOL_GPL(refcount_dec); | 169 | EXPORT_SYMBOL_GPL(refcount_dec); |
170 | 170 | ||
@@ -204,7 +204,7 @@ bool refcount_dec_not_one(refcount_t *r) | |||
204 | 204 | ||
205 | new = val - 1; | 205 | new = val - 1; |
206 | if (new > val) { | 206 | if (new > val) { |
207 | WARN(new > val, "refcount_t: underflow; use-after-free.\n"); | 207 | WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n"); |
208 | return true; | 208 | return true; |
209 | } | 209 | } |
210 | 210 | ||