From: Ding Tianhong dingtianhong@huawei.com
ascend inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
The commit 4daf80d7164 ("arm64/ascend: Enable...") missed to set the correct dvpp mmap area when the user didn't set the MAP_DVPP flags, so add new area zone to fix this.
And fix some coding style, rename the enable_map_dvpp to enable_mmap_dvpp.
v2: return true if the input addr is DVPP_MMAP_BASE for dvpp_mmap_zone.
Fixes: 4daf80d7164 ("arm64/ascend: Enable DvPP mmap features for Ascend Platform") Signed-off-by: Ding Tianhong dingtianhong@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/mm/init.c | 2 +- arch/arm64/mm/mmap.c | 4 ---- drivers/char/svm.c | 4 ++-- fs/hugetlbfs/inode.c | 4 ++-- include/linux/mman.h | 57 +++++++++++++++++++++++++++++++------------- mm/mmap.c | 20 ++++++++-------- 6 files changed, 55 insertions(+), 36 deletions(-)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 08cc25afd9857..88887e0722b7c 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -771,7 +771,7 @@ __setup("keepinitrd", keepinitrd_setup); static int __init ascend_enable_setup(char *__unused) { if (IS_ENABLED(CONFIG_ASCEND_DVPP_MMAP)) - enable_map_dvpp = 1; + enable_mmap_dvpp = 1;
if (IS_ENABLED(CONFIG_ASCEND_IOPF_HIPRI)) enable_iopf_hipri = 1; diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index f25859a1c5fab..157f2caa13516 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -103,10 +103,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) mm->get_unmapped_area = arch_get_unmapped_area; } else { mm->mmap_base = mmap_base(random_factor, rlim_stack); - - if (enable_map_dvpp && dvpp_mmap_zone(mm->mmap_base)) - mm->mmap_base = DVPP_MMAP_BASE; - mm->get_unmapped_area = arch_get_unmapped_area_topdown; } } diff --git a/drivers/char/svm.c b/drivers/char/svm.c index 7f9d854e15f94..87cf6c14dbc12 100644 --- a/drivers/char/svm.c +++ b/drivers/char/svm.c @@ -1526,8 +1526,8 @@ static unsigned long svm_get_unmapped_area(struct file *file, info.low_limit = TASK_UNMAPPED_BASE; info.high_limit = DVPP_MMAP_BASE;
- if (enable_map_dvpp) - dvpp_mmap_get_area(info); + if (enable_mmap_dvpp) + dvpp_mmap_get_area(&info, flags);
addr = vm_unmapped_area(&info); } diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 2ac900f022809..7a8994585b891 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -277,8 +277,8 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, info.align_mask = PAGE_MASK & ~huge_page_mask(h); info.align_offset = 0;
- if (enable_map_dvpp) - dvpp_mmap_get_area(info); + if (enable_mmap_dvpp) + dvpp_mmap_get_area(&info, flags);
return vm_unmapped_area(&info); } diff --git a/include/linux/mman.h b/include/linux/mman.h index 8a443bca454de..f4c25c06653c0 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -8,7 +8,7 @@ #include <linux/atomic.h> #include <uapi/linux/mman.h>
- +extern int enable_mmap_dvpp; /* * Enable MAP_32BIT for Ascend Platform */ @@ -16,31 +16,56 @@
#define MAP_DVPP 0x200
-#define DVPP_MMAP_BASE (TASK_SIZE - 0x100000000UL) #define DVPP_MMAP_SIZE (0x100000000UL) +#define DVPP_MMAP_BASE (TASK_SIZE - DVPP_MMAP_SIZE)
-#define dvpp_mmap_check(addr, len, flags) \ - (((enable_map_dvpp) && (flags & MAP_DVPP) && \ - (addr < DVPP_MMAP_BASE + DVPP_MMAP_SIZE) && \ - (addr > DVPP_MMAP_BASE)) ? -EINVAL : 0) +static inline int dvpp_mmap_check(unsigned long addr, unsigned long len, + unsigned long flags) +{ + if (enable_mmap_dvpp && (flags & MAP_DVPP) && + (addr < DVPP_MMAP_BASE + DVPP_MMAP_SIZE) && + (addr > DVPP_MMAP_BASE)) + return -EINVAL; + else + return 0; +}
-#define dvpp_mmap_get_area(info) \ -({ \ - (info.low_limit = DVPP_MMAP_BASE); \ - (info.high_limit = DVPP_MMAP_BASE + DVPP_MMAP_SIZE); \ -}) +static inline void dvpp_mmap_get_area(struct vm_unmapped_area_info *info, + unsigned long flags) +{ + if (flags & MAP_DVPP) { + info->low_limit = DVPP_MMAP_BASE; + info->high_limit = DVPP_MMAP_BASE + DVPP_MMAP_SIZE; + } else { + info->low_limit = max(info->low_limit, TASK_UNMAPPED_BASE); + info->high_limit = min(info->high_limit, DVPP_MMAP_BASE); + } +}
-#define dvpp_mmap_zone(addr) ((addr > DVPP_MMAP_BASE) ? 1 : 0) +static inline int dvpp_mmap_zone(unsigned long addr) +{ + if (addr >= DVPP_MMAP_BASE) + return 1; + else + return 0; +}
#else
#define MAP_DVPP (0)
-#define dvpp_mmap_check(addr, len, flags) (0) +static inline int dvpp_mmap_check(unsigned long addr, unsigned long len, + unsigned long flags) +{ + return 0; +}
-#define dvpp_mmap_get_area(info) do { } while (0) +static inline void dvpp_mmap_get_area(struct vm_unmapped_area_info *info, + unsigned long flags) +{ +}
-#define dvpp_mmap_zone(addr) (0) +static inline int dvpp_mmap_zone(unsigned long addr) { return 0; }
#define DVPP_MMAP_BASE (0)
@@ -48,8 +73,6 @@
#endif
-extern int enable_map_dvpp; - /* * 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 f6a1e46bc6d9f..fd1b27b82f5ab 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2099,8 +2099,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, info.high_limit = TASK_SIZE; info.align_mask = 0;
- if (enable_map_dvpp) - dvpp_mmap_get_area(info); + if (enable_mmap_dvpp) + dvpp_mmap_get_area(&info, flags);
return vm_unmapped_area(&info); } @@ -2148,8 +2148,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.high_limit = mm->mmap_base; info.align_mask = 0;
- if (enable_map_dvpp) - dvpp_mmap_get_area(info); + if (enable_mmap_dvpp) + dvpp_mmap_get_area(&info, flags);
addr = vm_unmapped_area(&info);
@@ -2165,8 +2165,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.low_limit = TASK_UNMAPPED_BASE; info.high_limit = TASK_SIZE;
- if (enable_map_dvpp) - dvpp_mmap_get_area(info); + if (enable_mmap_dvpp) + dvpp_mmap_get_area(&info, flags);
addr = vm_unmapped_area(&info); } @@ -3748,18 +3748,18 @@ subsys_initcall(init_reserve_notifier); /* * Enable the MAP_32BIT (mmaps and hugetlb). */ -int enable_map_dvpp __read_mostly; +int enable_mmap_dvpp __read_mostly;
#ifdef CONFIG_ASCEND_DVPP_MMAP
-static int __init ascend_enable_map_dvpp(char *s) +static int __init ascend_enable_mmap_dvpp(char *s) { - enable_map_dvpp = 1; + enable_mmap_dvpp = 1;
pr_info("Ascend enable dvpp mmap features\n");
return 1; } -__setup("enable_map_dvpp", ascend_enable_map_dvpp); +__setup("enable_mmap_dvpp", ascend_enable_mmap_dvpp);
#endif