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: 56a22a261008 ("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 --- include/linux/hugetlb.h | 3 --- include/linux/mman.h | 14 ++++++++++++++ mm/mmap.c | 5 ++--- 3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 5c0dabc8e4e8..4a5cf4c98496 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/mmap.c b/mm/mmap.c index 6fdd884eab90..9dfef56dd0e8 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1578,9 +1578,8 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file, /* 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(mm, file, addr, len, vm_flags, pgoff, uf); if (!IS_ERR_VALUE(addr) &&