From: "Eric W. Biederman" ebiederm@xmission.com
mainline inclusion from mainline-v5.6 commit b95e31c07c5eb4f5c0769f12b38b0343d7961040 category: bugfix bugzilla: 32426 CVE: NA
------------------------
The reasons why the extra posix_cpu_timers_exit_group() invocation has been added are not entirely clear from the commit message. Today all that posix_cpu_timers_exit_group() does is stop timers that are tracking the task from firing. Every other operation on those timers is still allowed.
The practical implication of this is posix_cpu_timer_del() which could not get the siglock after the thread group leader has exited (because sighand == NULL) would be able to run successfully because the timer was already dequeued.
With that locking issue fixed there is no point in disabling all of the timers. So remove this ``tempoary'' hack.
Fixes: e0a70217107e ("posix-cpu-timers: workaround to suppress the problems with mt exec") Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/87o8tityzs.fsf@x220.int.ebiederm.org Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- kernel/exit.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/kernel/exit.c b/kernel/exit.c index 35adc3b1e9be9..891d65e3ffd51 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -102,17 +102,8 @@ static void __exit_signal(struct task_struct *tsk)
#ifdef CONFIG_POSIX_TIMERS posix_cpu_timers_exit(tsk); - if (group_dead) { + if (group_dead) posix_cpu_timers_exit_group(tsk); - } else { - /* - * This can only happen if the caller is de_thread(). - * FIXME: this is the temporary hack, we should teach - * posix-cpu-timers to handle this case correctly. - */ - if (unlikely(has_group_leader_pid(tsk))) - posix_cpu_timers_exit_group(tsk); - } #endif
if (group_dead) {
From: "zhangyi (F)" yi.zhang@huawei.com
mainline inclusion from mainline-v5.9-rc2 commit bc71726c725767205757821df364acff87f92ac5 category: bugfix bugzilla: 34540 CVE: NA ---------------------------
There is a risk of filesystem inconsistency if we failed to async write back metadata buffer in the background. Because of current buffer's end io procedure is handled by end_buffer_async_write() in the block layer, and it only clear the buffer's uptodate flag and mark the write_io_error flag, so ext4 cannot detect such failure immediately. In most cases of getting metadata buffer (e.g. ext4_read_inode_bitmap()), although the buffer's data is actually uptodate, it may still read data from disk because the buffer's uptodate flag has been cleared. Finally, it may lead to on-disk filesystem inconsistency if reading old data from the disk successfully and write them out again.
This patch detect bdev mapping->wb_err when getting journal's write access and mark the filesystem error if bdev's mapping->wb_err was increased, this could prevent further writing and potential inconsistency.
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Suggested-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200620025427.1756360-2-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu
Conflict: fs/ext4/super.c fs/ext4/ext4_jbd2.c
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Reviewed-by: Yang Erkun yangerkun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/ext4.h | 4 ++++ fs/ext4/ext4_jbd2.c | 24 ++++++++++++++++++++++++ fs/ext4/super.c | 17 +++++++++++++++++ 3 files changed, 45 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4491b9911807c..03cf8faf51b9f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1535,6 +1535,10 @@ struct ext4_sb_info { */ struct percpu_rw_semaphore s_writepages_rwsem; struct dax_device *s_daxdev; + + /* Record the errseq of the backing block device */ + errseq_t s_bdev_wb_err; + spinlock_t s_bdev_wb_lock; };
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index d3b8cdea5df75..2048e30db852a 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -173,6 +173,27 @@ static void ext4_journal_abort_handle(const char *caller, unsigned int line, jbd2_journal_abort_handle(handle); }
+static void ext4_check_bdev_write_error(struct super_block *sb) +{ + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; + struct ext4_sb_info *sbi = EXT4_SB(sb); + int err; + + /* + * If the block device has write error flag, it may have failed to + * async write out metadata buffers in the background. In this case, + * we could read old data from disk and write it out again, which + * may lead to on-disk filesystem inconsistency. + */ + if (errseq_check(&mapping->wb_err, READ_ONCE(sbi->s_bdev_wb_err))) { + spin_lock(&sbi->s_bdev_wb_lock); + err = errseq_check_and_advance(&mapping->wb_err, &sbi->s_bdev_wb_err); + spin_unlock(&sbi->s_bdev_wb_lock); + if (err) + ext4_error(sb, "Error while async write back metadata"); + } +} + int __ext4_journal_get_write_access(const char *where, unsigned int line, handle_t *handle, struct buffer_head *bh) { @@ -180,6 +201,9 @@ int __ext4_journal_get_write_access(const char *where, unsigned int line,
might_sleep();
+ if (bh->b_bdev->bd_super) + ext4_check_bdev_write_error(bh->b_bdev->bd_super); + if (ext4_handle_valid(handle)) { err = jbd2_journal_get_write_access(handle, bh); if (err) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b6b6a25cce081..170542479954e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4591,6 +4591,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } #endif /* CONFIG_QUOTA */
+ /* + * Save the original bdev mapping's wb_err value which could be + * used to detect the metadata async write error. + */ + spin_lock_init(&sbi->s_bdev_wb_lock); + if (!sb_rdonly(sb)) + errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err, + &sbi->s_bdev_wb_err); + sb->s_bdev->bd_super = sb; EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; ext4_orphan_cleanup(sb, es); EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; @@ -5438,6 +5447,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; }
+ /* + * Update the original bdev mapping's wb_err value + * which could be used to detect the metadata async + * write error. + */ + errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err, + &sbi->s_bdev_wb_err); + /* * Mounting a RDONLY partition read-write, so reread * and store the current valid flag. (It may have
From: "zhangyi (F)" yi.zhang@huawei.com
mainline inclusion from mainline-v5.9-rc2 commit c044f3d8360d2ecf831ba2cc9f08cf9fb2c699fb category: bugfix bugzilla: 34540 CVE: NA ---------------------------
If we free a metadata buffer which has been failed to async write out in the background, the jbd2 checkpoint procedure will not detect this failure in jbd2_log_do_checkpoint(), so it may lead to filesystem inconsistency after cleanup journal tail. This patch abort the journal if free a buffer has write_io_error flag to prevent potential further inconsistency.
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Link: https://lore.kernel.org/r/20200620025427.1756360-5-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Yang Erkun yangerkun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/jbd2/transaction.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index c39613161cc2a..37ede30b59815 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -2082,6 +2082,7 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, { struct buffer_head *head; struct buffer_head *bh; + bool has_write_io_error = false; int ret = 0;
J_ASSERT(PageLocked(page)); @@ -2106,11 +2107,26 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, jbd_unlock_bh_state(bh); if (buffer_jbd(bh)) goto busy; + + /* + * If we free a metadata buffer which has been failed to + * write out, the jbd2 checkpoint procedure will not detect + * this failure and may lead to filesystem inconsistency + * after cleanup journal tail. + */ + if (buffer_write_io_error(bh)) { + pr_err("JBD2: Error while async write back metadata bh %llu.", + (unsigned long long)bh->b_blocknr); + has_write_io_error = true; + } } while ((bh = bh->b_this_page) != head);
ret = try_to_free_buffers(page);
busy: + if (has_write_io_error) + jbd2_journal_abort(journal, -EIO); + return ret; }
From: Qiujun Huang hqjagain@gmail.com
mainline inclusion from mainline-5.7-rc1 commit dce8e237100f60c28cc66effb526ba65a01d8cb3 category: bugfix bugzilla: 33842 CVE: NA
-------------------------------------------------
KCSAN find inode->i_disksize could be accessed concurrently.
BUG: KCSAN: data-race in ext4_mark_iloc_dirty / ext4_write_end
write (marked) to 0xffff8b8932f40090 of 8 bytes by task 66792 on cpu 0: ext4_write_end+0x53f/0x5b0 ext4_da_write_end+0x237/0x510 generic_perform_write+0x1c4/0x2a0 ext4_buffered_write_iter+0x13a/0x210 ext4_file_write_iter+0xe2/0x9b0 new_sync_write+0x29c/0x3a0 __vfs_write+0x92/0xa0 vfs_write+0xfc/0x2a0 ksys_write+0xe8/0x140 __x64_sys_write+0x4c/0x60 do_syscall_64+0x8a/0x2a0 entry_SYSCALL_64_after_hwframe+0x44/0xa9
read to 0xffff8b8932f40090 of 8 bytes by task 14414 on cpu 1: ext4_mark_iloc_dirty+0x716/0x1190 ext4_mark_inode_dirty+0xc9/0x360 ext4_convert_unwritten_extents+0x1bc/0x2a0 ext4_convert_unwritten_io_end_vec+0xc5/0x150 ext4_put_io_end+0x82/0x130 ext4_writepages+0xae7/0x16f0 do_writepages+0x64/0x120 __writeback_single_inode+0x7d/0x650 writeback_sb_inodes+0x3a4/0x860 __writeback_inodes_wb+0xc4/0x150 wb_writeback+0x43f/0x510 wb_workfn+0x3b2/0x8a0 process_one_work+0x39b/0x7e0 worker_thread+0x88/0x650 kthread+0x1d4/0x1f0 ret_from_fork+0x35/0x40
The plain read is outside of inode->i_data_sem critical section which results in a data race. Fix it by adding READ_ONCE().
Signed-off-by: Qiujun Huang hqjagain@gmail.com Link: https://lore.kernel.org/r/1582556566-3909-1-git-send-email-hqjagain@gmail.co... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 89a363a2e0bf0..81abc917f2b0f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5316,7 +5316,7 @@ static int ext4_do_update_inode(handle_t *handle, raw_inode->i_file_acl_high = cpu_to_le16(ei->i_file_acl >> 32); raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl); - if (ei->i_disksize != ext4_isize(inode->i_sb, raw_inode)) { + if (READ_ONCE(ei->i_disksize) != ext4_isize(inode->i_sb, raw_inode)) { ext4_isize_set(raw_inode, ei->i_disksize); need_datasync = 1; }
From: Harshad Shirwadkar harshadshirwadkar@gmail.com
mainline inclusion from mainline-v5.7-rc1 commit f2eeca099bbda45029da35abecb428a9084a5463 category: bugfix bugzilla: 41998 CVE: NA
-----------------------------------------------
Writeback errors can leave buffer in not up-to-date state when there are errors during background writes. Force buffer up-to-date while marking it dirty.
Signed-off-by: Harshad Shirwadkar harshadshirwadkar@gmail.com Link: https://lore.kernel.org/r/20191224190940.157952-1-harshadshirwadkar@gmail.co... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/ext4_jbd2.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index 2048e30db852a..a589b7f795582 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -332,6 +332,7 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, err); } } else { + set_buffer_uptodate(bh); if (inode) mark_buffer_dirty_inode(bh, inode); else
From: Jan Kara jack@suse.cz
mainline inclusion from mainline-5.8-rc1 commit 4301efa4c7cca11556dd89899eee066d49b47bf7 category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
Ext4 needs to remove inode from writeback lists after it is out of visibility of its journalling machinery (which can still dirty the inode). Export inode_io_list_del() for it.
Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200421085445.5731-3-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/fs-writeback.c | 1 + fs/internal.h | 2 -- include/linux/writeback.h | 1 + 3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index fe1604ad90230..83aee2a33d102 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1045,6 +1045,7 @@ void inode_io_list_del(struct inode *inode) inode_io_list_del_locked(inode, wb); spin_unlock(&wb->list_lock); } +EXPORT_SYMBOL(inode_io_list_del);
/* * mark an inode as under writeback on the sb diff --git a/fs/internal.h b/fs/internal.h index b2705b6dccdb6..9ddf9ba82bdb1 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -136,8 +136,6 @@ extern int dentry_needs_remove_privs(struct dentry *dentry); /* * fs-writeback.c */ -extern void inode_io_list_del(struct inode *inode); - extern long get_nr_dirty_inodes(void); extern int invalidate_inodes(struct super_block *, bool);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 1b5feef03462b..539c01869b843 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -174,6 +174,7 @@ void wakeup_flusher_threads(enum wb_reason reason); void wakeup_flusher_threads_bdi(struct backing_dev_info *bdi, enum wb_reason reason); void inode_wait_for_writeback(struct inode *inode); +void inode_io_list_del(struct inode *inode);
/* writeback.h requires fs.h; it, too, is not included from here. */ static inline void wait_on_inode(struct inode *inode)
From: Jan Kara jack@suse.cz
mainline inclusion from mainline-5.8-rc1 commit ceff86fddae8748fe00d4f2d249cb02cae62ad84 category: bugfix bugzilla: 37213 CVE: NA
-------------------------------------------------
When we are evicting inode with journalled data, we may race with transaction commit in the following way:
CPU0 CPU1 jbd2_journal_commit_transaction() evict(inode) inode_io_list_del() inode_wait_for_writeback() process BJ_Forget list __jbd2_journal_insert_checkpoint() __jbd2_journal_refile_buffer() __jbd2_journal_unfile_buffer() if (test_clear_buffer_jbddirty(bh)) mark_buffer_dirty(bh) __mark_inode_dirty(inode) ext4_evict_inode(inode) frees the inode
This results in use-after-free issues in the writeback code (or the assertion added in the previous commit triggering).
Fix the problem by removing inode from writeback lists once all the page cache is evicted and so inode cannot be added to writeback lists again.
Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200421085445.5731-4-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/inode.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 81abc917f2b0f..f2a82cdc6b1e7 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -222,6 +222,16 @@ void ext4_evict_inode(struct inode *inode) ext4_begin_ordered_truncate(inode, 0); truncate_inode_pages_final(&inode->i_data);
+ /* + * For inodes with journalled data, transaction commit could have + * dirtied the inode. Flush worker is ignoring it because of I_FREEING + * flag but we still need to remove the inode from the writeback lists. + */ + if (!list_empty_careful(&inode->i_io_list)) { + WARN_ON_ONCE(!ext4_should_journal_data(inode)); + inode_io_list_del(inode); + } + /* * Protect us against freezing - iput() caller didn't have to have any * protection against it
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