| From: Mike Kravetz <mike.kravetz@oracle.com> |
| Subject: migrate: hugetlb: check for hugetlb shared PMD in node migration |
| Date: Thu, 26 Jan 2023 14:27:21 -0800 |
| |
| migrate_pages/mempolicy semantics state that CAP_SYS_NICE is required to |
| move pages shared with another process to a different node. page_mapcount |
| > 1 is being used to determine if a hugetlb page is shared. However, a |
| hugetlb page will have a mapcount of 1 if mapped by multiple processes via |
| a shared PMD. As a result, hugetlb pages shared by multiple processes and |
| mapped with a shared PMD can be moved by a process without CAP_SYS_NICE. |
| |
| To fix, check for a shared PMD if mapcount is 1. If a shared PMD is found |
| consider the page shared. |
| |
| Link: https://lkml.kernel.org/r/20230126222721.222195-3-mike.kravetz@oracle.com |
| Fixes: e2d8cf405525 ("migrate: add hugepage migration code to migrate_pages()") |
| Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> |
| Acked-by: Peter Xu <peterx@redhat.com> |
| Acked-by: David Hildenbrand <david@redhat.com> |
| Cc: James Houghton <jthoughton@google.com> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Cc: Michal Hocko <mhocko@suse.com> |
| Cc: Muchun Song <songmuchun@bytedance.com> |
| Cc: Naoya Horiguchi <naoya.horiguchi@linux.dev> |
| Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com> |
| Cc: Yang Shi <shy828301@gmail.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/mempolicy.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/mm/mempolicy.c~migrate-hugetlb-check-for-hugetlb-shared-pmd-in-node-migration |
| +++ a/mm/mempolicy.c |
| @@ -600,7 +600,8 @@ static int queue_pages_hugetlb(pte_t *pt |
| |
| /* With MPOL_MF_MOVE, we migrate only unshared hugepage. */ |
| if (flags & (MPOL_MF_MOVE_ALL) || |
| - (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) { |
| + (flags & MPOL_MF_MOVE && page_mapcount(page) == 1 && |
| + !hugetlb_pmd_shared(pte))) { |
| if (isolate_hugetlb(page, qp->pagelist) && |
| (flags & MPOL_MF_STRICT)) |
| /* |
| _ |