Annotation of /trunk/kernel-alx/patches-4.9/0147-4.9.48-all-fixes.patch
Parent Directory | Revision Log
Revision 2989 -
(hide annotations)
(download)
Fri Sep 8 09:23:20 2017 UTC (7 years ago) by niro
File size: 14817 byte(s)
Fri Sep 8 09:23:20 2017 UTC (7 years ago) by niro
File size: 14817 byte(s)
-linux-4.9.48
1 | niro | 2989 | diff --git a/Makefile b/Makefile |
2 | index a0abbfc15a49..cfa188b427b1 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 4 | ||
7 | PATCHLEVEL = 9 | ||
8 | -SUBLEVEL = 47 | ||
9 | +SUBLEVEL = 48 | ||
10 | EXTRAVERSION = | ||
11 | NAME = Roaring Lionus | ||
12 | |||
13 | diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h | ||
14 | index 4cb4b6d3452c..0bc66e1d3a7e 100644 | ||
15 | --- a/arch/alpha/include/asm/types.h | ||
16 | +++ b/arch/alpha/include/asm/types.h | ||
17 | @@ -1,6 +1,6 @@ | ||
18 | #ifndef _ALPHA_TYPES_H | ||
19 | #define _ALPHA_TYPES_H | ||
20 | |||
21 | -#include <asm-generic/int-ll64.h> | ||
22 | +#include <uapi/asm/types.h> | ||
23 | |||
24 | #endif /* _ALPHA_TYPES_H */ | ||
25 | diff --git a/arch/alpha/include/uapi/asm/types.h b/arch/alpha/include/uapi/asm/types.h | ||
26 | index 9fd3cd459777..8d1024d7be05 100644 | ||
27 | --- a/arch/alpha/include/uapi/asm/types.h | ||
28 | +++ b/arch/alpha/include/uapi/asm/types.h | ||
29 | @@ -9,8 +9,18 @@ | ||
30 | * need to be careful to avoid a name clashes. | ||
31 | */ | ||
32 | |||
33 | -#ifndef __KERNEL__ | ||
34 | +/* | ||
35 | + * This is here because we used to use l64 for alpha | ||
36 | + * and we don't want to impact user mode with our change to ll64 | ||
37 | + * in the kernel. | ||
38 | + * | ||
39 | + * However, some user programs are fine with this. They can | ||
40 | + * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here. | ||
41 | + */ | ||
42 | +#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__) | ||
43 | #include <asm-generic/int-l64.h> | ||
44 | +#else | ||
45 | +#include <asm-generic/int-ll64.h> | ||
46 | #endif | ||
47 | |||
48 | #endif /* _UAPI_ALPHA_TYPES_H */ | ||
49 | diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c | ||
50 | index 0c060c5e844a..2206e0e00934 100644 | ||
51 | --- a/arch/arm/kvm/mmu.c | ||
52 | +++ b/arch/arm/kvm/mmu.c | ||
53 | @@ -837,7 +837,7 @@ void kvm_free_stage2_pgd(struct kvm *kvm) | ||
54 | spin_lock(&kvm->mmu_lock); | ||
55 | if (kvm->arch.pgd) { | ||
56 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); | ||
57 | - pgd = kvm->arch.pgd; | ||
58 | + pgd = READ_ONCE(kvm->arch.pgd); | ||
59 | kvm->arch.pgd = NULL; | ||
60 | } | ||
61 | spin_unlock(&kvm->mmu_lock); | ||
62 | diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c | ||
63 | index 28556fce4267..45af0fe00f33 100644 | ||
64 | --- a/crypto/algif_skcipher.c | ||
65 | +++ b/crypto/algif_skcipher.c | ||
66 | @@ -86,8 +86,13 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq) | ||
67 | } | ||
68 | sgl = sreq->tsg; | ||
69 | n = sg_nents(sgl); | ||
70 | - for_each_sg(sgl, sg, n, i) | ||
71 | - put_page(sg_page(sg)); | ||
72 | + for_each_sg(sgl, sg, n, i) { | ||
73 | + struct page *page = sg_page(sg); | ||
74 | + | ||
75 | + /* some SGs may not have a page mapped */ | ||
76 | + if (page && page_ref_count(page)) | ||
77 | + put_page(page); | ||
78 | + } | ||
79 | |||
80 | kfree(sreq->tsg); | ||
81 | } | ||
82 | diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c | ||
83 | index a37de5db5731..ddd6badd0eee 100644 | ||
84 | --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c | ||
85 | +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | ||
86 | @@ -612,7 +612,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, | ||
87 | } else { | ||
88 | pr_err("Failed to fill pool (%p)\n", pool); | ||
89 | /* If we have any pages left put them to the pool. */ | ||
90 | - list_for_each_entry(p, &pool->list, lru) { | ||
91 | + list_for_each_entry(p, &new_pages, lru) { | ||
92 | ++cpages; | ||
93 | } | ||
94 | list_splice(&new_pages, &pool->list); | ||
95 | diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c | ||
96 | index f573448d2132..8477292e92c8 100644 | ||
97 | --- a/drivers/i2c/busses/i2c-ismt.c | ||
98 | +++ b/drivers/i2c/busses/i2c-ismt.c | ||
99 | @@ -341,8 +341,10 @@ static int ismt_process_desc(const struct ismt_desc *desc, | ||
100 | break; | ||
101 | case I2C_SMBUS_BLOCK_DATA: | ||
102 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
103 | - memcpy(&data->block[1], dma_buffer, desc->rxbytes); | ||
104 | - data->block[0] = desc->rxbytes; | ||
105 | + if (desc->rxbytes != dma_buffer[0] + 1) | ||
106 | + return -EMSGSIZE; | ||
107 | + | ||
108 | + memcpy(data->block, dma_buffer, desc->rxbytes); | ||
109 | break; | ||
110 | } | ||
111 | return 0; | ||
112 | diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c | ||
113 | index c0178a122940..d74374f25392 100644 | ||
114 | --- a/drivers/irqchip/irq-mips-gic.c | ||
115 | +++ b/drivers/irqchip/irq-mips-gic.c | ||
116 | @@ -1115,8 +1115,11 @@ static int __init gic_of_init(struct device_node *node, | ||
117 | gic_len = resource_size(&res); | ||
118 | } | ||
119 | |||
120 | - if (mips_cm_present()) | ||
121 | + if (mips_cm_present()) { | ||
122 | write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); | ||
123 | + /* Ensure GIC region is enabled before trying to access it */ | ||
124 | + __sync(); | ||
125 | + } | ||
126 | gic_present = true; | ||
127 | |||
128 | __gic_init(gic_base, gic_len, cpu_vec, 0, node); | ||
129 | diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c | ||
130 | index bbf7604889b7..1c539c83e8cf 100644 | ||
131 | --- a/drivers/net/wireless/ti/wl1251/main.c | ||
132 | +++ b/drivers/net/wireless/ti/wl1251/main.c | ||
133 | @@ -1571,6 +1571,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | ||
134 | |||
135 | wl->state = WL1251_STATE_OFF; | ||
136 | mutex_init(&wl->mutex); | ||
137 | + spin_lock_init(&wl->wl_lock); | ||
138 | |||
139 | wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE; | ||
140 | wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE; | ||
141 | diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c | ||
142 | index 900ffafb85ca..7b79a54a2789 100644 | ||
143 | --- a/fs/ceph/addr.c | ||
144 | +++ b/fs/ceph/addr.c | ||
145 | @@ -188,7 +188,7 @@ static int ceph_releasepage(struct page *page, gfp_t g) | ||
146 | /* | ||
147 | * read a single page, without unlocking it. | ||
148 | */ | ||
149 | -static int readpage_nounlock(struct file *filp, struct page *page) | ||
150 | +static int ceph_do_readpage(struct file *filp, struct page *page) | ||
151 | { | ||
152 | struct inode *inode = file_inode(filp); | ||
153 | struct ceph_inode_info *ci = ceph_inode(inode); | ||
154 | @@ -218,7 +218,7 @@ static int readpage_nounlock(struct file *filp, struct page *page) | ||
155 | |||
156 | err = ceph_readpage_from_fscache(inode, page); | ||
157 | if (err == 0) | ||
158 | - goto out; | ||
159 | + return -EINPROGRESS; | ||
160 | |||
161 | dout("readpage inode %p file %p page %p index %lu\n", | ||
162 | inode, filp, page, page->index); | ||
163 | @@ -248,8 +248,11 @@ static int readpage_nounlock(struct file *filp, struct page *page) | ||
164 | |||
165 | static int ceph_readpage(struct file *filp, struct page *page) | ||
166 | { | ||
167 | - int r = readpage_nounlock(filp, page); | ||
168 | - unlock_page(page); | ||
169 | + int r = ceph_do_readpage(filp, page); | ||
170 | + if (r != -EINPROGRESS) | ||
171 | + unlock_page(page); | ||
172 | + else | ||
173 | + r = 0; | ||
174 | return r; | ||
175 | } | ||
176 | |||
177 | @@ -1235,7 +1238,7 @@ static int ceph_update_writeable_page(struct file *file, | ||
178 | goto retry_locked; | ||
179 | r = writepage_nounlock(page, NULL); | ||
180 | if (r < 0) | ||
181 | - goto fail_nosnap; | ||
182 | + goto fail_unlock; | ||
183 | goto retry_locked; | ||
184 | } | ||
185 | |||
186 | @@ -1263,11 +1266,14 @@ static int ceph_update_writeable_page(struct file *file, | ||
187 | } | ||
188 | |||
189 | /* we need to read it. */ | ||
190 | - r = readpage_nounlock(file, page); | ||
191 | - if (r < 0) | ||
192 | - goto fail_nosnap; | ||
193 | + r = ceph_do_readpage(file, page); | ||
194 | + if (r < 0) { | ||
195 | + if (r == -EINPROGRESS) | ||
196 | + return -EAGAIN; | ||
197 | + goto fail_unlock; | ||
198 | + } | ||
199 | goto retry_locked; | ||
200 | -fail_nosnap: | ||
201 | +fail_unlock: | ||
202 | unlock_page(page); | ||
203 | return r; | ||
204 | } | ||
205 | diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c | ||
206 | index 5bc5d37b1217..a2d7997afd94 100644 | ||
207 | --- a/fs/ceph/cache.c | ||
208 | +++ b/fs/ceph/cache.c | ||
209 | @@ -240,13 +240,7 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp) | ||
210 | } | ||
211 | } | ||
212 | |||
213 | -static void ceph_vfs_readpage_complete(struct page *page, void *data, int error) | ||
214 | -{ | ||
215 | - if (!error) | ||
216 | - SetPageUptodate(page); | ||
217 | -} | ||
218 | - | ||
219 | -static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int error) | ||
220 | +static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error) | ||
221 | { | ||
222 | if (!error) | ||
223 | SetPageUptodate(page); | ||
224 | @@ -274,7 +268,7 @@ int ceph_readpage_from_fscache(struct inode *inode, struct page *page) | ||
225 | return -ENOBUFS; | ||
226 | |||
227 | ret = fscache_read_or_alloc_page(ci->fscache, page, | ||
228 | - ceph_vfs_readpage_complete, NULL, | ||
229 | + ceph_readpage_from_fscache_complete, NULL, | ||
230 | GFP_KERNEL); | ||
231 | |||
232 | switch (ret) { | ||
233 | @@ -303,7 +297,7 @@ int ceph_readpages_from_fscache(struct inode *inode, | ||
234 | return -ENOBUFS; | ||
235 | |||
236 | ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages, | ||
237 | - ceph_vfs_readpage_complete_unlock, | ||
238 | + ceph_readpage_from_fscache_complete, | ||
239 | NULL, mapping_gfp_mask(mapping)); | ||
240 | |||
241 | switch (ret) { | ||
242 | diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c | ||
243 | index 581712534c93..dd3e236d7a2b 100644 | ||
244 | --- a/fs/cifs/dir.c | ||
245 | +++ b/fs/cifs/dir.c | ||
246 | @@ -194,7 +194,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon) | ||
247 | int i; | ||
248 | |||
249 | if (unlikely(direntry->d_name.len > | ||
250 | - tcon->fsAttrInfo.MaxPathNameComponentLength)) | ||
251 | + le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) | ||
252 | return -ENAMETOOLONG; | ||
253 | |||
254 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { | ||
255 | diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h | ||
256 | index dc0d141f33e2..1e1449ad00e8 100644 | ||
257 | --- a/fs/cifs/smb2pdu.h | ||
258 | +++ b/fs/cifs/smb2pdu.h | ||
259 | @@ -84,8 +84,8 @@ | ||
260 | |||
261 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 | ||
262 | |||
263 | -/* BB FIXME - analyze following length BB */ | ||
264 | -#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */ | ||
265 | +/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */ | ||
266 | +#define MAX_SMB2_HDR_SIZE 0x00b0 | ||
267 | |||
268 | #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) | ||
269 | #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) | ||
270 | diff --git a/fs/eventpoll.c b/fs/eventpoll.c | ||
271 | index 10db91218933..3cbc30413add 100644 | ||
272 | --- a/fs/eventpoll.c | ||
273 | +++ b/fs/eventpoll.c | ||
274 | @@ -523,8 +523,13 @@ static void ep_remove_wait_queue(struct eppoll_entry *pwq) | ||
275 | wait_queue_head_t *whead; | ||
276 | |||
277 | rcu_read_lock(); | ||
278 | - /* If it is cleared by POLLFREE, it should be rcu-safe */ | ||
279 | - whead = rcu_dereference(pwq->whead); | ||
280 | + /* | ||
281 | + * If it is cleared by POLLFREE, it should be rcu-safe. | ||
282 | + * If we read NULL we need a barrier paired with | ||
283 | + * smp_store_release() in ep_poll_callback(), otherwise | ||
284 | + * we rely on whead->lock. | ||
285 | + */ | ||
286 | + whead = smp_load_acquire(&pwq->whead); | ||
287 | if (whead) | ||
288 | remove_wait_queue(whead, &pwq->wait); | ||
289 | rcu_read_unlock(); | ||
290 | @@ -1009,17 +1014,6 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k | ||
291 | struct eventpoll *ep = epi->ep; | ||
292 | int ewake = 0; | ||
293 | |||
294 | - if ((unsigned long)key & POLLFREE) { | ||
295 | - ep_pwq_from_wait(wait)->whead = NULL; | ||
296 | - /* | ||
297 | - * whead = NULL above can race with ep_remove_wait_queue() | ||
298 | - * which can do another remove_wait_queue() after us, so we | ||
299 | - * can't use __remove_wait_queue(). whead->lock is held by | ||
300 | - * the caller. | ||
301 | - */ | ||
302 | - list_del_init(&wait->task_list); | ||
303 | - } | ||
304 | - | ||
305 | spin_lock_irqsave(&ep->lock, flags); | ||
306 | |||
307 | /* | ||
308 | @@ -1101,10 +1095,26 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k | ||
309 | if (pwake) | ||
310 | ep_poll_safewake(&ep->poll_wait); | ||
311 | |||
312 | - if (epi->event.events & EPOLLEXCLUSIVE) | ||
313 | - return ewake; | ||
314 | + if (!(epi->event.events & EPOLLEXCLUSIVE)) | ||
315 | + ewake = 1; | ||
316 | + | ||
317 | + if ((unsigned long)key & POLLFREE) { | ||
318 | + /* | ||
319 | + * If we race with ep_remove_wait_queue() it can miss | ||
320 | + * ->whead = NULL and do another remove_wait_queue() after | ||
321 | + * us, so we can't use __remove_wait_queue(). | ||
322 | + */ | ||
323 | + list_del_init(&wait->task_list); | ||
324 | + /* | ||
325 | + * ->whead != NULL protects us from the race with ep_free() | ||
326 | + * or ep_remove(), ep_remove_wait_queue() takes whead->lock | ||
327 | + * held by the caller. Once we nullify it, nothing protects | ||
328 | + * ep/epi or even wait. | ||
329 | + */ | ||
330 | + smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL); | ||
331 | + } | ||
332 | |||
333 | - return 1; | ||
334 | + return ewake; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h | ||
339 | index fc824e2828f3..5d2add1a6c96 100644 | ||
340 | --- a/include/asm-generic/topology.h | ||
341 | +++ b/include/asm-generic/topology.h | ||
342 | @@ -48,7 +48,11 @@ | ||
343 | #define parent_node(node) ((void)(node),0) | ||
344 | #endif | ||
345 | #ifndef cpumask_of_node | ||
346 | -#define cpumask_of_node(node) ((void)node, cpu_online_mask) | ||
347 | + #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
348 | + #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) | ||
349 | + #else | ||
350 | + #define cpumask_of_node(node) ((void)node, cpu_online_mask) | ||
351 | + #endif | ||
352 | #endif | ||
353 | #ifndef pcibus_to_node | ||
354 | #define pcibus_to_node(bus) ((void)(bus), -1) | ||
355 | diff --git a/kernel/cpuset.c b/kernel/cpuset.c | ||
356 | index 247afb108343..03a3a6e94eb9 100644 | ||
357 | --- a/kernel/cpuset.c | ||
358 | +++ b/kernel/cpuset.c | ||
359 | @@ -1905,6 +1905,7 @@ static struct cftype files[] = { | ||
360 | { | ||
361 | .name = "memory_pressure", | ||
362 | .read_u64 = cpuset_read_u64, | ||
363 | + .private = FILE_MEMORY_PRESSURE, | ||
364 | }, | ||
365 | |||
366 | { | ||
367 | diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c | ||
368 | index f9ec9add2164..a1de021dccba 100644 | ||
369 | --- a/kernel/events/uprobes.c | ||
370 | +++ b/kernel/events/uprobes.c | ||
371 | @@ -1254,8 +1254,6 @@ void uprobe_end_dup_mmap(void) | ||
372 | |||
373 | void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) | ||
374 | { | ||
375 | - newmm->uprobes_state.xol_area = NULL; | ||
376 | - | ||
377 | if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) { | ||
378 | set_bit(MMF_HAS_UPROBES, &newmm->flags); | ||
379 | /* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */ | ||
380 | diff --git a/kernel/fork.c b/kernel/fork.c | ||
381 | index 50bf262cc427..9321b1ad3335 100644 | ||
382 | --- a/kernel/fork.c | ||
383 | +++ b/kernel/fork.c | ||
384 | @@ -745,6 +745,13 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p) | ||
385 | #endif | ||
386 | } | ||
387 | |||
388 | +static void mm_init_uprobes_state(struct mm_struct *mm) | ||
389 | +{ | ||
390 | +#ifdef CONFIG_UPROBES | ||
391 | + mm->uprobes_state.xol_area = NULL; | ||
392 | +#endif | ||
393 | +} | ||
394 | + | ||
395 | static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, | ||
396 | struct user_namespace *user_ns) | ||
397 | { | ||
398 | @@ -772,6 +779,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, | ||
399 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS | ||
400 | mm->pmd_huge_pte = NULL; | ||
401 | #endif | ||
402 | + mm_init_uprobes_state(mm); | ||
403 | |||
404 | if (current->mm) { | ||
405 | mm->flags = current->mm->flags & MMF_INIT_MASK; | ||
406 | diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c | ||
407 | index 5a0f75a3bf01..eead4b339466 100644 | ||
408 | --- a/lib/mpi/mpicoder.c | ||
409 | +++ b/lib/mpi/mpicoder.c | ||
410 | @@ -364,11 +364,11 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | ||
411 | } | ||
412 | |||
413 | miter.consumed = lzeros; | ||
414 | - sg_miter_stop(&miter); | ||
415 | |||
416 | nbytes -= lzeros; | ||
417 | nbits = nbytes * 8; | ||
418 | if (nbits > MAX_EXTERN_MPI_BITS) { | ||
419 | + sg_miter_stop(&miter); | ||
420 | pr_info("MPI: mpi too large (%u bits)\n", nbits); | ||
421 | return NULL; | ||
422 | } | ||
423 | @@ -376,6 +376,8 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | ||
424 | if (nbytes > 0) | ||
425 | nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8); | ||
426 | |||
427 | + sg_miter_stop(&miter); | ||
428 | + | ||
429 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); | ||
430 | val = mpi_alloc(nlimbs); | ||
431 | if (!val) | ||
432 | diff --git a/mm/madvise.c b/mm/madvise.c | ||
433 | index 63a12162f4c6..55f30ec32e5b 100644 | ||
434 | --- a/mm/madvise.c | ||
435 | +++ b/mm/madvise.c | ||
436 | @@ -533,6 +533,8 @@ static long madvise_remove(struct vm_area_struct *vma, | ||
437 | static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end) | ||
438 | { | ||
439 | struct page *p; | ||
440 | + struct zone *zone; | ||
441 | + | ||
442 | if (!capable(CAP_SYS_ADMIN)) | ||
443 | return -EPERM; | ||
444 | for (; start < end; start += PAGE_SIZE << | ||
445 | @@ -561,6 +563,11 @@ static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end) | ||
446 | if (ret) | ||
447 | return ret; | ||
448 | } | ||
449 | + | ||
450 | + /* Ensure that all poisoned pages are removed from per-cpu lists */ | ||
451 | + for_each_populated_zone(zone) | ||
452 | + drain_all_pages(zone); | ||
453 | + | ||
454 | return 0; | ||
455 | } | ||
456 | #endif | ||
457 | diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c | ||
458 | index e26b515f7794..8ce5711ea21b 100644 | ||
459 | --- a/net/xfrm/xfrm_policy.c | ||
460 | +++ b/net/xfrm/xfrm_policy.c | ||
461 | @@ -3308,9 +3308,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | ||
462 | struct xfrm_state *x_new[XFRM_MAX_DEPTH]; | ||
463 | struct xfrm_migrate *mp; | ||
464 | |||
465 | + /* Stage 0 - sanity checks */ | ||
466 | if ((err = xfrm_migrate_check(m, num_migrate)) < 0) | ||
467 | goto out; | ||
468 | |||
469 | + if (dir >= XFRM_POLICY_MAX) { | ||
470 | + err = -EINVAL; | ||
471 | + goto out; | ||
472 | + } | ||
473 | + | ||
474 | /* Stage 1 - find policy */ | ||
475 | if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) { | ||
476 | err = -ENOENT; |