
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 -- 2.25.1