From: He Kuang hekuang@huawei.com
mainline inclusion from mainline-5.0-rc5 commit da06d5683868 category: bugfix bugzilla: 38073 CVE: NA
-------------------------------------------------
The annotation line percentage is compared and inserted into the rbtree, but the percent field of 'struct annotation_data' is an array, the comparison result between them is the address difference.
This patch compares the right slot of percent array according to opts->percent_type and makes things right.
The problem can be reproduced by pressing 'H' in perf top annotation view. It should highlight the instruction line which has the highest sampling percentage.
Signed-off-by: He Kuang hekuang@huawei.com Reviewed-by: Jiri Olsa jolsa@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: http://lkml.kernel.org/r/20190120160523.4391-1-hekuang@huawei.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Wei Li liwei391@huawei.com Reviewed-by: Jian Cheng cj.chengjian@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- tools/perf/ui/browsers/annotate.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index a3c255228d62..131f51131b52 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -225,20 +225,24 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser) return ret; }
-static int disasm__cmp(struct annotation_line *a, struct annotation_line *b) +static double disasm__cmp(struct annotation_line *a, struct annotation_line *b, + int percent_type) { int i;
for (i = 0; i < a->data_nr; i++) { - if (a->data[i].percent == b->data[i].percent) + if (a->data[i].percent[percent_type] == b->data[i].percent[percent_type]) continue; - return a->data[i].percent < b->data[i].percent; + return a->data[i].percent[percent_type] - + b->data[i].percent[percent_type]; } return 0; }
-static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al) +static void disasm_rb_tree__insert(struct annotate_browser *browser, + struct annotation_line *al) { + struct rb_root *root = &browser->entries; struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct annotation_line *l; @@ -247,7 +251,7 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line parent = *p; l = rb_entry(parent, struct annotation_line, rb_node);
- if (disasm__cmp(al, l)) + if (disasm__cmp(al, l, browser->opts->percent_type) < 0) p = &(*p)->rb_left; else p = &(*p)->rb_right; @@ -330,7 +334,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, RB_CLEAR_NODE(&pos->al.rb_node); continue; } - disasm_rb_tree__insert(&browser->entries, &pos->al); + disasm_rb_tree__insert(browser, &pos->al); } pthread_mutex_unlock(¬es->lock);
From: John Stultz john.stultz@linaro.org
mainline inclusion from mainline-v5.8-rc1 commit 8508f4cba308 category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
Valentine reported seeing:
[ 3.626638] INFO: trying to register non-static key. [ 3.626639] the code is fine but needs lockdep annotation. [ 3.626640] turning off the locking correctness validator. [ 3.626644] CPU: 7 PID: 51 Comm: kworker/7:1 Not tainted 5.7.0-rc2-00115-g8c2e9790f196 #116 [ 3.626646] Hardware name: HiKey960 (DT) [ 3.626656] Workqueue: events deferred_probe_work_func [ 3.632476] sd 0:0:0:0: [sda] Optimal transfer size 8192 bytes not a multiple of physical block size (16384 bytes) [ 3.640220] Call trace: [ 3.640225] dump_backtrace+0x0/0x1b8 [ 3.640227] show_stack+0x20/0x30 [ 3.640230] dump_stack+0xec/0x158 [ 3.640234] register_lock_class+0x598/0x5c0 [ 3.640235] __lock_acquire+0x80/0x16c0 [ 3.640236] lock_acquire+0xf4/0x4a0 [ 3.640241] _raw_spin_lock_irqsave+0x70/0xa8 [ 3.640245] uart_add_one_port+0x388/0x4b8 [ 3.640248] pl011_register_port+0x70/0xf0 [ 3.640250] pl011_probe+0x184/0x1b8 [ 3.640254] amba_probe+0xdc/0x180 [ 3.640256] really_probe+0xe0/0x338 [ 3.640257] driver_probe_device+0x60/0xf8 [ 3.640259] __device_attach_driver+0x8c/0xd0 [ 3.640260] bus_for_each_drv+0x84/0xd8 [ 3.640261] __device_attach+0xe4/0x140 [ 3.640263] device_initial_probe+0x1c/0x28 [ 3.640265] bus_probe_device+0xa4/0xb0 [ 3.640266] deferred_probe_work_func+0x7c/0xb8 [ 3.640269] process_one_work+0x2c0/0x768 [ 3.640271] worker_thread+0x4c/0x498 [ 3.640272] kthread+0x14c/0x158 [ 3.640275] ret_from_fork+0x10/0x1c
Which seems to be due to the fact that after allocating the uap structure, nothing initializes the spinlock.
Its a little confusing, as uart_port_spin_lock_init() is one place where the lock is supposed to be initialized, but it has an exception for the case where the port is a console.
This makes it seem like a deeper fix is needed to properly register the console, but I'm not sure what that entails, and Andy suggested that this approach is less invasive.
Thus, this patch resolves the issue by initializing the spinlock in the driver, and resolves the resulting warning.
Cc: Andy Shevchenko andy.shevchenko@gmail.com Cc: Russell King linux@armlinux.org.uk Cc: Jiri Slaby jslaby@suse.com Cc: linux-serial@vger.kernel.org Reported-by: Valentin Schneider valentin.schneider@arm.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: John Stultz john.stultz@linaro.org Reviewed-and-tested-by: Valentin Schneider valentin.schneider@arm.com Link: https://lore.kernel.org/r/20200428184050.6501-1-john.stultz@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/tty/serial/amba-pl011.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index af21122dfade..1d501154e9f7 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2585,6 +2585,7 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, uap->port.fifosize = uap->fifosize; uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = index; + spin_lock_init(&uap->port.lock);
amba_ports[index] = uap;
From: OGAWA Hirofumi hirofumi@mail.parknet.co.jp
mainline inclusion from mainline-v5.8-rc1 commit b1b65750b8db67834482f758fc385bfa7560d228 category: bugfix bugzilla: 36873 CVE: NA
---------------------------
If FAT length == 0, the image doesn't have any data. And it can be the cause of overlapping the root dir and FAT entries.
Also Windows treats it as invalid format.
Reported-by: syzbot+6f1624f937d9d6911e2d@syzkaller.appspotmail.com Signed-off-by: OGAWA Hirofumi hirofumi@mail.parknet.co.jp Signed-off-by: Andrew Morton akpm@linux-foundation.org Cc: Marco Elver elver@google.com Cc: Dmitry Vyukov dvyukov@google.com Link: http://lkml.kernel.org/r/87r1wz8mrd.fsf@mail.parknet.co.jp Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Zheng Bin zhengbin13@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/fat/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 70d37a5fd72c..607e1d124062 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1519,6 +1519,12 @@ static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b, goto out; }
+ if (bpb->fat_fat_length == 0 && bpb->fat32_length == 0) { + if (!silent) + fat_msg(sb, KERN_ERR, "bogus number of FAT sectors"); + goto out; + } + error = 0;
out:
From: "zhangyi (F)" yi.zhang@huawei.com
hulk inclusion category: bugfix bugzilla: 34619 CVE: NA ---------------------------
This reverts commit a8fcabe57a1803790fd48f1e00ec3af4db27ab2a. The upstream fix this problem throuth <7b97d868b7ab> "ext4, jbd2: ensure panic by fix a race between jbd2 abort and ext4 error handlers", so revert this patch and backport <7b97d868b7ab>.
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/super.c | 25 ++++++++++++------------- fs/jbd2/journal.c | 6 ++++-- include/linux/jbd2.h | 6 +----- 3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b10f96860dd8..553932670b80 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -498,8 +498,6 @@ static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno)
static void ext4_handle_error(struct super_block *sb) { - struct ext4_sb_info *sbi = EXT4_SB(sb); - if (test_opt(sb, WARN_ON_ERROR)) WARN_ON_ONCE(1);
@@ -507,9 +505,9 @@ static void ext4_handle_error(struct super_block *sb) return;
if (!test_opt(sb, ERRORS_CONT)) { - journal_t *journal = sbi->s_journal; + journal_t *journal = EXT4_SB(sb)->s_journal;
- sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; + EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; if (journal) jbd2_journal_abort(journal, -EIO); } @@ -530,8 +528,9 @@ static void ext4_handle_error(struct super_block *sb) smp_wmb(); sb->s_flags |= SB_RDONLY; } else if (test_opt(sb, ERRORS_PANIC)) { - if (sbi->s_journal && is_journal_aborted(sbi->s_journal)) - wait_for_completion(&sbi->s_journal->j_record_errno); + if (EXT4_SB(sb)->s_journal && + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) + return; panic("EXT4-fs (device %s): panic forced after error\n", sb->s_id); } @@ -720,11 +719,10 @@ void __ext4_std_error(struct super_block *sb, const char *function, void __ext4_abort(struct super_block *sb, const char *function, unsigned int line, const char *fmt, ...) { - struct ext4_sb_info *sbi = EXT4_SB(sb); struct va_format vaf; va_list args;
- if (unlikely(ext4_forced_shutdown(sbi))) + if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) return;
save_error_info(sb, function, line); @@ -737,21 +735,22 @@ void __ext4_abort(struct super_block *sb, const char *function,
if (sb_rdonly(sb) == 0) { ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); - sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; + EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; /* * Make sure updated value of ->s_mount_flags will be visible * before ->s_flags update */ smp_wmb(); sb->s_flags |= SB_RDONLY; - if (sbi->s_journal) - jbd2_journal_abort(sbi->s_journal, -EIO); + if (EXT4_SB(sb)->s_journal) + jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); save_error_info(sb, function, line); ext4_netlink_send_info(sb, 2); } if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) { - if (sbi->s_journal && is_journal_aborted(sbi->s_journal)) - wait_for_completion(&sbi->s_journal->j_record_errno); + if (EXT4_SB(sb)->s_journal && + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) + return; panic("EXT4-fs panic from previous error\n"); } } diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 753cbe3c50a8..7301bb766172 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1142,7 +1142,6 @@ static journal_t *journal_init_common(struct block_device *bdev, init_waitqueue_head(&journal->j_wait_commit); init_waitqueue_head(&journal->j_wait_updates); init_waitqueue_head(&journal->j_wait_reserved); - init_completion(&journal->j_record_errno); mutex_init(&journal->j_barrier); mutex_init(&journal->j_checkpoint_mutex); spin_lock_init(&journal->j_revoke_lock); @@ -2188,7 +2187,10 @@ void jbd2_journal_abort(journal_t *journal, int errno) * layer could realise that a filesystem check is needed. */ jbd2_journal_update_sb_errno(journal); - complete_all(&journal->j_record_errno); + + write_lock(&journal->j_state_lock); + journal->j_flags |= JBD2_REC_ERR; + write_unlock(&journal->j_state_lock); }
/** diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index e87a6fd79d71..12b935c9ec1e 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -788,11 +788,6 @@ struct journal_s */ int j_errno;
- /** - * @j_record_errno: complete to record errno in the journal superblock - */ - struct completion j_record_errno; - /** * @j_sb_buffer: The first part of the superblock buffer. */ @@ -1275,6 +1270,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3) #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file * data write error in ordered * mode */ +#define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */
/* * Function declarations for the journaling transaction and buffer
From: "zhangyi (F)" yi.zhang@huawei.com
mainline inclusion from mainline-v5.8-rc1 commit 7b97d868b7ab2448859668de9222b8af43f76e78 category: bugfix bugzilla: 34619 CVE: NA ---------------------------
In the ext4 filesystem with errors=panic, if one process is recording errno in the superblock when invoking jbd2_journal_abort() due to some error cases, it could be raced by another __ext4_abort() which is setting the SB_RDONLY flag but missing panic because errno has not been recorded.
jbd2_journal_commit_transaction() jbd2_journal_abort() journal->j_flags |= JBD2_ABORT; jbd2_journal_update_sb_errno() | ext4_journal_check_start() | __ext4_abort() | sb->s_flags |= SB_RDONLY; | if (!JBD2_REC_ERR) | return; journal->j_flags |= JBD2_REC_ERR;
Finally, it will no longer trigger panic because the filesystem has already been set read-only. Fix this by introduce j_abort_mutex to make sure journal abort is completed before panic, and remove JBD2_REC_ERR flag.
Fixes: 4327ba52afd03 ("ext4, jbd2: ensure entering into panic after recording an error in superblock") Signed-off-by: zhangyi (F) yi.zhang@huawei.com Reviewed-by: Jan Kara jack@suse.cz Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200609073540.3810702-1-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu
Conflict: fs/ext4/super.c
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/super.c | 16 +++++----------- fs/jbd2/journal.c | 17 ++++++++++++----- include/linux/jbd2.h | 6 +++++- 3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 553932670b80..0a950b060ace 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -528,9 +528,6 @@ static void ext4_handle_error(struct super_block *sb) smp_wmb(); sb->s_flags |= SB_RDONLY; } else if (test_opt(sb, ERRORS_PANIC)) { - if (EXT4_SB(sb)->s_journal && - !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) - return; panic("EXT4-fs (device %s): panic forced after error\n", sb->s_id); } @@ -734,25 +731,22 @@ void __ext4_abort(struct super_block *sb, const char *function, va_end(args);
if (sb_rdonly(sb) == 0) { - ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; + if (EXT4_SB(sb)->s_journal) + jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); + + ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); /* * Make sure updated value of ->s_mount_flags will be visible * before ->s_flags update */ smp_wmb(); sb->s_flags |= SB_RDONLY; - if (EXT4_SB(sb)->s_journal) - jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); save_error_info(sb, function, line); ext4_netlink_send_info(sb, 2); } - if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) { - if (EXT4_SB(sb)->s_journal && - !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) - return; + if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) panic("EXT4-fs panic from previous error\n"); - } }
void __ext4_msg(struct super_block *sb, diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 7301bb766172..344f5cf53fb5 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1142,6 +1142,7 @@ static journal_t *journal_init_common(struct block_device *bdev, init_waitqueue_head(&journal->j_wait_commit); init_waitqueue_head(&journal->j_wait_updates); init_waitqueue_head(&journal->j_wait_reserved); + mutex_init(&journal->j_abort_mutex); mutex_init(&journal->j_barrier); mutex_init(&journal->j_checkpoint_mutex); spin_lock_init(&journal->j_revoke_lock); @@ -1401,7 +1402,8 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags) printk(KERN_ERR "JBD2: Error %d detected when updating " "journal superblock for %s.\n", ret, journal->j_devname); - jbd2_journal_abort(journal, ret); + if (!is_journal_aborted(journal)) + jbd2_journal_abort(journal, ret); }
return ret; @@ -2152,6 +2154,13 @@ void jbd2_journal_abort(journal_t *journal, int errno) { transaction_t *transaction;
+ /* + * Lock the aborting procedure until everything is done, this avoid + * races between filesystem's error handling flow (e.g. ext4_abort()), + * ensure panic after the error info is written into journal's + * superblock. + */ + mutex_lock(&journal->j_abort_mutex); /* * ESHUTDOWN always takes precedence because a file system check * caused by any other journal abort error is not required after @@ -2166,6 +2175,7 @@ void jbd2_journal_abort(journal_t *journal, int errno) journal->j_errno = errno; jbd2_journal_update_sb_errno(journal); } + mutex_unlock(&journal->j_abort_mutex); return; }
@@ -2187,10 +2197,7 @@ void jbd2_journal_abort(journal_t *journal, int errno) * layer could realise that a filesystem check is needed. */ jbd2_journal_update_sb_errno(journal); - - write_lock(&journal->j_state_lock); - journal->j_flags |= JBD2_REC_ERR; - write_unlock(&journal->j_state_lock); + mutex_unlock(&journal->j_abort_mutex); }
/** diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 12b935c9ec1e..667fce234ac9 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -788,6 +788,11 @@ struct journal_s */ int j_errno;
+ /** + * @j_abort_mutex: Lock the whole aborting procedure. + */ + struct mutex j_abort_mutex; + /** * @j_sb_buffer: The first part of the superblock buffer. */ @@ -1270,7 +1275,6 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3) #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file * data write error in ordered * mode */ -#define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */
/* * Function declarations for the journaling transaction and buffer
From: Chiqijun chiqijun@huawei.com
driver inclusion category: bugfix bugzilla: 4472
-----------------------------------------------------------------------
The statistics saved by the driver are 110K. The tool only obtains 4K at a time. When the last time it is obtained, the length calculation is wrong, which may lead to out-of-bounds copy.
Signed-off-by: Chiqijun chiqijun@huawei.com Reviewed-by: Zengweiliang zengweiliang.zengweiliang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c index ab47805ca369..e49a21fa952e 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_dbg.c @@ -253,8 +253,6 @@ u16 hinic_dbg_clear_hw_stats(void *hwdev) void hinic_get_chip_fault_stats(const void *hwdev, u8 *chip_fault_stats, int offset) { - int copy_len = offset + MAX_DRV_BUF_SIZE - HINIC_CHIP_FAULT_SIZE; - if (offset < 0 || offset > HINIC_CHIP_FAULT_SIZE) { pr_err("Invalid chip offset value: %d\n", offset); return; @@ -267,7 +265,7 @@ void hinic_get_chip_fault_stats(const void *hwdev, else memcpy(chip_fault_stats, ((struct hinic_hwdev *)hwdev)->chip_fault_stats + offset, - copy_len); + HINIC_CHIP_FAULT_SIZE - offset); }
int hinic_dbg_get_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)