From: Fang Lijun fanglijun3@huawei.com
ascend inclusion category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
The vm_flags will overflow on arm32 as left shift CHECKNODE_BITS(48).
This checknode function only used in cdm feature.
Fixes: cdccf4d4b7b5 ("arm64/ascend: mm: Add MAP_CHECKNODE flag to check node hugetlb") Signed-off-by: Fang Lijun fanglijun3@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- include/linux/hugetlb.h | 3 --- include/linux/mman.h | 14 ++++++++++++++ mm/hugetlb.c | 1 + mm/mmap.c | 5 ++--- 4 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 9cd938bb24fe..3f355dfaf31f 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -15,9 +15,6 @@ struct ctl_table; struct user_struct; struct mmu_gather;
-#define CHECKNODE_BITS 48 -#define CHECKNODE_MASK (~((_AC(1, UL) << CHECKNODE_BITS) - 1)) - #ifndef is_hugepd /* * Some architectures requires a hugepage directory format that is diff --git a/include/linux/mman.h b/include/linux/mman.h index f4c25c06653c..d35d984c058c 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -73,6 +73,20 @@ static inline int dvpp_mmap_zone(unsigned long addr) { return 0; }
#endif
+#ifdef CONFIG_COHERENT_DEVICE +#define CHECKNODE_BITS 48 +#define CHECKNODE_MASK (~((_AC(1, UL) << CHECKNODE_BITS) - 1)) +static inline void set_vm_checknode(vm_flags_t vm_flags, unsigned long flags) +{ + if (is_set_cdmmask()) + vm_flags |= VM_CHECKNODE | ((((flags >> MAP_HUGE_SHIFT) & + MAP_HUGE_MASK) << CHECKNODE_BITS) & CHECKNODE_MASK); +} +#else +#define CHECKNODE_BITS (0) +static inline void set_vm_checknode(vm_flags_t vm_flags, unsigned long flags) {} +#endif + /* * Arrange for legacy / undefined architecture specific flags to be * ignored by mmap handling code. diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 327d24f0cf0d..7c2f51528c1c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -25,6 +25,7 @@ #include <linux/swap.h> #include <linux/swapops.h> #include <linux/jhash.h> +#include <linux/mman.h>
#include <asm/page.h> #include <asm/pgtable.h> diff --git a/mm/mmap.c b/mm/mmap.c index 6197c5590ded..4cc9ee8a0287 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1564,9 +1564,8 @@ unsigned long do_mmap(struct file *file, unsigned long addr, /* set numa node id into vm_flags, * hugetlbfs file mmap will use it to check node */ - if (is_set_cdmmask() && (flags & MAP_CHECKNODE)) - vm_flags |= VM_CHECKNODE | ((((flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK) - << CHECKNODE_BITS) & CHECKNODE_MASK); + if (flags & MAP_CHECKNODE) + set_vm_checknode(vm_flags, flags);
addr = mmap_region(file, addr, len, vm_flags, pgoff, uf); if (!IS_ERR_VALUE(addr) &&