| From foo@baz Sun May 27 17:33:38 CEST 2018 |
| From: Yisheng Xie <xieyisheng1@huawei.com> |
| Date: Wed, 31 Jan 2018 16:16:15 -0800 |
| Subject: mm/mempolicy: add nodes_empty check in SYSC_migrate_pages |
| |
| From: Yisheng Xie <xieyisheng1@huawei.com> |
| |
| [ Upstream commit 0486a38bcc4749808edbc848f1bcf232042770fc ] |
| |
| As in manpage of migrate_pages, the errno should be set to EINVAL when |
| none of the node IDs specified by new_nodes are on-line and allowed by |
| the process's current cpuset context, or none of the specified nodes |
| contain memory. However, when test by following case: |
| |
| new_nodes = 0; |
| old_nodes = 0xf; |
| ret = migrate_pages(pid, old_nodes, new_nodes, MAX); |
| |
| The ret will be 0 and no errno is set. As the new_nodes is empty, we |
| should expect EINVAL as documented. |
| |
| To fix the case like above, this patch check whether target nodes AND |
| current task_nodes is empty, and then check whether AND |
| node_states[N_MEMORY] is empty. |
| |
| Link: http://lkml.kernel.org/r/1510882624-44342-4-git-send-email-xieyisheng1@huawei.com |
| Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com> |
| Acked-by: Vlastimil Babka <vbabka@suse.cz> |
| Cc: Andi Kleen <ak@linux.intel.com> |
| Cc: Chris Salls <salls@cs.ucsb.edu> |
| Cc: Christopher Lameter <cl@linux.com> |
| Cc: David Rientjes <rientjes@google.com> |
| Cc: Ingo Molnar <mingo@kernel.org> |
| Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> |
| Cc: Tan Xiaojun <tanxiaojun@huawei.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| mm/mempolicy.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| --- a/mm/mempolicy.c |
| +++ b/mm/mempolicy.c |
| @@ -1442,10 +1442,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi |
| goto out_put; |
| } |
| |
| - if (!nodes_subset(*new, node_states[N_MEMORY])) { |
| - err = -EINVAL; |
| + task_nodes = cpuset_mems_allowed(current); |
| + nodes_and(*new, *new, task_nodes); |
| + if (nodes_empty(*new)) |
| + goto out_put; |
| + |
| + nodes_and(*new, *new, node_states[N_MEMORY]); |
| + if (nodes_empty(*new)) |
| goto out_put; |
| - } |
| |
| err = security_task_movememory(task); |
| if (err) |