summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ioremap.c39
-rw-r--r--lib/iov_iter.c4
-rw-r--r--lib/radix-tree.c4
-rw-r--r--lib/refcount.c14
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
17static int __read_mostly ioremap_p4d_capable;
17static int __read_mostly ioremap_pud_capable; 18static int __read_mostly ioremap_pud_capable;
18static int __read_mostly ioremap_pmd_capable; 19static int __read_mostly ioremap_pmd_capable;
19static int __read_mostly ioremap_huge_disabled; 20static int __read_mostly ioremap_huge_disabled;
@@ -35,6 +36,11 @@ void __init ioremap_huge_init(void)
35 } 36 }
36} 37}
37 38
39static inline int ioremap_p4d_enabled(void)
40{
41 return ioremap_p4d_capable;
42}
43
38static inline int ioremap_pud_enabled(void) 44static 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 */
55static inline int ioremap_p4d_enabled(void) { return 0; }
49static inline int ioremap_pud_enabled(void) { return 0; } 56static inline int ioremap_pud_enabled(void) { return 0; }
50static inline int ioremap_pmd_enabled(void) { return 0; } 57static 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
97static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr, 104static 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
130static 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
123int ioremap_page_range(unsigned long addr, 156int 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
67void refcount_add(unsigned int i, refcount_t *r) 67void 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}
71EXPORT_SYMBOL_GPL(refcount_add); 71EXPORT_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 */
112void refcount_inc(refcount_t *r) 112void 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}
116EXPORT_SYMBOL_GPL(refcount_inc); 116EXPORT_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
165void refcount_dec(refcount_t *r) 165void 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}
169EXPORT_SYMBOL_GPL(refcount_dec); 169EXPORT_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