From: Aurelien Aptel aaptel@suse.com
[ Upstream commit bc31d0cdcfbadb6258b45db97e93b1c83822ba33 ]
We have a customer reporting crashes in lock_get_status() with many "Leaked POSIX lock" messages preceeding the crash.
Leaked POSIX lock on dev=0x0:0x56 ... Leaked POSIX lock on dev=0x0:0x56 ... Leaked POSIX lock on dev=0x0:0x56 ... Leaked POSIX lock on dev=0x0:0x53 ... Leaked POSIX lock on dev=0x0:0x53 ... Leaked POSIX lock on dev=0x0:0x53 ... Leaked POSIX lock on dev=0x0:0x53 ... POSIX: fl_owner=ffff8900e7b79380 fl_flags=0x1 fl_type=0x1 fl_pid=20709 Leaked POSIX lock on dev=0x0:0x4b ino... Leaked locks on dev=0x0:0x4b ino=0xf911400000029: POSIX: fl_owner=ffff89f41c870e00 fl_flags=0x1 fl_type=0x1 fl_pid=19592 stack segment: 0000 [#1] SMP Modules linked in: binfmt_misc msr tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag rpcsec_gss_krb5 arc4 ecb auth_rpcgss nfsv4 md4 nfs nls_utf8 lockd grace cifs sunrpc ccm dns_resolver fscache af_packet iscsi_ibft iscsi_boot_sysfs vmw_vsock_vmci_transport vsock xfs libcrc32c sb_edac edac_core crct10dif_pclmul crc32_pclmul ghash_clmulni_intel drbg ansi_cprng vmw_balloon aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd joydev pcspkr vmxnet3 i2c_piix4 vmw_vmci shpchp fjes processor button ac btrfs xor raid6_pq sr_mod cdrom ata_generic sd_mod ata_piix vmwgfx crc32c_intel drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm serio_raw ahci libahci drm libata vmw_pvscsi sg dm_multipath dm_mod scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4
Supported: Yes CPU: 6 PID: 28250 Comm: lsof Not tainted 4.4.156-94.64-default #1 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/05/2016 task: ffff88a345f28740 ti: ffff88c74005c000 task.ti: ffff88c74005c000 RIP: 0010:[<ffffffff8125dcab>] [<ffffffff8125dcab>] lock_get_status+0x9b/0x3b0 RSP: 0018:ffff88c74005fd90 EFLAGS: 00010202 RAX: ffff89bde83e20ae RBX: ffff89e870003d18 RCX: 0000000049534f50 RDX: ffffffff81a3541f RSI: ffffffff81a3544e RDI: ffff89bde83e20ae RBP: 0026252423222120 R08: 0000000020584953 R09: 000000000000ffff R10: 0000000000000000 R11: ffff88c74005fc70 R12: ffff89e5ca7b1340 R13: 00000000000050e5 R14: ffff89e870003d30 R15: ffff89e5ca7b1340 FS: 00007fafd64be800(0000) GS:ffff89f41fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000001c80018 CR3: 000000a522048000 CR4: 0000000000360670 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Stack: 0000000000000208 ffffffff81a3d6b6 ffff89e870003d30 ffff89e870003d18 ffff89e5ca7b1340 ffff89f41738d7c0 ffff89e870003d30 ffff89e5ca7b1340 ffffffff8125e08f 0000000000000000 ffff89bc22b67d00 ffff88c74005ff28 Call Trace: [<ffffffff8125e08f>] locks_show+0x2f/0x70 [<ffffffff81230ad1>] seq_read+0x251/0x3a0 [<ffffffff81275bbc>] proc_reg_read+0x3c/0x70 [<ffffffff8120e456>] __vfs_read+0x26/0x140 [<ffffffff8120e9da>] vfs_read+0x7a/0x120 [<ffffffff8120faf2>] SyS_read+0x42/0xa0 [<ffffffff8161cbc3>] entry_SYSCALL_64_fastpath+0x1e/0xb7
When Linux closes a FD (close(), close-on-exec, dup2(), ...) it calls filp_close() which also removes all posix locks.
The lock struct is initialized like so in filp_close() and passed down to cifs
... lock.fl_type = F_UNLCK; lock.fl_flags = FL_POSIX | FL_CLOSE; lock.fl_start = 0; lock.fl_end = OFFSET_MAX; ...
Note the FL_CLOSE flag, which hints the VFS code that this unlocking is done for closing the fd.
filp_close() locks_remove_posix(filp, id); vfs_lock_file(filp, F_SETLK, &lock, NULL); return filp->f_op->lock(filp, cmd, fl) => cifs_lock() rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock, unlock, xid); rc = server->ops->mand_unlock_range(cfile, flock, xid); if (flock->fl_flags & FL_POSIX && !rc) rc = locks_lock_file_wait(file, flock)
Notice how we don't call locks_lock_file_wait() which does the generic VFS lock/unlock/wait work on the inode if rc != 0.
If we are closing the handle, the SMB server is supposed to remove any locks associated with it. Similarly, cifs.ko frees and wakes up any lock and lock waiter when closing the file:
cifs_close() cifsFileInfo_put(file->private_data) /* * Delete any outstanding lock records. We'll lose them when the file * is closed anyway. */ down_write(&cifsi->lock_sem); list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) { list_del(&li->llist); cifs_del_lock_waiters(li); kfree(li); } list_del(&cifs_file->llist->llist); kfree(cifs_file->llist); up_write(&cifsi->lock_sem);
So we can safely ignore unlocking failures in cifs_lock() if they happen with the FL_CLOSE flag hint set as both the server and the client take care of it during the actual closing.
This is not a proper fix for the unlocking failure but it's safe and it seems to prevent the lock leakages and crashes the customer experiences.
Signed-off-by: Aurelien Aptel aaptel@suse.com Signed-off-by: NeilBrown neil@brown.name Signed-off-by: Steve French stfrench@microsoft.com Acked-by: Pavel Shilovsky pshilov@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/file.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 08761a6a039d..d847132ab027 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1631,8 +1631,20 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, rc = server->ops->mand_unlock_range(cfile, flock, xid);
out: - if (flock->fl_flags & FL_POSIX && !rc) + if (flock->fl_flags & FL_POSIX) { + /* + * If this is a request to remove all locks because we + * are closing the file, it doesn't matter if the + * unlocking failed as both cifs.ko and the SMB server + * remove the lock on file close + */ + if (rc) { + cifs_dbg(VFS, "%s failed rc=%d\n", __func__, rc); + if (!(flock->fl_flags & FL_CLOSE)) + return rc; + } rc = locks_lock_file_wait(file, flock); + } return rc; }
From: Masahiro Yamada yamada.masahiro@socionext.com
[ Upstream commit fc2b47b55f17fd996f7a01975ce1c33c2f2513f6 ]
It believe it is a bad idea to hardcode a specific compiler prefix that may or may not be installed on a user's system. It is annoying when testing features that should not require compilers at all.
For example, mrproper, headers_install, etc. should work without any compiler.
They look like follows on my machine.
$ make ARCH=h8300 mrproper ./scripts/gcc-version.sh: line 26: h8300-unknown-linux-gcc: command not found ./scripts/gcc-version.sh: line 27: h8300-unknown-linux-gcc: command not found make: h8300-unknown-linux-gcc: Command not found make: h8300-unknown-linux-gcc: Command not found [ a bunch of the same error messages continue ]
$ make ARCH=h8300 headers_install ./scripts/gcc-version.sh: line 26: h8300-unknown-linux-gcc: command not found ./scripts/gcc-version.sh: line 27: h8300-unknown-linux-gcc: command not found make: h8300-unknown-linux-gcc: Command not found HOSTCC scripts/basic/fixdep make: h8300-unknown-linux-gcc: Command not found WRAP arch/h8300/include/generated/uapi/asm/kvm_para.h [ snip ]
The solution is to delete this line, or to use cc-cross-prefix like some architectures do. I chose the latter as a moderate fixup.
I added an alternative 'h8300-linux-' because it is available at:
https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/h8300/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile index 58634e6bae92..55f251810129 100644 --- a/arch/h8300/Makefile +++ b/arch/h8300/Makefile @@ -27,7 +27,7 @@ KBUILD_LDFLAGS += $(ldflags-y) CHECKFLAGS += -msize-long
ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := h8300-unknown-linux- +CROSS_COMPILE := $(call cc-cross-prefix, h8300-unknown-linux- h8300-linux-) endif
core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
From: Chao Yu yuchao0@huawei.com
[ Upstream commit 2c28aba8b2e2a51749fa66e01b68e1cd5b53e022 ]
With below testcase, we will fail to find existed xattr entry:
1. mkfs.f2fs -O extra_attr -O flexible_inline_xattr /dev/zram0 2. mount -t f2fs -o inline_xattr_size=1 /dev/zram0 /mnt/f2fs/ 3. touch /mnt/f2fs/file 4. setfattr -n "user.name" -v 0 /mnt/f2fs/file 5. getfattr -n "user.name" /mnt/f2fs/file
/mnt/f2fs/file: user.name: No such attribute
The reason is for inode which has very small inline xattr size, __find_inline_xattr() will fail to traverse any entry due to first entry may not be loaded from xattr node yet, later, we may skip to check entire xattr datas in __find_xattr(), result in such wrong condition.
This patch adds condition to check such case to avoid this issue.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/xattr.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 087e53a2d96c..409a637f7a92 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -227,11 +227,11 @@ static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode, { struct f2fs_xattr_entry *entry; unsigned int inline_size = inline_xattr_size(inode); + void *max_addr = base_addr + inline_size;
list_for_each_xattr(entry, base_addr) { - if ((void *)entry + sizeof(__u32) > base_addr + inline_size || - (void *)XATTR_NEXT_ENTRY(entry) + sizeof(__u32) > - base_addr + inline_size) { + if ((void *)entry + sizeof(__u32) > max_addr || + (void *)XATTR_NEXT_ENTRY(entry) > max_addr) { *last_addr = entry; return NULL; } @@ -242,6 +242,13 @@ static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode, if (!memcmp(entry->e_name, name, len)) break; } + + /* inline xattr header or entry across max inline xattr size */ + if (IS_XATTR_LAST_ENTRY(entry) && + (void *)entry + sizeof(__u32) > max_addr) { + *last_addr = entry; + return NULL; + } return entry; }
From: Chao Yu yuchao0@huawei.com
[ Upstream commit aadcef64b22f668c1a107b86d3521d9cac915c24 ]
As Jiqun Li reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=202883
sometimes, dead lock when make system call SYS_getdents64 with fsync() is called by another process.
monkey running on android9.0
1. task 9785 held sbi->cp_rwsem and waiting lock_page() 2. task 10349 held mm_sem and waiting sbi->cp_rwsem 3. task 9709 held lock_page() and waiting mm_sem
so this is a dead lock scenario.
task stack is show by crash tools as following
crash_arm64> bt ffffffc03c354080 PID: 9785 TASK: ffffffc03c354080 CPU: 1 COMMAND: "RxIoScheduler-3"
#7 [ffffffc01b50fac0] __lock_page at ffffff80081b11e8
crash-arm64> bt 10349 PID: 10349 TASK: ffffffc018b83080 CPU: 1 COMMAND: "BUGLY_ASYNC_UPL"
#3 [ffffffc01f8cfa40] rwsem_down_read_failed at ffffff8008a93afc
PC: 00000033 LR: 00000000 SP: 00000000 PSTATE: ffffffffffffffff
crash-arm64> bt 9709 PID: 9709 TASK: ffffffc03e7f3080 CPU: 1 COMMAND: "IntentService[A"
#3 [ffffffc001e67850] rwsem_down_read_failed at ffffff8008a93afc #8 [ffffffc001e67b80] el1_ia at ffffff8008084fc4
PC: ffffff8008274114 [compat_filldir64+120] LR: ffffff80083584d4 [f2fs_fill_dentries+448] SP: ffffffc001e67b80 PSTATE: 80400145 X29: ffffffc001e67b80 X28: 0000000000000000 X27: 000000000000001a X26: 00000000000093d7 X25: ffffffc070d52480 X24: 0000000000000008 X23: 0000000000000028 X22: 00000000d43dfd60 X21: ffffffc001e67e90 X20: 0000000000000011 X19: ffffff80093a4000 X18: 0000000000000000 X17: 0000000000000000 X16: 0000000000000000 X15: 0000000000000000 X14: ffffffffffffffff X13: 0000000000000008 X12: 0101010101010101 X11: 7f7f7f7f7f7f7f7f X10: 6a6a6a6a6a6a6a6a X9: 7f7f7f7f7f7f7f7f X8: 0000000080808000 X7: ffffff800827409c X6: 0000000080808000 X5: 0000000000000008 X4: 00000000000093d7 X3: 000000000000001a X2: 0000000000000011 X1: ffffffc070d52480 X0: 0000000000800238
#9 [ffffffc001e67be0] f2fs_fill_dentries at ffffff80083584d0
PC: 0000003c LR: 00000000 SP: 00000000 PSTATE: 000000d9 X12: f48a02ff X11: d4678960 X10: d43dfc00 X9: d4678ae4 X8: 00000058 X7: d4678994 X6: d43de800 X5: 000000d9 X4: d43dfc0c X3: d43dfc10 X2: d46799c8 X1: 00000000 X0: 00001068
Below potential deadlock will happen between three threads: Thread A Thread B Thread C - f2fs_do_sync_file - f2fs_write_checkpoint - down_write(&sbi->node_change) -- 1) - do_page_fault - down_write(&mm->mmap_sem) -- 2) - do_wp_page - f2fs_vm_page_mkwrite - getdents64 - f2fs_read_inline_dir - lock_page -- 3) - f2fs_sync_node_pages - lock_page -- 3) - __do_map_lock - down_read(&sbi->node_change) -- 1) - f2fs_fill_dentries - dir_emit - compat_filldir64 - do_page_fault - down_read(&mm->mmap_sem) -- 2)
Since f2fs_readdir is protected by inode.i_rwsem, there should not be any updates in inode page, we're safe to lookup dents in inode page without its lock held, so taking off the lock to improve concurrency of readdir and avoid potential deadlock.
Reported-by: Jiqun Li jiqun.li@unisoc.com Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/inline.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 115dc219344b..92703efde36e 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -661,6 +661,12 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, if (IS_ERR(ipage)) return PTR_ERR(ipage);
+ /* + * f2fs_readdir was protected by inode.i_rwsem, it is safe to access + * ipage without page's lock held. + */ + unlock_page(ipage); + inline_dentry = inline_data_addr(inode, ipage);
make_dentry_ptr_inline(inode, &d, inline_dentry); @@ -669,7 +675,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, if (!err) ctx->pos = d.max;
- f2fs_put_page(ipage, 1); + f2fs_put_page(ipage, 0); return err < 0 ? err : 0; }
From: Chao Yu yuchao0@huawei.com
[ Upstream commit 48432984d718c95cf13e26d487c2d1b697c3c01f ]
Thread A Thread B - __fput - f2fs_release_file - drop_inmem_pages - mutex_lock(&fi->inmem_lock) - __revoke_inmem_pages - lock_page(page) - open - f2fs_setattr - truncate_setsize - truncate_inode_pages_range - lock_page(page) - truncate_cleanup_page - f2fs_invalidate_page - drop_inmem_page - mutex_lock(&fi->inmem_lock);
We may encounter above ABBA deadlock as reported by Kyungtae Kim:
I'm reporting a bug in linux-4.17.19: "INFO: task hung in drop_inmem_page" (no reproducer)
I think this might be somehow related to the following: https://groups.google.com/forum/#%21searchin/syzkaller-bugs/INFO%243A%2420ta...
========================================= INFO: task syz-executor7:10822 blocked for more than 120 seconds. Not tainted 4.17.19 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. syz-executor7 D27024 10822 6346 0x00000004 Call Trace: context_switch kernel/sched/core.c:2867 [inline] __schedule+0x721/0x1e60 kernel/sched/core.c:3515 schedule+0x88/0x1c0 kernel/sched/core.c:3559 schedule_preempt_disabled+0x18/0x30 kernel/sched/core.c:3617 __mutex_lock_common kernel/locking/mutex.c:833 [inline] __mutex_lock+0x5bd/0x1410 kernel/locking/mutex.c:893 mutex_lock_nested+0x1b/0x20 kernel/locking/mutex.c:908 drop_inmem_page+0xcb/0x810 fs/f2fs/segment.c:327 f2fs_invalidate_page+0x337/0x5e0 fs/f2fs/data.c:2401 do_invalidatepage mm/truncate.c:165 [inline] truncate_cleanup_page+0x261/0x330 mm/truncate.c:187 truncate_inode_pages_range+0x552/0x1610 mm/truncate.c:367 truncate_inode_pages mm/truncate.c:478 [inline] truncate_pagecache+0x6d/0x90 mm/truncate.c:801 truncate_setsize+0x81/0xa0 mm/truncate.c:826 f2fs_setattr+0x44f/0x1270 fs/f2fs/file.c:781 notify_change+0xa62/0xe80 fs/attr.c:313 do_truncate+0x12e/0x1e0 fs/open.c:63 do_last fs/namei.c:2955 [inline] path_openat+0x2042/0x29f0 fs/namei.c:3505 do_filp_open+0x1bd/0x2c0 fs/namei.c:3540 do_sys_open+0x35e/0x4e0 fs/open.c:1101 __do_sys_open fs/open.c:1119 [inline] __se_sys_open fs/open.c:1114 [inline] __x64_sys_open+0x89/0xc0 fs/open.c:1114 do_syscall_64+0xc4/0x4e0 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4497b9 RSP: 002b:00007f734e459c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 RAX: ffffffffffffffda RBX: 00007f734e45a6cc RCX: 00000000004497b9 RDX: 0000000000000104 RSI: 00000000000a8280 RDI: 0000000020000080 RBP: 000000000071bea0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 0000000000007230 R14: 00000000006f02d0 R15: 00007f734e45a700 INFO: task syz-executor7:10858 blocked for more than 120 seconds. Not tainted 4.17.19 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. syz-executor7 D28880 10858 6346 0x00000004 Call Trace: context_switch kernel/sched/core.c:2867 [inline] __schedule+0x721/0x1e60 kernel/sched/core.c:3515 schedule+0x88/0x1c0 kernel/sched/core.c:3559 __rwsem_down_write_failed_common kernel/locking/rwsem-xadd.c:565 [inline] rwsem_down_write_failed+0x5e6/0xc90 kernel/locking/rwsem-xadd.c:594 call_rwsem_down_write_failed+0x17/0x30 arch/x86/lib/rwsem.S:117 __down_write arch/x86/include/asm/rwsem.h:142 [inline] down_write+0x58/0xa0 kernel/locking/rwsem.c:72 inode_lock include/linux/fs.h:713 [inline] do_truncate+0x120/0x1e0 fs/open.c:61 do_last fs/namei.c:2955 [inline] path_openat+0x2042/0x29f0 fs/namei.c:3505 do_filp_open+0x1bd/0x2c0 fs/namei.c:3540 do_sys_open+0x35e/0x4e0 fs/open.c:1101 __do_sys_open fs/open.c:1119 [inline] __se_sys_open fs/open.c:1114 [inline] __x64_sys_open+0x89/0xc0 fs/open.c:1114 do_syscall_64+0xc4/0x4e0 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4497b9 RSP: 002b:00007f734e3b4c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 RAX: ffffffffffffffda RBX: 00007f734e3b56cc RCX: 00000000004497b9 RDX: 0000000000000104 RSI: 00000000000a8280 RDI: 0000000020000080 RBP: 000000000071c238 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 0000000000007230 R14: 00000000006f02d0 R15: 00007f734e3b5700 INFO: task syz-executor5:10829 blocked for more than 120 seconds. Not tainted 4.17.19 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. syz-executor5 D28760 10829 6308 0x80000002 Call Trace: context_switch kernel/sched/core.c:2867 [inline] __schedule+0x721/0x1e60 kernel/sched/core.c:3515 schedule+0x88/0x1c0 kernel/sched/core.c:3559 io_schedule+0x21/0x80 kernel/sched/core.c:5179 wait_on_page_bit_common mm/filemap.c:1100 [inline] __lock_page+0x2b5/0x390 mm/filemap.c:1273 lock_page include/linux/pagemap.h:483 [inline] __revoke_inmem_pages+0xb35/0x11c0 fs/f2fs/segment.c:231 drop_inmem_pages+0xa3/0x3e0 fs/f2fs/segment.c:306 f2fs_release_file+0x2c7/0x330 fs/f2fs/file.c:1556 __fput+0x2c7/0x780 fs/file_table.c:209 ____fput+0x1a/0x20 fs/file_table.c:243 task_work_run+0x151/0x1d0 kernel/task_work.c:113 exit_task_work include/linux/task_work.h:22 [inline] do_exit+0x8ba/0x30a0 kernel/exit.c:865 do_group_exit+0x13b/0x3a0 kernel/exit.c:968 get_signal+0x6bb/0x1650 kernel/signal.c:2482 do_signal+0x84/0x1b70 arch/x86/kernel/signal.c:810 exit_to_usermode_loop+0x155/0x190 arch/x86/entry/common.c:162 prepare_exit_to_usermode arch/x86/entry/common.c:196 [inline] syscall_return_slowpath arch/x86/entry/common.c:265 [inline] do_syscall_64+0x445/0x4e0 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4497b9 RSP: 002b:00007f1c68e74ce8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca RAX: fffffffffffffe00 RBX: 000000000071bf80 RCX: 00000000004497b9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000000071bf80 RBP: 000000000071bf80 R08: 0000000000000000 R09: 000000000071bf58 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f1c68e759c0 R15: 00007f1c68e75700
This patch tries to use trylock_page to mitigate such deadlock condition for fix.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 30779aaa9dba..1fa6f8185766 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -216,7 +216,8 @@ void f2fs_register_inmem_page(struct inode *inode, struct page *page) }
static int __revoke_inmem_pages(struct inode *inode, - struct list_head *head, bool drop, bool recover) + struct list_head *head, bool drop, bool recover, + bool trylock) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct inmem_pages *cur, *tmp; @@ -228,7 +229,16 @@ static int __revoke_inmem_pages(struct inode *inode, if (drop) trace_f2fs_commit_inmem_page(page, INMEM_DROP);
- lock_page(page); + if (trylock) { + /* + * to avoid deadlock in between page lock and + * inmem_lock. + */ + if (!trylock_page(page)) + continue; + } else { + lock_page(page); + }
f2fs_wait_on_page_writeback(page, DATA, true);
@@ -317,13 +327,19 @@ void f2fs_drop_inmem_pages(struct inode *inode) struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode);
- mutex_lock(&fi->inmem_lock); - __revoke_inmem_pages(inode, &fi->inmem_pages, true, false); - spin_lock(&sbi->inode_lock[ATOMIC_FILE]); - if (!list_empty(&fi->inmem_ilist)) - list_del_init(&fi->inmem_ilist); - spin_unlock(&sbi->inode_lock[ATOMIC_FILE]); - mutex_unlock(&fi->inmem_lock); + while (!list_empty(&fi->inmem_pages)) { + mutex_lock(&fi->inmem_lock); + __revoke_inmem_pages(inode, &fi->inmem_pages, + true, false, true); + + if (list_empty(&fi->inmem_pages)) { + spin_lock(&sbi->inode_lock[ATOMIC_FILE]); + if (!list_empty(&fi->inmem_ilist)) + list_del_init(&fi->inmem_ilist); + spin_unlock(&sbi->inode_lock[ATOMIC_FILE]); + } + mutex_unlock(&fi->inmem_lock); + }
clear_inode_flag(inode, FI_ATOMIC_FILE); fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0; @@ -427,12 +443,15 @@ static int __f2fs_commit_inmem_pages(struct inode *inode) * recovery or rewrite & commit last transaction. For other * error number, revoking was done by filesystem itself. */ - err = __revoke_inmem_pages(inode, &revoke_list, false, true); + err = __revoke_inmem_pages(inode, &revoke_list, + false, true, false);
/* drop all uncommitted pages */ - __revoke_inmem_pages(inode, &fi->inmem_pages, true, false); + __revoke_inmem_pages(inode, &fi->inmem_pages, + true, false, false); } else { - __revoke_inmem_pages(inode, &revoke_list, false, false); + __revoke_inmem_pages(inode, &revoke_list, + false, false, false); }
return err;
From: Louis Taylor louis@kragniz.eu
[ Upstream commit 60f7691c624b41a05bfc3493d9b0519e7951b7ef ]
When compiling with -Wformat, clang warns:
drivers/i2c/busses/i2c-sis630.c:482:4: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat] smbus_base + SMB_STS, ^~~~~~~~~~~~~~~~~~~~
drivers/i2c/busses/i2c-sis630.c:483:4: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat] smbus_base + SMB_STS + SIS630_SMB_IOREGION - 1); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/i2c/busses/i2c-sis630.c:531:37: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat] "SMBus SIS630 adapter at %04hx", smbus_base + SMB_STS); ~~~~~ ^~~~~~~~~~~~~~~~~~~~
This patch fixes the format strings to use the format type for int.
Link: https://github.com/ClangBuiltLinux/linux/issues/378 Signed-off-by: Louis Taylor louis@kragniz.eu Reviewed-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Jean Delvare jdelvare@suse.de Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-sis630.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 1e6805b5cef2..a57aa4fe51a4 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -478,7 +478,7 @@ static int sis630_setup(struct pci_dev *sis630_dev) if (!request_region(smbus_base + SMB_STS, SIS630_SMB_IOREGION, sis630_driver.name)) { dev_err(&sis630_dev->dev, - "I/O Region 0x%04hx-0x%04hx for SMBus already in use.\n", + "I/O Region 0x%04x-0x%04x for SMBus already in use.\n", smbus_base + SMB_STS, smbus_base + SMB_STS + SIS630_SMB_IOREGION - 1); retval = -EBUSY; @@ -528,7 +528,7 @@ static int sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) sis630_adapter.dev.parent = &dev->dev;
snprintf(sis630_adapter.name, sizeof(sis630_adapter.name), - "SMBus SIS630 adapter at %04hx", smbus_base + SMB_STS); + "SMBus SIS630 adapter at %04x", smbus_base + SMB_STS);
return i2c_add_adapter(&sis630_adapter); }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 31b265b3baaf55f209229888b7ffea523ddab366 ]
As reported back in 2016-11 [1], the "ftdump" kdb command triggers a BUG for "sleeping function called from invalid context".
kdb's "ftdump" command wants to call ring_buffer_read_prepare() in atomic context. A very simple solution for this is to add allocation flags to ring_buffer_read_prepare() so kdb can call it without triggering the allocation error. This patch does that.
Note that in the original email thread about this, it was suggested that perhaps the solution for kdb was to either preallocate the buffer ahead of time or create our own iterator. I'm hoping that this alternative of adding allocation flags to ring_buffer_read_prepare() can be considered since it means I don't need to duplicate more of the core trace code into "trace_kdb.c" (for either creating my own iterator or re-preparing a ring allocator whose memory was already allocated).
NOTE: another option for kdb is to actually figure out how to make it reuse the existing ftrace_dump() function and totally eliminate the duplication. This sounds very appealing and actually works (the "sr z" command can be seen to properly dump the ftrace buffer). The downside here is that ftrace_dump() fully consumes the trace buffer. Unless that is changed I'd rather not use it because it means "ftdump | grep xyz" won't be very useful to search the ftrace buffer since it will throw away the whole trace on the first grep. A future patch to dump only the last few lines of the buffer will also be hard to implement.
[1] https://lkml.kernel.org/r/20161117191605.GA21459@google.com
Link: http://lkml.kernel.org/r/20190308193205.213659-1-dianders@chromium.org
Reported-by: Brian Norris briannorris@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/ring_buffer.h | 2 +- kernel/trace/ring_buffer.c | 5 +++-- kernel/trace/trace.c | 6 ++++-- kernel/trace/trace_kdb.c | 6 ++++-- 4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 0940fda59872..941bfd9b3c89 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -128,7 +128,7 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts, unsigned long *lost_events);
struct ring_buffer_iter * -ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu); +ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags); void ring_buffer_read_prepare_sync(void); void ring_buffer_read_start(struct ring_buffer_iter *iter); void ring_buffer_read_finish(struct ring_buffer_iter *iter); diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 65bd4616220d..34b4c32b0692 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4141,6 +4141,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume); * ring_buffer_read_prepare - Prepare for a non consuming read of the buffer * @buffer: The ring buffer to read from * @cpu: The cpu buffer to iterate over + * @flags: gfp flags to use for memory allocation * * This performs the initial preparations necessary to iterate * through the buffer. Memory is allocated, buffer recording @@ -4158,7 +4159,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume); * This overall must be paired with ring_buffer_read_finish. */ struct ring_buffer_iter * -ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu) +ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags) { struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_iter *iter; @@ -4166,7 +4167,7 @@ ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu) if (!cpumask_test_cpu(cpu, buffer->cpumask)) return NULL;
- iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc(sizeof(*iter), flags); if (!iter) return NULL;
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1f96b292df31..c65cea71d1ee 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3903,7 +3903,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) if (iter->cpu_file == RING_BUFFER_ALL_CPUS) { for_each_tracing_cpu(cpu) { iter->buffer_iter[cpu] = - ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); + ring_buffer_read_prepare(iter->trace_buffer->buffer, + cpu, GFP_KERNEL); } ring_buffer_read_prepare_sync(); for_each_tracing_cpu(cpu) { @@ -3913,7 +3914,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) } else { cpu = iter->cpu_file; iter->buffer_iter[cpu] = - ring_buffer_read_prepare(iter->trace_buffer->buffer, cpu); + ring_buffer_read_prepare(iter->trace_buffer->buffer, + cpu, GFP_KERNEL); ring_buffer_read_prepare_sync(); ring_buffer_read_start(iter->buffer_iter[cpu]); tracing_iter_reset(iter, cpu); diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index d953c163a079..810d78a8d14c 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -51,14 +51,16 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) if (cpu_file == RING_BUFFER_ALL_CPUS) { for_each_tracing_cpu(cpu) { iter.buffer_iter[cpu] = - ring_buffer_read_prepare(iter.trace_buffer->buffer, cpu); + ring_buffer_read_prepare(iter.trace_buffer->buffer, + cpu, GFP_ATOMIC); ring_buffer_read_start(iter.buffer_iter[cpu]); tracing_iter_reset(&iter, cpu); } } else { iter.cpu_file = cpu_file; iter.buffer_iter[cpu_file] = - ring_buffer_read_prepare(iter.trace_buffer->buffer, cpu_file); + ring_buffer_read_prepare(iter.trace_buffer->buffer, + cpu_file, GFP_ATOMIC); ring_buffer_read_start(iter.buffer_iter[cpu_file]); tracing_iter_reset(&iter, cpu_file); }
From: Tonghao Zhang xiangxia.m.yue@gmail.com
[ Upstream commit 24319258660a84dd77f4be026a55b10a12524919 ]
If we try to set VFs rate on a VF (not PF) net device, the kernel will be crash. The commands are show as below:
$ echo 2 > /sys/class/net/$MLX_PF0/device/sriov_numvfs $ ip link set $MLX_VF0 vf 0 max_tx_rate 2 min_tx_rate 1
If not applied the first patch ("net/mlx5: Avoid panic when setting vport mac, getting vport config"), the command:
$ ip link set $MLX_VF0 vf 0 rate 100
can also crash the kernel.
[ 1650.006388] RIP: 0010:mlx5_eswitch_set_vport_rate+0x1f/0x260 [mlx5_core] [ 1650.007092] do_setlink+0x982/0xd20 [ 1650.007129] __rtnl_newlink+0x528/0x7d0 [ 1650.007374] rtnl_newlink+0x43/0x60 [ 1650.007407] rtnetlink_rcv_msg+0x2a2/0x320 [ 1650.007484] netlink_rcv_skb+0xcb/0x100 [ 1650.007519] netlink_unicast+0x17f/0x230 [ 1650.007554] netlink_sendmsg+0x2d2/0x3d0 [ 1650.007592] sock_sendmsg+0x36/0x50 [ 1650.007625] ___sys_sendmsg+0x280/0x2a0 [ 1650.007963] __sys_sendmsg+0x58/0xa0 [ 1650.007998] do_syscall_64+0x5b/0x180 [ 1650.009438] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Fixes: c9497c98901c ("net/mlx5: Add support for setting VF min rate") Cc: Mohamad Haj Yahia mohamad@mellanox.com Signed-off-by: Tonghao Zhang xiangxia.m.yue@gmail.com Reviewed-by: Roi Dayan roid@mellanox.com Acked-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index d6706475a3ba..886a4a77c47f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -2044,19 +2044,24 @@ static int normalize_vports_min_rate(struct mlx5_eswitch *esw, u32 divider) int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport, u32 max_rate, u32 min_rate) { - u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); - bool min_rate_supported = MLX5_CAP_QOS(esw->dev, esw_bw_share) && - fw_max_bw_share >= MLX5_MIN_BW_SHARE; - bool max_rate_supported = MLX5_CAP_QOS(esw->dev, esw_rate_limit); struct mlx5_vport *evport; + u32 fw_max_bw_share; u32 previous_min_rate; u32 divider; + bool min_rate_supported; + bool max_rate_supported; int err = 0;
if (!ESW_ALLOWED(esw)) return -EPERM; if (!LEGAL_VPORT(esw, vport)) return -EINVAL; + + fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); + min_rate_supported = MLX5_CAP_QOS(esw->dev, esw_bw_share) && + fw_max_bw_share >= MLX5_MIN_BW_SHARE; + max_rate_supported = MLX5_CAP_QOS(esw->dev, esw_rate_limit); + if ((min_rate && !min_rate_supported) || (max_rate && !max_rate_supported)) return -EOPNOTSUPP;
From: Tonghao Zhang xiangxia.m.yue@gmail.com
[ Upstream commit 6e77c413e8e73d0f36b5358b601389d75ec4451c ]
If we try to set VFs mac address on a VF (not PF) net device, the kernel will be crash. The commands are show as below:
$ echo 2 > /sys/class/net/$MLX_PF0/device/sriov_numvfs $ ip link set $MLX_VF0 vf 0 mac 00:11:22:33:44:00
[exception RIP: mlx5_eswitch_set_vport_mac+41] [ffffb8b7079e3688] do_setlink at ffffffff8f67f85b [ffffb8b7079e37a8] __rtnl_newlink at ffffffff8f683778 [ffffb8b7079e3b68] rtnl_newlink at ffffffff8f683a63 [ffffb8b7079e3b90] rtnetlink_rcv_msg at ffffffff8f67d812 [ffffb8b7079e3c10] netlink_rcv_skb at ffffffff8f6b88ab [ffffb8b7079e3c60] netlink_unicast at ffffffff8f6b808f [ffffb8b7079e3ca0] netlink_sendmsg at ffffffff8f6b8412 [ffffb8b7079e3d18] sock_sendmsg at ffffffff8f6452f6 [ffffb8b7079e3d30] ___sys_sendmsg at ffffffff8f645860 [ffffb8b7079e3eb0] __sys_sendmsg at ffffffff8f647a38 [ffffb8b7079e3f38] do_syscall_64 at ffffffff8f00401b [ffffb8b7079e3f50] entry_SYSCALL_64_after_hwframe at ffffffff8f80008c
and
[exception RIP: mlx5_eswitch_get_vport_config+12] [ffffa70607e57678] mlx5e_get_vf_config at ffffffffc03c7f8f [mlx5_core] [ffffa70607e57688] do_setlink at ffffffffbc67fa59 [ffffa70607e577a8] __rtnl_newlink at ffffffffbc683778 [ffffa70607e57b68] rtnl_newlink at ffffffffbc683a63 [ffffa70607e57b90] rtnetlink_rcv_msg at ffffffffbc67d812 [ffffa70607e57c10] netlink_rcv_skb at ffffffffbc6b88ab [ffffa70607e57c60] netlink_unicast at ffffffffbc6b808f [ffffa70607e57ca0] netlink_sendmsg at ffffffffbc6b8412 [ffffa70607e57d18] sock_sendmsg at ffffffffbc6452f6 [ffffa70607e57d30] ___sys_sendmsg at ffffffffbc645860 [ffffa70607e57eb0] __sys_sendmsg at ffffffffbc647a38 [ffffa70607e57f38] do_syscall_64 at ffffffffbc00401b [ffffa70607e57f50] entry_SYSCALL_64_after_hwframe at ffffffffbc80008c
Fixes: a8d70a054a718 ("net/mlx5: E-Switch, Disallow vlan/spoofcheck setup if not being esw manager") Cc: Eli Cohen eli@mellanox.com Signed-off-by: Tonghao Zhang xiangxia.m.yue@gmail.com Reviewed-by: Roi Dayan roid@mellanox.com Acked-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 886a4a77c47f..26c9f9421901 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1797,7 +1797,7 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, u64 node_guid; int err = 0;
- if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) + if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager)) return -EPERM; if (!LEGAL_VPORT(esw, vport) || is_multicast_ether_addr(mac)) return -EINVAL; @@ -1871,7 +1871,7 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, { struct mlx5_vport *evport;
- if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) + if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager)) return -EPERM; if (!LEGAL_VPORT(esw, vport)) return -EINVAL;
From: Russell King rmk+kernel@armlinux.org.uk
[ Upstream commit d01849f7deba81f4959fd9e51bf20dbf46987d1c ]
Tony notes that the GPIO module does not idle when level interrupts are in use, as the wakeup appears to get stuck.
After extensive investigation, it appears that the wakeup will only be cleared if the interrupt status register is cleared while the interrupt is enabled. However, we are currently clearing it with the interrupt disabled for level-based interrupts.
It is acknowledged that this observed behaviour conflicts with a statement in the TRM:
CAUTION After servicing the interrupt, the status bit in the interrupt status register (GPIOi.GPIO_IRQSTATUS_0 or GPIOi.GPIO_IRQSTATUS_1) must be reset and the interrupt line released (by setting the corresponding bit of the interrupt status register to 1) before enabling an interrupt for the GPIO channel in the interrupt-enable register (GPIOi.GPIO_IRQSTATUS_SET_0 or GPIOi.GPIO_IRQSTATUS_SET_1) to prevent the occurrence of unexpected interrupts when enabling an interrupt for the GPIO channel.
However, this does not appear to be a practical problem.
Further, as reported by Grygorii Strashko grygorii.strashko@ti.com, the TI Android kernel tree has an earlier similar patch as "GPIO: OMAP: Fix the sequence to clear the IRQ status" saying:
if the status is cleared after disabling the IRQ then sWAKEUP will not be cleared and gates the module transition
When we unmask the level interrupt after the interrupt has been handled, enable the interrupt and only then clear the interrupt. If the interrupt is still pending, the hardware will re-assert the interrupt status.
Should the caution note in the TRM prove to be a problem, we could use a clear-enable-clear sequence instead.
Cc: Aaro Koskinen aaro.koskinen@iki.fi Cc: Keerthy j-keerthy@ti.com Cc: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Russell King rmk+kernel@armlinux.org.uk [tony@atomide.com: updated comments based on an earlier TI patch] Signed-off-by: Tony Lindgren tony@atomide.com Acked-by: Grygorii Strashko grygorii.strashko@ti.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-omap.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e81008678a38..6c1acf642c8e 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -888,14 +888,16 @@ static void omap_gpio_unmask_irq(struct irq_data *d) if (trigger) omap_set_gpio_triggering(bank, offset, trigger);
- /* For level-triggered GPIOs, the clearing must be done after - * the HW source is cleared, thus after the handler has run */ - if (bank->level_mask & BIT(offset)) { - omap_set_gpio_irqenable(bank, offset, 0); + omap_set_gpio_irqenable(bank, offset, 1); + + /* + * For level-triggered GPIOs, clearing must be done after the source + * is cleared, thus after the handler has run. OMAP4 needs this done + * after enabing the interrupt to clear the wakeup status. + */ + if (bank->level_mask & BIT(offset)) omap_clear_gpio_irqstatus(bank, offset); - }
- omap_set_gpio_irqenable(bank, offset, 1); raw_spin_unlock_irqrestore(&bank->lock, flags); }
From: Luc Van Oostenryck luc.vanoostenryck@gmail.com
[ Upstream commit 62461ac2e5b6520b6d65fc6d7d7b4b8df4b848d8 ]
The percpu member of this structure is declared as: struct ... ** __percpu member; So its type is: __percpu pointer to pointer to struct ...
But looking at how it's used, its type should be: pointer to __percpu pointer to struct ... and it should thus be declared as: struct ... * __percpu *member;
So fix the placement of '__percpu' in the definition of this structures.
This silents a few Sparse's warnings like: warning: incorrect type in initializer (different address spaces) expected void const [noderef] asn:3 *__vpp_verify got struct sched_domain **
Link: http://lkml.kernel.org/r/20190118144902.79065-1-luc.vanoostenryck@gmail.com Fixes: 017c59c042d01 ("relay: Use per CPU constructs for the relay channel buffer pointers") Signed-off-by: Luc Van Oostenryck luc.vanoostenryck@gmail.com Cc: Jens Axboe axboe@suse.de Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/relay.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/relay.h b/include/linux/relay.h index e1bdf01a86e2..c759f96e39c1 100644 --- a/include/linux/relay.h +++ b/include/linux/relay.h @@ -66,7 +66,7 @@ struct rchan struct kref kref; /* channel refcount */ void *private_data; /* for user-defined data */ size_t last_toobig; /* tried to log event > subbuf size */ - struct rchan_buf ** __percpu buf; /* per-cpu channel buffers */ + struct rchan_buf * __percpu *buf; /* per-cpu channel buffers */ int is_global; /* One global buffer ? */ struct list_head list; /* for channel list */ struct dentry *parent; /* parent dentry passed to open */
From: Christian Brauner christian@brauner.io
[ Upstream commit 32a5ad9c22852e6bd9e74bdec5934ef9d1480bc5 ]
Currently, when writing
echo 18446744073709551616 > /proc/sys/fs/file-max
/proc/sys/fs/file-max will overflow and be set to 0. That quickly crashes the system.
This commit sets the max and min value for file-max. The max value is set to long int. Any higher value cannot currently be used as the percpu counters are long ints and not unsigned integers.
Note that the file-max value is ultimately parsed via __do_proc_doulongvec_minmax(). This function does not report error when min or max are exceeded. Which means if a value largen that long int is written userspace will not receive an error instead the old value will be kept. There is an argument to be made that this should be changed and __do_proc_doulongvec_minmax() should return an error when a dedicated min or max value are exceeded. However this has the potential to break userspace so let's defer this to an RFC patch.
Link: http://lkml.kernel.org/r/20190107222700.15954-3-christian@brauner.io Signed-off-by: Christian Brauner christian@brauner.io Acked-by: Kees Cook keescook@chromium.org Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Dominik Brodowski linux@dominikbrodowski.net Cc: "Eric W. Biederman" ebiederm@xmission.com Cc: Joe Lawrence joe.lawrence@redhat.com Cc: Luis Chamberlain mcgrof@kernel.org Cc: Waiman Long longman@redhat.com [christian@brauner.io: v4] Link: http://lkml.kernel.org/r/20190210203943.8227-3-christian@brauner.io Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sysctl.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3b86acd5de4e..9e22660153ff 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -126,6 +126,7 @@ static int __maybe_unused one = 1; static int __maybe_unused two = 2; static int __maybe_unused four = 4; static unsigned long one_ul = 1; +static unsigned long long_max = LONG_MAX; static int one_hundred = 100; static int one_thousand = 1000; #ifdef CONFIG_PRINTK @@ -1695,6 +1696,8 @@ static struct ctl_table fs_table[] = { .maxlen = sizeof(files_stat.max_files), .mode = 0644, .proc_handler = proc_doulongvec_minmax, + .extra1 = &zero, + .extra2 = &long_max, }, { .procname = "nr_open",
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit df103170854e87124ee7bdd2bca64b178e653f97 ]
When building with -Wsometimes-uninitialized, Clang warns:
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:495:3: warning: variable 'ns' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:495:3: warning: variable 'ns' is used uninitialized whenever '&&' condition is false [-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:532:3: warning: variable 'ns' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:532:3: warning: variable 'ns' is used uninitialized whenever '&&' condition is false [-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:741:3: warning: variable 'sec_inc' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:741:3: warning: variable 'sec_inc' is used uninitialized whenever '&&' condition is false [-Wsometimes-uninitialized]
Clang is concerned with the use of stmmac_do_void_callback (which stmmac_get_timestamp and stmmac_config_sub_second_increment wrap), as it may fail to initialize these values if the if condition was ever false (meaning the callbacks don't exist). It's not wrong because the callbacks (get_timestamp and config_sub_second_increment respectively) are the ones that initialize the variables. While it's unlikely that the callbacks are ever going to disappear and make that condition false, we can easily avoid this warning by zero initialize the variables.
Link: https://github.com/ClangBuiltLinux/linux/issues/384 Suggested-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 43ab9e905bed..886176be818e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -474,7 +474,7 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, struct sk_buff *skb) { struct skb_shared_hwtstamps shhwtstamp; - u64 ns; + u64 ns = 0;
if (!priv->hwts_tx_en) return; @@ -513,7 +513,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, { struct skb_shared_hwtstamps *shhwtstamp = NULL; struct dma_desc *desc = p; - u64 ns; + u64 ns = 0;
if (!priv->hwts_rx_en) return; @@ -558,8 +558,8 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) u32 snap_type_sel = 0; u32 ts_master_en = 0; u32 ts_event_en = 0; + u32 sec_inc = 0; u32 value = 0; - u32 sec_inc; bool xmac;
xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 43d281662fdb46750d49417559b71069f435298d ]
The enic driver relies on the CONFIG_CPUMASK_OFFSTACK feature to dynamically allocate a struct member, but this is normally intended for local variables.
Building with clang, I get a warning for a few locations that check the address of the cpumask_var_t:
drivers/net/ethernet/cisco/enic/enic_main.c:122:22: error: address of array 'enic->msix[i].affinity_mask' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion]
As far as I can tell, the code is still correct, as the truth value of the pointer is what we need in this configuration. To get rid of the warning, use cpumask_available() instead of checking the pointer directly.
Fixes: 322cf7e3a4e8 ("enic: assign affinity hint to interrupts") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/cisco/enic/enic_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 9a7f70db20c7..733d9172425b 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -119,7 +119,7 @@ static void enic_init_affinity_hint(struct enic *enic)
for (i = 0; i < enic->intr_count; i++) { if (enic_is_err_intr(enic, i) || enic_is_notify_intr(enic, i) || - (enic->msix[i].affinity_mask && + (cpumask_available(enic->msix[i].affinity_mask) && !cpumask_empty(enic->msix[i].affinity_mask))) continue; if (zalloc_cpumask_var(&enic->msix[i].affinity_mask, @@ -148,7 +148,7 @@ static void enic_set_affinity_hint(struct enic *enic) for (i = 0; i < enic->intr_count; i++) { if (enic_is_err_intr(enic, i) || enic_is_notify_intr(enic, i) || - !enic->msix[i].affinity_mask || + !cpumask_available(enic->msix[i].affinity_mask) || cpumask_empty(enic->msix[i].affinity_mask)) continue; err = irq_set_affinity_hint(enic->msix_entry[i].vector, @@ -161,7 +161,7 @@ static void enic_set_affinity_hint(struct enic *enic) for (i = 0; i < enic->wq_count; i++) { int wq_intr = enic_msix_wq_intr(enic, i);
- if (enic->msix[wq_intr].affinity_mask && + if (cpumask_available(enic->msix[wq_intr].affinity_mask) && !cpumask_empty(enic->msix[wq_intr].affinity_mask)) netif_set_xps_queue(enic->netdev, enic->msix[wq_intr].affinity_mask,
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 8e2688876c7f7073d925e1f150e86b8ed3338f52 ]
libbpf targets don't explicitly depend on fixdep target, so when we do 'make -j$(nproc)', there is a high probability, that some objects will be built before fixdep binary is available.
Fix this by running sub-make; this makes sure that fixdep dependency is properly accounted for.
For the same issue in perf, see commit abb26210a395 ("perf tools: Force fixdep compilation at the start of the build").
Before:
$ rm -rf /tmp/bld; mkdir /tmp/bld; make -j$(nproc) O=/tmp/bld -C tools/lib/bpf/
Auto-detecting system features: ... libelf: [ on ] ... bpf: [ on ]
HOSTCC /tmp/bld/fixdep.o CC /tmp/bld/libbpf.o CC /tmp/bld/bpf.o CC /tmp/bld/btf.o CC /tmp/bld/nlattr.o CC /tmp/bld/libbpf_errno.o CC /tmp/bld/str_error.o CC /tmp/bld/netlink.o CC /tmp/bld/bpf_prog_linfo.o CC /tmp/bld/libbpf_probes.o CC /tmp/bld/xsk.o HOSTLD /tmp/bld/fixdep-in.o LINK /tmp/bld/fixdep LD /tmp/bld/libbpf-in.o LINK /tmp/bld/libbpf.a LINK /tmp/bld/libbpf.so LINK /tmp/bld/test_libbpf
$ head /tmp/bld/.libbpf.o.cmd # cannot find fixdep (/usr/local/google/home/sdf/src/linux/xxx//fixdep) # using basic dep data
/tmp/bld/libbpf.o: libbpf.c /usr/include/stdc-predef.h \ /usr/include/stdlib.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \
After:
$ rm -rf /tmp/bld; mkdir /tmp/bld; make -j$(nproc) O=/tmp/bld -C tools/lib/bpf/
Auto-detecting system features: ... libelf: [ on ] ... bpf: [ on ]
HOSTCC /tmp/bld/fixdep.o HOSTLD /tmp/bld/fixdep-in.o LINK /tmp/bld/fixdep CC /tmp/bld/libbpf.o CC /tmp/bld/bpf.o CC /tmp/bld/nlattr.o CC /tmp/bld/btf.o CC /tmp/bld/libbpf_errno.o CC /tmp/bld/str_error.o CC /tmp/bld/netlink.o CC /tmp/bld/bpf_prog_linfo.o CC /tmp/bld/libbpf_probes.o CC /tmp/bld/xsk.o LD /tmp/bld/libbpf-in.o LINK /tmp/bld/libbpf.a LINK /tmp/bld/libbpf.so LINK /tmp/bld/test_libbpf
$ head /tmp/bld/.libbpf.o.cmd cmd_/tmp/bld/libbpf.o := gcc -Wp,-MD,/tmp/bld/.libbpf.o.d -Wp,-MT,/tmp/bld/libbpf.o -g -Wall -DHAVE_LIBELF_MMAP_SUPPORT -DCOMPAT_NEED_REALLOCARRAY -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wstrict-aliasing=3 -Werror -Wall -fPIC -I. -I/usr/local/google/home/sdf/src/linux/tools/include -I/usr/local/google/home/sdf/src/linux/tools/arch/x86/include/uapi -I/usr/local/google/home/sdf/src/linux/tools/include/uapi -fvisibility=hidden -D"BUILD_STR(s)=$(pound)s" -c -o /tmp/bld/libbpf.o libbpf.c
source_/tmp/bld/libbpf.o := libbpf.c
deps_/tmp/bld/libbpf.o := \ /usr/include/stdc-predef.h \ /usr/include/stdlib.h \ /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \
Fixes: 7c422f557266 ("tools build: Build fixdep helper from perf and basic libs") Reported-by: Eric Dumazet edumazet@google.com Signed-off-by: Stanislav Fomichev sdf@google.com Acked-by: Yonghong Song yhs@fb.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index d49902e818b5..3624557550a1 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -149,7 +149,8 @@ CMD_TARGETS = $(LIB_FILE)
TARGETS = $(CMD_TARGETS)
-all: fixdep all_cmd +all: fixdep + $(Q)$(MAKE) all_cmd
all_cmd: $(CMD_TARGETS)
From: John Garry john.garry@huawei.com
[ Upstream commit efdcad62e7b8a02fcccc5ccca57806dce1482ac8 ]
When the PHY comes down, we currently do not set the negotiated linkrate:
root@(none)$ pwd /sys/class/sas_phy/phy-0:0 root@(none)$ more enable 1 root@(none)$ more negotiated_linkrate 12.0 Gbit root@(none)$ echo 0 > enable root@(none)$ more negotiated_linkrate 12.0 Gbit root@(none)$
This patch fixes the driver code to set it properly when the PHY comes down.
If the PHY had been enabled, then set unknown; otherwise, flag as disabled.
The logical place to set the negotiated linkrate for this scenario is PHY down routine, which is called from the PHY down ISR.
However, it is not possible to know if the PHY comes down due to PHY disable or loss of link, as sas_phy.enabled member is not set until after the transport disable routine is complete, which races with the PHY down ISR.
As an imperfect solution, use sas_phy_data.enable as the flag to know if the PHY is down due to disable. It's imperfect, as sas_phy_data is internal to libsas.
I can't see another way without adding a new field to hisi_sas_phy and managing it, or changing SCSI SAS transport.
Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index a4e2e6aa9a6b..c25f3a9b0b9f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -10,6 +10,7 @@ */
#include "hisi_sas.h" +#include "../libsas/sas_internal.h" #define DRV_NAME "hisi_sas"
#define DEV_IS_GONE(dev) \ @@ -1879,9 +1880,18 @@ static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type,
static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) { + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct sas_phy *sphy = sas_phy->phy; + struct sas_phy_data *d = sphy->hostdata; + phy->phy_attached = 0; phy->phy_type = 0; phy->port = NULL; + + if (d->enable) + sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; + else + sphy->negotiated_linkrate = SAS_PHY_DISABLED; }
void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
From: Xiang Chen chenxiang66@hisilicon.com
[ Upstream commit 4790595723d4b833b18c994973d39f9efb842887 ]
For internal IO and SMP IO, there is a time-out timer for them. In the timer handler, it checks whether IO is done according to the flag task->task_state_lock.
There is an issue which may cause system suspended: internal IO or SMP IO is sent, but at that time because of hardware exception (such as inject 2Bit ECC error), so IO is not completed and also not timeout. But, at that time, the SAS controller reset occurs to recover system. It will release the resource and set the status of IO to be SAS_TASK_STATE_DONE, so when IO timeout, it will never complete the completion of IO and wait for ever.
[ 729.123632] Call trace: [ 729.126791] [<ffff00000808655c>] __switch_to+0x94/0xa8 [ 729.133106] [<ffff000008d96e98>] __schedule+0x1e8/0x7fc [ 729.138975] [<ffff000008d974e0>] schedule+0x34/0x8c [ 729.144401] [<ffff000008d9b000>] schedule_timeout+0x1d8/0x3cc [ 729.150690] [<ffff000008d98218>] wait_for_common+0xdc/0x1a0 [ 729.157101] [<ffff000008d98304>] wait_for_completion+0x28/0x34 [ 729.165973] [<ffff000000dcefb4>] hisi_sas_internal_task_abort+0x2a0/0x424 [hisi_sas_test_main] [ 729.176447] [<ffff000000dd18f4>] hisi_sas_abort_task+0x244/0x2d8 [hisi_sas_test_main] [ 729.185258] [<ffff000008971714>] sas_eh_handle_sas_errors+0x1c8/0x7b8 [ 729.192391] [<ffff000008972774>] sas_scsi_recover_host+0x130/0x398 [ 729.199237] [<ffff00000894d8a8>] scsi_error_handler+0x148/0x5c0 [ 729.206009] [<ffff0000080f4118>] kthread+0x10c/0x138 [ 729.211563] [<ffff0000080855dc>] ret_from_fork+0x10/0x18
To solve the issue, callback function task_done of those IOs need to be called when on SAS controller reset.
Signed-off-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index c25f3a9b0b9f..fd9d82c9033d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -810,7 +810,8 @@ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task spin_lock_irqsave(&task->task_state_lock, flags); task->task_state_flags &= ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); - task->task_state_flags |= SAS_TASK_STATE_DONE; + if (!slot->is_internal && task->task_proto != SAS_PROTOCOL_SMP) + task->task_state_flags |= SAS_TASK_STATE_DONE; spin_unlock_irqrestore(&task->task_state_lock, flags); }
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit e0f0ae838a25464179d37f355d763f9ec139fc15 ]
The pm8xxx_get_channel() implementation is unclear, and causes gcc to suddenly generate odd warnings. The trigger for the warning (at least for me) was the entirely unrelated commit 79a4e91d1bb2 ("device.h: Add __cold to dev_<level> logging functions"), which apparently changes gcc code generation in the caller function enough to cause this:
drivers/iio/adc/qcom-pm8xxx-xoadc.c: In function ‘pm8xxx_xoadc_probe’: drivers/iio/adc/qcom-pm8xxx-xoadc.c:633:8: warning: ‘ch’ may be used uninitialized in this function [-Wmaybe-uninitialized] ret = pm8xxx_read_channel_rsv(adc, ch, AMUX_RSV4, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &read_nomux_rsv4, true); ~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/adc/qcom-pm8xxx-xoadc.c:426:27: note: ‘ch’ was declared here struct pm8xxx_chan_info *ch; ^~
because gcc for some reason then isn't able to see that the termination condition for the "for( )" loop in that function is also the condition for returning NULL.
So it's not _actually_ uninitialized, but the function is admittedly just unnecessarily oddly written.
Simplify and clarify the function, making gcc also see that it always returns a valid initialized value.
Cc: Joe Perches joe@perches.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Andy Gross andy.gross@linaro.org Cc: David Brown david.brown@linaro.org Cc: Jonathan Cameron jic23@kernel.org Cc: Hartmut Knaack knaack.h@gmx.de Cc: Lars-Peter Clausen lars@metafoo.de Cc: Peter Meerwald-Stadler pmeerw@pmeerw.net Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/qcom-pm8xxx-xoadc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/adc/qcom-pm8xxx-xoadc.c b/drivers/iio/adc/qcom-pm8xxx-xoadc.c index b093ecddf1a8..54db848f0bcd 100644 --- a/drivers/iio/adc/qcom-pm8xxx-xoadc.c +++ b/drivers/iio/adc/qcom-pm8xxx-xoadc.c @@ -423,18 +423,14 @@ static irqreturn_t pm8xxx_eoc_irq(int irq, void *d) static struct pm8xxx_chan_info * pm8xxx_get_channel(struct pm8xxx_xoadc *adc, u8 chan) { - struct pm8xxx_chan_info *ch; int i;
for (i = 0; i < adc->nchans; i++) { - ch = &adc->chans[i]; + struct pm8xxx_chan_info *ch = &adc->chans[i]; if (ch->hwchan->amux_channel == chan) - break; + return ch; } - if (i == adc->nchans) - return NULL; - - return ch; + return NULL; }
static int pm8xxx_read_channel_rsv(struct pm8xxx_xoadc *adc,
From: Kairui Song kasong@redhat.com
[ Upstream commit 179fb36abb097976997f50733d5b122a29158cba ]
After commit 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments"), kexec fails with a kernel panic:
kexec_core: Starting new kernel BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v3.0 03/02/2018 RIP: 0010:0xffffc9000001d000
Call Trace: ? __send_ipi_mask+0x1c6/0x2d0 ? hv_send_ipi_mask_allbutself+0x6d/0xb0 ? mp_save_irq+0x70/0x70 ? __ioapic_read_entry+0x32/0x50 ? ioapic_read_entry+0x39/0x50 ? clear_IO_APIC_pin+0xb8/0x110 ? native_stop_other_cpus+0x6e/0x170 ? native_machine_shutdown+0x22/0x40 ? kernel_kexec+0x136/0x156
That happens if hypercall based IPIs are used because the hypercall page is reset very early upon kexec reboot, but kexec sends IPIs to stop CPUs, which invokes the hypercall and dereferences the unusable page.
To fix his, reset hv_hypercall_pg to NULL before the page is reset to avoid any misuse, IPI sending will fall back to the non hypercall based method. This only happens on kexec / kdump so just setting the pointer to NULL is good enough.
Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments") Signed-off-by: Kairui Song kasong@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: "K. Y. Srinivasan" kys@microsoft.com Cc: Haiyang Zhang haiyangz@microsoft.com Cc: Stephen Hemminger sthemmin@microsoft.com Cc: Sasha Levin sashal@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: "H. Peter Anvin" hpa@zytor.com Cc: Vitaly Kuznetsov vkuznets@redhat.com Cc: Dave Young dyoung@redhat.com Cc: devel@linuxdriverproject.org Link: https://lkml.kernel.org/r/20190306111827.14131-1-kasong@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/hyperv/hv_init.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 20c876c7c5bf..87abd5145cc9 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -387,6 +387,13 @@ void hyperv_cleanup(void) /* Reset our OS id */ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+ /* + * Reset hypercall page reference before reset the page, + * let hypercall operations fail safely rather than + * panic the kernel for using invalid hypercall page + */ + hv_hypercall_pg = NULL; + /* Reset the hypercall page */ hypercall_msr.as_uint64 = 0; wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
From: Jiri Olsa jolsa@redhat.com
[ Upstream commit e34c940245437f36d2c492edd1f8237eff391064 ]
Ravi Bangoria reported that we fail with an empty NUMA node with the following message:
$ lscpu NUMA node0 CPU(s): NUMA node1 CPU(s): 0-4
$ sudo ./perf c2c report node/cpu topology bugFailed setup nodes
Fix this by detecting the empty node and keeping its CPU set empty.
Reported-by: Nageswara R Sastry nasastry@in.ibm.com Signed-off-by: Jiri Olsa jolsa@kernel.org Tested-by: Ravi Bangoria ravi.bangoria@linux.ibm.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Jonas Rabenstein jonas.rabenstein@studium.uni-erlangen.de Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: http://lkml.kernel.org/r/20190305152536.21035-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-c2c.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index f3aa9d02a5ab..763c2edf52e7 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2055,6 +2055,12 @@ static int setup_nodes(struct perf_session *session) if (!set) return -ENOMEM;
+ nodes[node] = set; + + /* empty node, skip */ + if (cpu_map__empty(map)) + continue; + for (cpu = 0; cpu < map->nr; cpu++) { set_bit(map->map[cpu], set);
@@ -2063,8 +2069,6 @@ static int setup_nodes(struct perf_session *session)
cpu2node[map->map[cpu]] = node; } - - nodes[node] = set; }
setup_nodes_header();
From: Qian Cai cai@lca.pw
[ Upstream commit d778015ac95bc036af73342c878ab19250e01fe1 ]
next_present_section_nr() could only return an unsigned number -1, so just check it specifically where compilers will convert -1 to unsigned if needed.
mm/sparse.c: In function 'sparse_init_nid': mm/sparse.c:200:20: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits] ((section_nr >= 0) && \ ^~ mm/sparse.c:478:2: note: in expansion of macro 'for_each_present_section_nr' for_each_present_section_nr(pnum_begin, pnum) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~ mm/sparse.c:200:20: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits] ((section_nr >= 0) && \ ^~ mm/sparse.c:497:2: note: in expansion of macro 'for_each_present_section_nr' for_each_present_section_nr(pnum_begin, pnum) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~ mm/sparse.c: In function 'sparse_init': mm/sparse.c:200:20: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits] ((section_nr >= 0) && \ ^~ mm/sparse.c:520:2: note: in expansion of macro 'for_each_present_section_nr' for_each_present_section_nr(pnum_begin + 1, pnum_end) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~
Link: http://lkml.kernel.org/r/20190228181839.86504-1-cai@lca.pw Fixes: c4e1be9ec113 ("mm, sparsemem: break out of loops early") Signed-off-by: Qian Cai cai@lca.pw Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Dave Hansen dave.hansen@linux.intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/sparse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/sparse.c b/mm/sparse.c index 10b07eea9a6e..45950a074bdb 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -196,7 +196,7 @@ static inline int next_present_section_nr(int section_nr) } #define for_each_present_section_nr(start, section_nr) \ for (section_nr = next_present_section_nr(start-1); \ - ((section_nr >= 0) && \ + ((section_nr != -1) && \ (section_nr <= __highest_present_section_nr)); \ section_nr = next_present_section_nr(section_nr))
From: Peng Fan peng.fan@nxp.com
[ Upstream commit 0d3bd18a5efd66097ef58622b898d3139790aa9d ]
In case cma_init_reserved_mem failed, need to free the memblock allocated by memblock_reserve or memblock_alloc_range.
Quote Catalin's comments: https://lkml.org/lkml/2019/2/26/482
Kmemleak is supposed to work with the memblock_{alloc,free} pair and it ignores the memblock_reserve() as a memblock_alloc() implementation detail. It is, however, tolerant to memblock_free() being called on a sub-range or just a different range from a previous memblock_alloc(). So the original patch looks fine to me. FWIW:
Link: http://lkml.kernel.org/r/20190227144631.16708-1-peng.fan@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Reviewed-by: Catalin Marinas catalin.marinas@arm.com Reviewed-by: Mike Rapoport rppt@linux.ibm.com Cc: Laura Abbott labbott@redhat.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: Michal Hocko mhocko@suse.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Marek Szyprowski m.szyprowski@samsung.com Cc: Andrey Konovalov andreyknvl@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/cma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/cma.c b/mm/cma.c index 4cb76121a3ab..bfe9f5397165 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -353,12 +353,14 @@ int __init cma_declare_contiguous(phys_addr_t base,
ret = cma_init_reserved_mem(base, size, order_per_bit, name, res_cma); if (ret) - goto err; + goto free_mem;
pr_info("Reserved %ld MiB at %pa\n", (unsigned long)size / SZ_1M, &base); return 0;
+free_mem: + memblock_free(base, size); err: pr_err("Failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); return ret;
From: Qian Cai cai@lca.pw
[ Upstream commit 0c81585499601acd1d0e1cbf424cabfaee60628c ]
After offlining a memory block, kmemleak scan will trigger a crash, as it encounters a page ext address that has already been freed during memory offlining. At the beginning in alloc_page_ext(), it calls kmemleak_alloc(), but it does not call kmemleak_free() in free_page_ext().
BUG: unable to handle kernel paging request at ffff888453d00000 PGD 128a01067 P4D 128a01067 PUD 128a04067 PMD 47e09e067 PTE 800ffffbac2ff060 Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI CPU: 1 PID: 1594 Comm: bash Not tainted 5.0.0-rc8+ #15 Hardware name: HP ProLiant DL180 Gen9/ProLiant DL180 Gen9, BIOS U20 10/25/2017 RIP: 0010:scan_block+0xb5/0x290 Code: 85 6e 01 00 00 48 b8 00 00 30 f5 81 88 ff ff 48 39 c3 0f 84 5b 01 00 00 48 89 d8 48 c1 e8 03 42 80 3c 20 00 0f 85 87 01 00 00 <4c> 8b 3b e8 f3 0c fa ff 4c 39 3d 0c 6b 4c 01 0f 87 08 01 00 00 4c RSP: 0018:ffff8881ec57f8e0 EFLAGS: 00010082 RAX: 0000000000000000 RBX: ffff888453d00000 RCX: ffffffffa61e5a54 RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff888453d00000 RBP: ffff8881ec57f920 R08: fffffbfff4ed588d R09: fffffbfff4ed588c R10: fffffbfff4ed588c R11: ffffffffa76ac463 R12: dffffc0000000000 R13: ffff888453d00ff9 R14: ffff8881f80cef48 R15: ffff8881f80cef48 FS: 00007f6c0e3f8740(0000) GS:ffff8881f7680000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff888453d00000 CR3: 00000001c4244003 CR4: 00000000001606a0 Call Trace: scan_gray_list+0x269/0x430 kmemleak_scan+0x5a8/0x10f0 kmemleak_write+0x541/0x6ca full_proxy_write+0xf8/0x190 __vfs_write+0xeb/0x980 vfs_write+0x15a/0x4f0 ksys_write+0xd2/0x1b0 __x64_sys_write+0x73/0xb0 do_syscall_64+0xeb/0xaaa entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f6c0dad73b8 Code: 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 63 2d 00 8b 00 85 c0 75 17 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 49 89 d4 55 RSP: 002b:00007ffd5b863cb8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007f6c0dad73b8 RDX: 0000000000000005 RSI: 000055a9216e1710 RDI: 0000000000000001 RBP: 000055a9216e1710 R08: 000000000000000a R09: 00007ffd5b863840 R10: 000000000000000a R11: 0000000000000246 R12: 00007f6c0dda9780 R13: 0000000000000005 R14: 00007f6c0dda4740 R15: 0000000000000005 Modules linked in: nls_iso8859_1 nls_cp437 vfat fat kvm_intel kvm irqbypass efivars ip_tables x_tables xfs sd_mod ahci libahci igb i2c_algo_bit libata i2c_core dm_mirror dm_region_hash dm_log dm_mod efivarfs CR2: ffff888453d00000 ---[ end trace ccf646c7456717c5 ]--- Kernel panic - not syncing: Fatal exception Shutting down cpus with NMI Kernel Offset: 0x24c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) ---[ end Kernel panic - not syncing: Fatal exception ]---
Link: http://lkml.kernel.org/r/20190227173147.75650-1-cai@lca.pw Signed-off-by: Qian Cai cai@lca.pw Reviewed-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/page_ext.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/mm/page_ext.c b/mm/page_ext.c index 4961f13b6ec1..aad120123688 100644 --- a/mm/page_ext.c +++ b/mm/page_ext.c @@ -273,6 +273,7 @@ static void free_page_ext(void *addr) table_size = get_entry_size() * PAGES_PER_SECTION;
BUG_ON(PageReserved(page)); + kmemleak_free(addr); free_pages_exact(addr, table_size); } }
From: Daniel Jordan daniel.m.jordan@oracle.com
[ Upstream commit c10d38cc8d3e43f946b6c2bf4602c86791587f30 ]
Dan Carpenter reports a potential NULL dereference in get_swap_page_of_type:
Smatch complains that the NULL checks on "si" aren't consistent. This seems like a real bug because we have not ensured that the type is valid and so "si" can be NULL.
Add the missing check for NULL, taking care to use a read barrier to ensure CPU1 observes CPU0's updates in the correct order:
CPU0 CPU1 alloc_swap_info() if (type >= nr_swapfiles) swap_info[type] = p /* handle invalid entry */ smp_wmb() smp_rmb() ++nr_swapfiles p = swap_info[type]
Without smp_rmb, CPU1 might observe CPU0's write to nr_swapfiles before CPU0's write to swap_info[type] and read NULL from swap_info[type].
Ying Huang noticed other places in swapfile.c don't order these reads properly. Introduce swap_type_to_swap_info to encourage correct usage.
Use READ_ONCE and WRITE_ONCE to follow the Linux Kernel Memory Model (see tools/memory-model/Documentation/explanation.txt).
This ordering need not be enforced in places where swap_lock is held (e.g. si_swapinfo) because swap_lock serializes updates to nr_swapfiles and the swap_info array.
Link: http://lkml.kernel.org/r/20190131024410.29859-1-daniel.m.jordan@oracle.com Fixes: ec8acf20afb8 ("swap: add per-partition lock for swapfile") Signed-off-by: Daniel Jordan daniel.m.jordan@oracle.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Suggested-by: "Huang, Ying" ying.huang@intel.com Reviewed-by: Andrea Parri andrea.parri@amarulasolutions.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Alan Stern stern@rowland.harvard.edu Cc: Andi Kleen ak@linux.intel.com Cc: Dave Hansen dave.hansen@linux.intel.com Cc: Omar Sandoval osandov@fb.com Cc: Paul McKenney paulmck@linux.vnet.ibm.com Cc: Shaohua Li shli@kernel.org Cc: Stephen Rothwell sfr@canb.auug.org.au Cc: Tejun Heo tj@kernel.org Cc: Will Deacon will.deacon@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/swapfile.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/mm/swapfile.c b/mm/swapfile.c index 340ef3177686..0047dcaf9369 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -98,6 +98,15 @@ static atomic_t proc_poll_event = ATOMIC_INIT(0);
atomic_t nr_rotate_swap = ATOMIC_INIT(0);
+static struct swap_info_struct *swap_type_to_swap_info(int type) +{ + if (type >= READ_ONCE(nr_swapfiles)) + return NULL; + + smp_rmb(); /* Pairs with smp_wmb in alloc_swap_info. */ + return READ_ONCE(swap_info[type]); +} + static inline unsigned char swap_count(unsigned char ent) { return ent & ~SWAP_HAS_CACHE; /* may include COUNT_CONTINUED flag */ @@ -1030,12 +1039,14 @@ int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_size) /* The only caller of this function is now suspend routine */ swp_entry_t get_swap_page_of_type(int type) { - struct swap_info_struct *si; + struct swap_info_struct *si = swap_type_to_swap_info(type); pgoff_t offset;
- si = swap_info[type]; + if (!si) + goto fail; + spin_lock(&si->lock); - if (si && (si->flags & SWP_WRITEOK)) { + if (si->flags & SWP_WRITEOK) { atomic_long_dec(&nr_swap_pages); /* This is called for allocating swap entry, not cache */ offset = scan_swap_map(si, 1); @@ -1046,6 +1057,7 @@ swp_entry_t get_swap_page_of_type(int type) atomic_long_inc(&nr_swap_pages); } spin_unlock(&si->lock); +fail: return (swp_entry_t) {0}; }
@@ -1057,9 +1069,9 @@ static struct swap_info_struct *__swap_info_get(swp_entry_t entry) if (!entry.val) goto out; type = swp_type(entry); - if (type >= nr_swapfiles) + p = swap_type_to_swap_info(type); + if (!p) goto bad_nofile; - p = swap_info[type]; if (!(p->flags & SWP_USED)) goto bad_device; offset = swp_offset(entry); @@ -1708,10 +1720,9 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) sector_t swapdev_block(int type, pgoff_t offset) { struct block_device *bdev; + struct swap_info_struct *si = swap_type_to_swap_info(type);
- if ((unsigned int)type >= nr_swapfiles) - return 0; - if (!(swap_info[type]->flags & SWP_WRITEOK)) + if (!si || !(si->flags & SWP_WRITEOK)) return 0; return map_swap_entry(swp_entry(type, offset), &bdev); } @@ -2269,7 +2280,7 @@ static sector_t map_swap_entry(swp_entry_t entry, struct block_device **bdev) struct swap_extent *se; pgoff_t offset;
- sis = swap_info[swp_type(entry)]; + sis = swp_swap_info(entry); *bdev = sis->bdev;
offset = swp_offset(entry); @@ -2707,9 +2718,7 @@ static void *swap_start(struct seq_file *swap, loff_t *pos) if (!l) return SEQ_START_TOKEN;
- for (type = 0; type < nr_swapfiles; type++) { - smp_rmb(); /* read nr_swapfiles before swap_info[type] */ - si = swap_info[type]; + for (type = 0; (si = swap_type_to_swap_info(type)); type++) { if (!(si->flags & SWP_USED) || !si->swap_map) continue; if (!--l) @@ -2729,9 +2738,7 @@ static void *swap_next(struct seq_file *swap, void *v, loff_t *pos) else type = si->type + 1;
- for (; type < nr_swapfiles; type++) { - smp_rmb(); /* read nr_swapfiles before swap_info[type] */ - si = swap_info[type]; + for (; (si = swap_type_to_swap_info(type)); type++) { if (!(si->flags & SWP_USED) || !si->swap_map) continue; ++*pos; @@ -2838,14 +2845,14 @@ static struct swap_info_struct *alloc_swap_info(void) } if (type >= nr_swapfiles) { p->type = type; - swap_info[type] = p; + WRITE_ONCE(swap_info[type], p); /* * Write swap_info[type] before nr_swapfiles, in case a * racing procfs swap_start() or swap_next() is reading them. * (We never shrink nr_swapfiles, we never free this entry.) */ smp_wmb(); - nr_swapfiles++; + WRITE_ONCE(nr_swapfiles, nr_swapfiles + 1); } else { kvfree(p); p = swap_info[type]; @@ -3365,7 +3372,7 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage) { struct swap_info_struct *p; struct swap_cluster_info *ci; - unsigned long offset, type; + unsigned long offset; unsigned char count; unsigned char has_cache; int err = -EINVAL; @@ -3373,10 +3380,10 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage) if (non_swap_entry(entry)) goto out;
- type = swp_type(entry); - if (type >= nr_swapfiles) + p = swp_swap_info(entry); + if (!p) goto bad_file; - p = swap_info[type]; + offset = swp_offset(entry); if (unlikely(offset >= p->max)) goto out; @@ -3473,7 +3480,7 @@ int swapcache_prepare(swp_entry_t entry)
struct swap_info_struct *swp_swap_info(swp_entry_t entry) { - return swap_info[swp_type(entry)]; + return swap_type_to_swap_info(swp_type(entry)); }
struct swap_info_struct *page_swap_info(struct page *page)
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit d342a0b38674867ea67fde47b0e1e60ffe9f17a2 ]
Since setting global init process to some memory cgroup is technically possible, oom_kill_memcg_member() must check it.
Tasks in /test1 are going to be killed due to memory.oom.group set Memory cgroup out of memory: Killed process 1 (systemd) total-vm:43400kB, anon-rss:1228kB, file-rss:3992kB, shmem-rss:0kB oom_reaper: reaped process 1 (systemd), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000008b
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
int main(int argc, char *argv[]) { static char buffer[10485760]; static int pipe_fd[2] = { EOF, EOF }; unsigned int i; int fd; char buf[64] = { }; if (pipe(pipe_fd)) return 1; if (chdir("/sys/fs/cgroup/")) return 1; fd = open("cgroup.subtree_control", O_WRONLY); write(fd, "+memory", 7); close(fd); mkdir("test1", 0755); fd = open("test1/memory.oom.group", O_WRONLY); write(fd, "1", 1); close(fd); fd = open("test1/cgroup.procs", O_WRONLY); write(fd, "1", 1); snprintf(buf, sizeof(buf) - 1, "%d", getpid()); write(fd, buf, strlen(buf)); close(fd); snprintf(buf, sizeof(buf) - 1, "%lu", sizeof(buffer) * 5); fd = open("test1/memory.max", O_WRONLY); write(fd, buf, strlen(buf)); close(fd); for (i = 0; i < 10; i++) if (fork() == 0) { char c; close(pipe_fd[1]); read(pipe_fd[0], &c, 1); memset(buffer, 0, sizeof(buffer)); sleep(3); _exit(0); } close(pipe_fd[0]); close(pipe_fd[1]); sleep(3); return 0; }
[ 37.052923][ T9185] a.out invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=0 [ 37.056169][ T9185] CPU: 4 PID: 9185 Comm: a.out Kdump: loaded Not tainted 5.0.0-rc4-next-20190131 #280 [ 37.059205][ T9185] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018 [ 37.062954][ T9185] Call Trace: [ 37.063976][ T9185] dump_stack+0x67/0x95 [ 37.065263][ T9185] dump_header+0x51/0x570 [ 37.066619][ T9185] ? trace_hardirqs_on+0x3f/0x110 [ 37.068171][ T9185] ? _raw_spin_unlock_irqrestore+0x3d/0x70 [ 37.069967][ T9185] oom_kill_process+0x18d/0x210 [ 37.071515][ T9185] out_of_memory+0x11b/0x380 [ 37.072936][ T9185] mem_cgroup_out_of_memory+0xb6/0xd0 [ 37.074601][ T9185] try_charge+0x790/0x820 [ 37.076021][ T9185] mem_cgroup_try_charge+0x42/0x1d0 [ 37.077629][ T9185] mem_cgroup_try_charge_delay+0x11/0x30 [ 37.079370][ T9185] do_anonymous_page+0x105/0x5e0 [ 37.080939][ T9185] __handle_mm_fault+0x9cb/0x1070 [ 37.082485][ T9185] handle_mm_fault+0x1b2/0x3a0 [ 37.083819][ T9185] ? handle_mm_fault+0x47/0x3a0 [ 37.085181][ T9185] __do_page_fault+0x255/0x4c0 [ 37.086529][ T9185] do_page_fault+0x28/0x260 [ 37.087788][ T9185] ? page_fault+0x8/0x30 [ 37.088978][ T9185] page_fault+0x1e/0x30 [ 37.090142][ T9185] RIP: 0033:0x7f8b183aefe0 [ 37.091433][ T9185] Code: 20 f3 44 0f 7f 44 17 d0 f3 44 0f 7f 47 30 f3 44 0f 7f 44 17 c0 48 01 fa 48 83 e2 c0 48 39 d1 74 a3 66 0f 1f 84 00 00 00 00 00 <66> 44 0f 7f 01 66 44 0f 7f 41 10 66 44 0f 7f 41 20 66 44 0f 7f 41 [ 37.096917][ T9185] RSP: 002b:00007fffc5d329e8 EFLAGS: 00010206 [ 37.098615][ T9185] RAX: 00000000006010e0 RBX: 0000000000000008 RCX: 0000000000c30000 [ 37.100905][ T9185] RDX: 00000000010010c0 RSI: 0000000000000000 RDI: 00000000006010e0 [ 37.103349][ T9185] RBP: 0000000000000000 R08: 00007f8b188f4740 R09: 0000000000000000 [ 37.105797][ T9185] R10: 00007fffc5d32420 R11: 00007f8b183aef40 R12: 0000000000000005 [ 37.108228][ T9185] R13: 0000000000000000 R14: ffffffffffffffff R15: 0000000000000000 [ 37.110840][ T9185] memory: usage 51200kB, limit 51200kB, failcnt 125 [ 37.113045][ T9185] memory+swap: usage 0kB, limit 9007199254740988kB, failcnt 0 [ 37.115808][ T9185] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0 [ 37.117660][ T9185] Memory cgroup stats for /test1: cache:0KB rss:49484KB rss_huge:30720KB shmem:0KB mapped_file:0KB dirty:0KB writeback:0KB inactive_anon:0KB active_anon:49700KB inactive_file:0KB active_file:0KB unevictable:0KB [ 37.123371][ T9185] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,oom_memcg=/test1,task_memcg=/test1,task=a.out,pid=9188,uid=0 [ 37.128158][ T9185] Memory cgroup out of memory: Killed process 9188 (a.out) total-vm:14456kB, anon-rss:10324kB, file-rss:504kB, shmem-rss:0kB [ 37.132710][ T9185] Tasks in /test1 are going to be killed due to memory.oom.group set [ 37.132833][ T54] oom_reaper: reaped process 9188 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.135498][ T9185] Memory cgroup out of memory: Killed process 1 (systemd) total-vm:43400kB, anon-rss:1228kB, file-rss:3992kB, shmem-rss:0kB [ 37.143434][ T9185] Memory cgroup out of memory: Killed process 9182 (a.out) total-vm:14456kB, anon-rss:76kB, file-rss:588kB, shmem-rss:0kB [ 37.144328][ T54] oom_reaper: reaped process 1 (systemd), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.147585][ T9185] Memory cgroup out of memory: Killed process 9183 (a.out) total-vm:14456kB, anon-rss:6228kB, file-rss:512kB, shmem-rss:0kB [ 37.157222][ T9185] Memory cgroup out of memory: Killed process 9184 (a.out) total-vm:14456kB, anon-rss:6228kB, file-rss:508kB, shmem-rss:0kB [ 37.157259][ T9185] Memory cgroup out of memory: Killed process 9185 (a.out) total-vm:14456kB, anon-rss:6228kB, file-rss:512kB, shmem-rss:0kB [ 37.157291][ T9185] Memory cgroup out of memory: Killed process 9186 (a.out) total-vm:14456kB, anon-rss:4180kB, file-rss:508kB, shmem-rss:0kB [ 37.157306][ T54] oom_reaper: reaped process 9183 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.157328][ T9185] Memory cgroup out of memory: Killed process 9187 (a.out) total-vm:14456kB, anon-rss:4180kB, file-rss:512kB, shmem-rss:0kB [ 37.157452][ T9185] Memory cgroup out of memory: Killed process 9189 (a.out) total-vm:14456kB, anon-rss:6228kB, file-rss:512kB, shmem-rss:0kB [ 37.158733][ T9185] Memory cgroup out of memory: Killed process 9190 (a.out) total-vm:14456kB, anon-rss:552kB, file-rss:512kB, shmem-rss:0kB [ 37.160083][ T54] oom_reaper: reaped process 9186 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.160187][ T54] oom_reaper: reaped process 9189 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.206941][ T54] oom_reaper: reaped process 9185 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.212300][ T9185] Memory cgroup out of memory: Killed process 9191 (a.out) total-vm:14456kB, anon-rss:4180kB, file-rss:512kB, shmem-rss:0kB [ 37.212317][ T54] oom_reaper: reaped process 9190 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.218860][ T9185] Memory cgroup out of memory: Killed process 9192 (a.out) total-vm:14456kB, anon-rss:1080kB, file-rss:512kB, shmem-rss:0kB [ 37.227667][ T54] oom_reaper: reaped process 9192 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB [ 37.292323][ T9193] abrt-hook-ccpp (9193) used greatest stack depth: 10480 bytes left [ 37.351843][ T1] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000008b [ 37.354833][ T1] CPU: 7 PID: 1 Comm: systemd Kdump: loaded Not tainted 5.0.0-rc4-next-20190131 #280 [ 37.357876][ T1] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018 [ 37.361685][ T1] Call Trace: [ 37.363239][ T1] dump_stack+0x67/0x95 [ 37.365010][ T1] panic+0xfc/0x2b0 [ 37.366853][ T1] do_exit+0xd55/0xd60 [ 37.368595][ T1] do_group_exit+0x47/0xc0 [ 37.370415][ T1] get_signal+0x32a/0x920 [ 37.372449][ T1] ? _raw_spin_unlock_irqrestore+0x3d/0x70 [ 37.374596][ T1] do_signal+0x32/0x6e0 [ 37.376430][ T1] ? exit_to_usermode_loop+0x26/0x9b [ 37.378418][ T1] ? prepare_exit_to_usermode+0xa8/0xd0 [ 37.380571][ T1] exit_to_usermode_loop+0x3e/0x9b [ 37.382588][ T1] prepare_exit_to_usermode+0xa8/0xd0 [ 37.384594][ T1] ? page_fault+0x8/0x30 [ 37.386453][ T1] retint_user+0x8/0x18 [ 37.388160][ T1] RIP: 0033:0x7f42c06974a8 [ 37.389922][ T1] Code: Bad RIP value. [ 37.391788][ T1] RSP: 002b:00007ffc3effd388 EFLAGS: 00010213 [ 37.394075][ T1] RAX: 000000000000000e RBX: 00007ffc3effd390 RCX: 0000000000000000 [ 37.396963][ T1] RDX: 000000000000002a RSI: 00007ffc3effd390 RDI: 0000000000000004 [ 37.399550][ T1] RBP: 00007ffc3effd680 R08: 0000000000000000 R09: 0000000000000000 [ 37.402334][ T1] R10: 00000000ffffffff R11: 0000000000000246 R12: 0000000000000001 [ 37.404890][ T1] R13: ffffffffffffffff R14: 0000000000000884 R15: 000056460b1ac3b0
Link: http://lkml.kernel.org/r/201902010336.x113a4EO027170@www262.sakura.ne.jp Fixes: 3d8b38eb81cac813 ("mm, oom: introduce memory.oom.group") Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Acked-by: Michal Hocko mhocko@suse.com Cc: Roman Gushchin guro@fb.com Cc: Johannes Weiner hannes@cmpxchg.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/oom_kill.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index e66ac8a47dd6..dbddb7a409dd 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -915,7 +915,8 @@ static void __oom_kill_process(struct task_struct *victim) */ static int oom_kill_memcg_member(struct task_struct *task, void *unused) { - if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) { + if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN && + !is_global_init(task)) { get_task_struct(task); __oom_kill_process(task); }
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 7775face207922ea62a4e96b9cd45abfdc7b9840 ]
If a memory cgroup contains a single process with many threads (including different process group sharing the mm) then it is possible to trigger a race when the oom killer complains that there are no oom elible tasks and complain into the log which is both annoying and confusing because there is no actual problem. The race looks as follows:
P1 oom_reaper P2 try_charge try_charge mem_cgroup_out_of_memory mutex_lock(oom_lock) out_of_memory oom_kill_process(P1,P2) wake_oom_reaper mutex_unlock(oom_lock) oom_reap_task mutex_lock(oom_lock) select_bad_process # no victim
The problem is more visible with many threads.
Fix this by checking for fatal_signal_pending from mem_cgroup_out_of_memory when the oom_lock is already held.
The oom bypass is safe because we do the same early in the try_charge path already. The situation migh have changed in the mean time. It should be safe to check for fatal_signal_pending and tsk_is_oom_victim but for a better code readability abstract the current charge bypass condition into should_force_charge and reuse it from that path. "
Link: http://lkml.kernel.org/r/01370f70-e1f6-ebe4-b95e-0df21a0bc15e@i-love.sakura.... Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Acked-by: Michal Hocko mhocko@suse.com Acked-by: Johannes Weiner hannes@cmpxchg.org Cc: David Rientjes rientjes@google.com Cc: Kirill Tkhai ktkhai@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/memcontrol.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9518aefd8cbb..7c712c4565e6 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -248,6 +248,12 @@ enum res_type { iter != NULL; \ iter = mem_cgroup_iter(NULL, iter, NULL))
+static inline bool should_force_charge(void) +{ + return tsk_is_oom_victim(current) || fatal_signal_pending(current) || + (current->flags & PF_EXITING); +} + /* Some nice accessors for the vmpressure. */ struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg) { @@ -1382,8 +1388,13 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, }; bool ret;
- mutex_lock(&oom_lock); - ret = out_of_memory(&oc); + if (mutex_lock_killable(&oom_lock)) + return true; + /* + * A few threads which were not waiting at mutex_lock_killable() can + * fail to bail out. Therefore, check again after holding oom_lock. + */ + ret = should_force_charge() || out_of_memory(&oc); mutex_unlock(&oom_lock); return ret; } @@ -2200,9 +2211,7 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, * bypass the last charges so that they can exit quickly and * free their memory. */ - if (unlikely(tsk_is_oom_victim(current) || - fatal_signal_pending(current) || - current->flags & PF_EXITING)) + if (unlikely(should_force_charge())) goto force;
/*
From: Vlastimil Babka vbabka@suse.cz
[ Upstream commit 2e25644e8da4ed3a27e7b8315aaae74660be72dc ]
Syzbot with KMSAN reports (excerpt):
================================================================== BUG: KMSAN: uninit-value in mpol_rebind_policy mm/mempolicy.c:353 [inline] BUG: KMSAN: uninit-value in mpol_rebind_mm+0x249/0x370 mm/mempolicy.c:384 CPU: 1 PID: 17420 Comm: syz-executor4 Not tainted 4.20.0-rc7+ #15 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x173/0x1d0 lib/dump_stack.c:113 kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613 __msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:295 mpol_rebind_policy mm/mempolicy.c:353 [inline] mpol_rebind_mm+0x249/0x370 mm/mempolicy.c:384 update_tasks_nodemask+0x608/0xca0 kernel/cgroup/cpuset.c:1120 update_nodemasks_hier kernel/cgroup/cpuset.c:1185 [inline] update_nodemask kernel/cgroup/cpuset.c:1253 [inline] cpuset_write_resmask+0x2a98/0x34b0 kernel/cgroup/cpuset.c:1728
...
Uninit was created at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:204 [inline] kmsan_internal_poison_shadow+0x92/0x150 mm/kmsan/kmsan.c:158 kmsan_kmalloc+0xa6/0x130 mm/kmsan/kmsan_hooks.c:176 kmem_cache_alloc+0x572/0xb90 mm/slub.c:2777 mpol_new mm/mempolicy.c:276 [inline] do_mbind mm/mempolicy.c:1180 [inline] kernel_mbind+0x8a7/0x31a0 mm/mempolicy.c:1347 __do_sys_mbind mm/mempolicy.c:1354 [inline]
As it's difficult to report where exactly the uninit value resides in the mempolicy object, we have to guess a bit. mm/mempolicy.c:353 contains this part of mpol_rebind_policy():
if (!mpol_store_user_nodemask(pol) && nodes_equal(pol->w.cpuset_mems_allowed, *newmask))
"mpol_store_user_nodemask(pol)" is testing pol->flags, which I couldn't ever see being uninitialized after leaving mpol_new(). So I'll guess it's actually about accessing pol->w.cpuset_mems_allowed on line 354, but still part of statement starting on line 353.
For w.cpuset_mems_allowed to be not initialized, and the nodes_equal() reachable for a mempolicy where mpol_set_nodemask() is called in do_mbind(), it seems the only possibility is a MPOL_PREFERRED policy with empty set of nodes, i.e. MPOL_LOCAL equivalent, with MPOL_F_LOCAL flag. Let's exclude such policies from the nodes_equal() check. Note the uninit access should be benign anyway, as rebinding this kind of policy is always a no-op. Therefore no actual need for stable inclusion.
Link: http://lkml.kernel.org/r/a71997c3-e8ae-a787-d5ce-3db05768b27c@suse.cz Link: http://lkml.kernel.org/r/73da3e9c-cc84-509e-17d9-0c434bb9967d@suse.cz Signed-off-by: Vlastimil Babka vbabka@suse.cz Reported-by: syzbot+b19c2dc2c990ea657a71@syzkaller.appspotmail.com Cc: Alexander Potapenko glider@google.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Andrea Arcangeli aarcange@redhat.com Cc: "Kirill A. Shutemov" kirill.shutemov@linux.intel.com Cc: Michal Hocko mhocko@suse.com Cc: David Rientjes rientjes@google.com Cc: Yisheng Xie xieyisheng1@huawei.com Cc: zhong jiang zhongjiang@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/mempolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 89d4439516f6..c716ba52fb9e 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -350,7 +350,7 @@ static void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask) { if (!pol) return; - if (!mpol_store_user_nodemask(pol) && + if (!mpol_store_user_nodemask(pol) && !(pol->flags & MPOL_F_LOCAL) && nodes_equal(pol->w.cpuset_mems_allowed, *newmask)) return;
From: "Uladzislau Rezki (Sony)" urezki@gmail.com
[ Upstream commit afd07389d3f4933c7f7817a92fb5e053d59a3182 ]
One of the vmalloc stress test case triggers the kernel BUG():
<snip> [60.562151] ------------[ cut here ]------------ [60.562154] kernel BUG at mm/vmalloc.c:512! [60.562206] invalid opcode: 0000 [#1] PREEMPT SMP PTI [60.562247] CPU: 0 PID: 430 Comm: vmalloc_test/0 Not tainted 4.20.0+ #161 [60.562293] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [60.562351] RIP: 0010:alloc_vmap_area+0x36f/0x390 <snip>
it can happen due to big align request resulting in overflowing of calculated address, i.e. it becomes 0 after ALIGN()'s fixup.
Fix it by checking if calculated address is within vstart/vend range.
Link: http://lkml.kernel.org/r/20190124115648.9433-2-urezki@gmail.com Signed-off-by: Uladzislau Rezki (Sony) urezki@gmail.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Ingo Molnar mingo@elte.hu Cc: Joel Fernandes joelaf@google.com Cc: Matthew Wilcox willy@infradead.org Cc: Michal Hocko mhocko@suse.com Cc: Oleksiy Avramchenko oleksiy.avramchenko@sonymobile.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Tejun Heo tj@kernel.org Cc: Thomas Garnier thgarnie@google.com Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/vmalloc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 91a789a46b12..a46ec261a44e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -498,7 +498,11 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, }
found: - if (addr + size > vend) + /* + * Check also calculated address against the vstart, + * because it can be 0 because of big align request. + */ + if (addr + size > vend || addr < vstart) goto overflow;
va->va_start = addr;
From: Qian Cai cai@lca.pw
[ Upstream commit 92d1d07daad65c300c7d0b68bbef8867e9895d54 ]
Kmemleak throws endless warnings during boot due to in __alloc_alien_cache(),
alc = kmalloc_node(memsize, gfp, node); init_arraycache(&alc->ac, entries, batch); kmemleak_no_scan(ac);
Kmemleak does not track the array cache (alc->ac) but the alien cache (alc) instead, so let it track the latter by lifting kmemleak_no_scan() out of init_arraycache().
There is another place that calls init_arraycache(), but alloc_kmem_cache_cpus() uses the percpu allocation where will never be considered as a leak.
kmemleak: Found object by alias at 0xffff8007b9aa7e38 CPU: 190 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc2+ #2 Call trace: dump_backtrace+0x0/0x168 show_stack+0x24/0x30 dump_stack+0x88/0xb0 lookup_object+0x84/0xac find_and_get_object+0x84/0xe4 kmemleak_no_scan+0x74/0xf4 setup_kmem_cache_node+0x2b4/0x35c __do_tune_cpucache+0x250/0x2d4 do_tune_cpucache+0x4c/0xe4 enable_cpucache+0xc8/0x110 setup_cpu_cache+0x40/0x1b8 __kmem_cache_create+0x240/0x358 create_cache+0xc0/0x198 kmem_cache_create_usercopy+0x158/0x20c kmem_cache_create+0x50/0x64 fsnotify_init+0x58/0x6c do_one_initcall+0x194/0x388 kernel_init_freeable+0x668/0x688 kernel_init+0x18/0x124 ret_from_fork+0x10/0x18 kmemleak: Object 0xffff8007b9aa7e00 (size 256): kmemleak: comm "swapper/0", pid 1, jiffies 4294697137 kmemleak: min_count = 1 kmemleak: count = 0 kmemleak: flags = 0x1 kmemleak: checksum = 0 kmemleak: backtrace: kmemleak_alloc+0x84/0xb8 kmem_cache_alloc_node_trace+0x31c/0x3a0 __kmalloc_node+0x58/0x78 setup_kmem_cache_node+0x26c/0x35c __do_tune_cpucache+0x250/0x2d4 do_tune_cpucache+0x4c/0xe4 enable_cpucache+0xc8/0x110 setup_cpu_cache+0x40/0x1b8 __kmem_cache_create+0x240/0x358 create_cache+0xc0/0x198 kmem_cache_create_usercopy+0x158/0x20c kmem_cache_create+0x50/0x64 fsnotify_init+0x58/0x6c do_one_initcall+0x194/0x388 kernel_init_freeable+0x668/0x688 kernel_init+0x18/0x124 kmemleak: Not scanning unknown object at 0xffff8007b9aa7e38 CPU: 190 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc2+ #2 Call trace: dump_backtrace+0x0/0x168 show_stack+0x24/0x30 dump_stack+0x88/0xb0 kmemleak_no_scan+0x90/0xf4 setup_kmem_cache_node+0x2b4/0x35c __do_tune_cpucache+0x250/0x2d4 do_tune_cpucache+0x4c/0xe4 enable_cpucache+0xc8/0x110 setup_cpu_cache+0x40/0x1b8 __kmem_cache_create+0x240/0x358 create_cache+0xc0/0x198 kmem_cache_create_usercopy+0x158/0x20c kmem_cache_create+0x50/0x64 fsnotify_init+0x58/0x6c do_one_initcall+0x194/0x388 kernel_init_freeable+0x668/0x688 kernel_init+0x18/0x124 ret_from_fork+0x10/0x18
Link: http://lkml.kernel.org/r/20190129184518.39808-1-cai@lca.pw Fixes: 1fe00d50a9e8 ("slab: factor out initialization of array cache") Signed-off-by: Qian Cai cai@lca.pw Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Christoph Lameter cl@linux.com Cc: Pekka Enberg penberg@kernel.org Cc: David Rientjes rientjes@google.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/slab.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/mm/slab.c b/mm/slab.c index fad6839e8eab..49007b825683 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -563,14 +563,6 @@ static void start_cpu_timer(int cpu)
static void init_arraycache(struct array_cache *ac, int limit, int batch) { - /* - * The array_cache structures contain pointers to free object. - * However, when such objects are allocated or transferred to another - * cache the pointers are not cleared and they could be counted as - * valid references during a kmemleak scan. Therefore, kmemleak must - * not scan such objects. - */ - kmemleak_no_scan(ac); if (ac) { ac->avail = 0; ac->limit = limit; @@ -586,6 +578,14 @@ static struct array_cache *alloc_arraycache(int node, int entries, struct array_cache *ac = NULL;
ac = kmalloc_node(memsize, gfp, node); + /* + * The array_cache structures contain pointers to free object. + * However, when such objects are allocated or transferred to another + * cache the pointers are not cleared and they could be counted as + * valid references during a kmemleak scan. Therefore, kmemleak must + * not scan such objects. + */ + kmemleak_no_scan(ac); init_arraycache(ac, entries, batchcount); return ac; } @@ -680,6 +680,7 @@ static struct alien_cache *__alloc_alien_cache(int node, int entries,
alc = kmalloc_node(memsize, gfp, node); if (alc) { + kmemleak_no_scan(alc); init_arraycache(&alc->ac, entries, batch); spin_lock_init(&alc->lock); }
From: Jia Guo guojia12@huawei.com
[ Upstream commit cc725ef3cb202ef2019a3c67c8913efa05c3cce6 ]
In the process of creating a node, it will cause NULL pointer dereference in kernel if o2cb_ctl failed in the interval (mkdir, o2cb_set_node_attribute(node_num)] in function o2cb_add_node.
The node num is initialized to 0 in function o2nm_node_group_make_item, o2nm_node_group_drop_item will mistake the node number 0 for a valid node number when we delete the node before the node number is set correctly. If the local node number of the current host happens to be 0, cluster->cl_local_node will be set to O2NM_INVALID_NODE_NUM while o2hb_thread still running. The panic stack is generated as follows:
o2hb_thread -o2hb_do_disk_heartbeat -o2hb_check_own_slot |-slot = ®->hr_slots[o2nm_this_node()]; //o2nm_this_node() return O2NM_INVALID_NODE_NUM
We need to check whether the node number is set when we delete the node.
Link: http://lkml.kernel.org/r/133d8045-72cc-863e-8eae-5013f9f6bc51@huawei.com Signed-off-by: Jia Guo guojia12@huawei.com Reviewed-by: Joseph Qi jiangqi903@gmail.com Acked-by: Jun Piao piaojun@huawei.com Cc: Mark Fasheh mark@fasheh.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Changwei Ge ge.changwei@h3c.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ocfs2/cluster/nodemanager.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 0e4166cc23a0..4ac775e32240 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -621,13 +621,15 @@ static void o2nm_node_group_drop_item(struct config_group *group, struct o2nm_node *node = to_o2nm_node(item); struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent);
- o2net_disconnect_node(node); + if (cluster->cl_nodes[node->nd_num] == node) { + o2net_disconnect_node(node);
- if (cluster->cl_has_local && - (cluster->cl_local_node == node->nd_num)) { - cluster->cl_has_local = 0; - cluster->cl_local_node = O2NM_INVALID_NODE_NUM; - o2net_stop_listening(node); + if (cluster->cl_has_local && + (cluster->cl_local_node == node->nd_num)) { + cluster->cl_has_local = 0; + cluster->cl_local_node = O2NM_INVALID_NODE_NUM; + o2net_stop_listening(node); + } }
/* XXX call into net to stop this node from trading messages */
From: Sahitya Tummala stummala@codeaurora.org
[ Upstream commit 9083977dabf3833298ddcd40dee28687f1e6b483 ]
Fix below warning coming because of using mutex lock in atomic context.
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:98 in_atomic(): 1, irqs_disabled(): 0, pid: 585, name: sh Preemption disabled at: __radix_tree_preload+0x28/0x130 Call trace: dump_backtrace+0x0/0x2b4 show_stack+0x20/0x28 dump_stack+0xa8/0xe0 ___might_sleep+0x144/0x194 __might_sleep+0x58/0x8c mutex_lock+0x2c/0x48 f2fs_trace_pid+0x88/0x14c f2fs_set_node_page_dirty+0xd0/0x184
Do not use f2fs_radix_tree_insert() to avoid doing cond_resched() with spin_lock() acquired.
Signed-off-by: Sahitya Tummala stummala@codeaurora.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/trace.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/fs/f2fs/trace.c b/fs/f2fs/trace.c index a1fcd00bbb2b..8ac1851a21c0 100644 --- a/fs/f2fs/trace.c +++ b/fs/f2fs/trace.c @@ -17,7 +17,7 @@ #include "trace.h"
static RADIX_TREE(pids, GFP_ATOMIC); -static struct mutex pids_lock; +static spinlock_t pids_lock; static struct last_io_info last_io;
static inline void __print_last_io(void) @@ -61,23 +61,29 @@ void f2fs_trace_pid(struct page *page)
set_page_private(page, (unsigned long)pid);
+retry: if (radix_tree_preload(GFP_NOFS)) return;
- mutex_lock(&pids_lock); + spin_lock(&pids_lock); p = radix_tree_lookup(&pids, pid); if (p == current) goto out; if (p) radix_tree_delete(&pids, pid);
- f2fs_radix_tree_insert(&pids, pid, current); + if (radix_tree_insert(&pids, pid, current)) { + spin_unlock(&pids_lock); + radix_tree_preload_end(); + cond_resched(); + goto retry; + }
trace_printk("%3x:%3x %4x %-16s\n", MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), pid, current->comm); out: - mutex_unlock(&pids_lock); + spin_unlock(&pids_lock); radix_tree_preload_end(); }
@@ -122,7 +128,7 @@ void f2fs_trace_ios(struct f2fs_io_info *fio, int flush)
void f2fs_build_trace_ios(void) { - mutex_init(&pids_lock); + spin_lock_init(&pids_lock); }
#define PIDVEC_SIZE 128 @@ -150,7 +156,7 @@ void f2fs_destroy_trace_ios(void) pid_t next_pid = 0; unsigned int found;
- mutex_lock(&pids_lock); + spin_lock(&pids_lock); while ((found = gang_lookup_pids(pid, next_pid, PIDVEC_SIZE))) { unsigned idx;
@@ -158,5 +164,5 @@ void f2fs_destroy_trace_ios(void) for (idx = 0; idx < found; idx++) radix_tree_delete(&pids, pid[idx]); } - mutex_unlock(&pids_lock); + spin_unlock(&pids_lock); }
From: zhengliang zhengliang6@huawei.com
[ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ]
v4: Rearrange the previous three versions.
The following scenario could lead to data block override by mistake.
TASK A | TASK kworker | TASK B | TASK C | | | open | | | write | | | close | | | | f2fs_write_data_pages | | | f2fs_write_cache_pages | | | f2fs_outplace_write_data | | | f2fs_allocate_data_block (get block in seg S, | | | S is full, and only | | | have this valid data | | | block) | | | allocate_segment | | | locate_dirty_segment (mark S as PRE) | | | f2fs_submit_page_write (submit but is not | | | written on dev) | | unlink | | | iput_final | | | f2fs_drop_inode | | | f2fs_truncate | | | (not evict) | | | | | write_checkpoint | | | flush merged bio but not wait file data writeback | | | set_prefree_as_free (mark S as FREE) | | | | update NODE/DATA | | | allocate_segment (select S) | writeback done | |
So we need to guarantee io complete before truncate inode in f2fs_drop_inode.
Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Zheng Liang zhengliang6@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c9639ef0e8d5..7c9de4a7b794 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -897,6 +897,10 @@ static int f2fs_drop_inode(struct inode *inode) sb_start_intwrite(inode->i_sb); f2fs_i_size_write(inode, 0);
+ f2fs_submit_merged_write_cond(F2FS_I_SB(inode), + inode, NULL, 0, DATA); + truncate_inode_pages_final(inode->i_mapping); + if (F2FS_HAS_BLOCKS(inode)) f2fs_truncate(inode);
From: Shuriyc Chu sureeju@gmail.com
[ Upstream commit 5704a06810682683355624923547b41540e2801a ]
(Taken from https://bugzilla.kernel.org/show_bug.cgi?id=200647)
'get_unused_fd_flags' in kthread cause kernel crash. It works fine on 4.1, but causes crash after get 64 fds. It also cause crash on ubuntu1404/1604/1804, centos7.5, and the crash messages are almost the same.
The crash message on centos7.5 shows below:
start fd 61 start fd 62 start fd 63 BUG: unable to handle kernel NULL pointer dereference at (null) IP: __wake_up_common+0x2e/0x90 PGD 0 Oops: 0000 [#1] SMP Modules linked in: test(OE) xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter devlink sunrpc kvm_intel kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd sg ppdev pcspkr virtio_balloon parport_pc parport i2c_piix4 joydev ip_tables xfs libcrc32c sr_mod cdrom sd_mod crc_t10dif crct10dif_generic ata_generic pata_acpi virtio_scsi virtio_console virtio_net cirrus drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm crct10dif_pclmul crct10dif_common crc32c_intel drm ata_piix serio_raw libata virtio_pci virtio_ring i2c_core virtio floppy dm_mirror dm_region_hash dm_log dm_mod CPU: 2 PID: 1820 Comm: test_fd Kdump: loaded Tainted: G OE ------------ 3.10.0-862.3.3.el7.x86_64 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.2-0-g5f4c7b1-prebuilt.qemu-project.org 04/01/2014 task: ffff8e92b9431fa0 ti: ffff8e94247a0000 task.ti: ffff8e94247a0000 RIP: 0010:__wake_up_common+0x2e/0x90 RSP: 0018:ffff8e94247a2d18 EFLAGS: 00010086 RAX: 0000000000000000 RBX: ffffffff9d09daa0 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffffffff9d09daa0 RBP: ffff8e94247a2d50 R08: 0000000000000000 R09: ffff8e92b95dfda8 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff9d09daa8 R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000003 FS: 0000000000000000(0000) GS:ffff8e9434e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000017c686000 CR4: 00000000000207e0 Call Trace: __wake_up+0x39/0x50 expand_files+0x131/0x250 __alloc_fd+0x47/0x170 get_unused_fd_flags+0x30/0x40 test_fd+0x12a/0x1c0 [test] kthread+0xd1/0xe0 ret_from_fork_nospec_begin+0x21/0x21 Code: 66 90 55 48 89 e5 41 57 41 89 f7 41 56 41 89 ce 41 55 41 54 49 89 fc 49 83 c4 08 53 48 83 ec 10 48 8b 47 08 89 55 cc 4c 89 45 d0 <48> 8b 08 49 39 c4 48 8d 78 e8 4c 8d 69 e8 75 08 eb 3b 4c 89 ef RIP __wake_up_common+0x2e/0x90 RSP <ffff8e94247a2d18> CR2: 0000000000000000
This issue exists since CentOS 7.5 3.10.0-862 and CentOS 7.4 (3.10.0-693.21.1 ) is ok. Root cause: the item 'resize_wait' is not initialized before being used.
Reported-by: Richard Zhang zhang.zijian@h3c.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/file.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/file.c b/fs/file.c index 7ffd6e9d103d..780d29e58847 100644 --- a/fs/file.c +++ b/fs/file.c @@ -457,6 +457,7 @@ struct files_struct init_files = { .full_fds_bits = init_files.full_fds_bits_init, }, .file_lock = __SPIN_LOCK_UNLOCKED(init_files.file_lock), + .resize_wait = __WAIT_QUEUE_HEAD_INITIALIZER(init_files.resize_wait), };
static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
From: Qian Cai cai@lca.pw
[ Upstream commit 4117992df66a26fa33908b4969e04801534baab1 ]
KASAN does not play well with the page poisoning (CONFIG_PAGE_POISONING). It triggers false positives in the allocation path:
BUG: KASAN: use-after-free in memchr_inv+0x2ea/0x330 Read of size 8 at addr ffff88881f800000 by task swapper/0 CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc1+ #54 Call Trace: dump_stack+0xe0/0x19a print_address_description.cold.2+0x9/0x28b kasan_report.cold.3+0x7a/0xb5 __asan_report_load8_noabort+0x19/0x20 memchr_inv+0x2ea/0x330 kernel_poison_pages+0x103/0x3d5 get_page_from_freelist+0x15e7/0x4d90
because KASAN has not yet unpoisoned the shadow page for allocation before it checks memchr_inv() but only found a stale poison pattern.
Also, false positives in free path,
BUG: KASAN: slab-out-of-bounds in kernel_poison_pages+0x29e/0x3d5 Write of size 4096 at addr ffff8888112cc000 by task swapper/0/1 CPU: 5 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc1+ #55 Call Trace: dump_stack+0xe0/0x19a print_address_description.cold.2+0x9/0x28b kasan_report.cold.3+0x7a/0xb5 check_memory_region+0x22d/0x250 memset+0x28/0x40 kernel_poison_pages+0x29e/0x3d5 __free_pages_ok+0x75f/0x13e0
due to KASAN adds poisoned redzones around slab objects, but the page poisoning needs to poison the whole page.
Link: http://lkml.kernel.org/r/20190114233405.67843-1-cai@lca.pw Signed-off-by: Qian Cai cai@lca.pw Acked-by: Andrey Ryabinin aryabinin@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/page_alloc.c | 2 +- mm/page_poison.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ef99971c13dd..8e6932a140b8 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1922,8 +1922,8 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
arch_alloc_page(page, order); kernel_map_pages(page, 1 << order, 1); - kernel_poison_pages(page, 1 << order, 1); kasan_alloc_pages(page, order); + kernel_poison_pages(page, 1 << order, 1); set_page_owner(page, order, gfp_flags); }
diff --git a/mm/page_poison.c b/mm/page_poison.c index aa2b3d34e8ea..6cfa8e7d7213 100644 --- a/mm/page_poison.c +++ b/mm/page_poison.c @@ -6,6 +6,7 @@ #include <linux/page_ext.h> #include <linux/poison.h> #include <linux/ratelimit.h> +#include <linux/kasan.h>
static bool want_page_poisoning __read_mostly;
@@ -34,7 +35,10 @@ static void poison_page(struct page *page) { void *addr = kmap_atomic(page);
+ /* KASAN still think the page is in-use, so skip it. */ + kasan_disable_current(); memset(addr, PAGE_POISON, PAGE_SIZE); + kasan_enable_current(); kunmap_atomic(addr); }
From: Louis Taylor louis@kragniz.eu
[ Upstream commit 259594bea574e515a148171b5cd84ce5cbdc028a ]
When compiling with -Wformat, clang emits the following warnings:
fs/cifs/smb1ops.c:312:20: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] tgt_total_cnt, total_in_tgt); ^~~~~~~~~~~~
fs/cifs/cifs_dfs_ref.c:289:4: warning: format specifies type 'short' but the argument has type 'int' [-Wformat] ref->flags, ref->server_type); ^~~~~~~~~~
fs/cifs/cifs_dfs_ref.c:289:16: warning: format specifies type 'short' but the argument has type 'int' [-Wformat] ref->flags, ref->server_type); ^~~~~~~~~~~~~~~~
fs/cifs/cifs_dfs_ref.c:291:4: warning: format specifies type 'short' but the argument has type 'int' [-Wformat] ref->ref_flag, ref->path_consumed); ^~~~~~~~~~~~~
fs/cifs/cifs_dfs_ref.c:291:19: warning: format specifies type 'short' but the argument has type 'int' [-Wformat] ref->ref_flag, ref->path_consumed); ^~~~~~~~~~~~~~~~~~ The types of these arguments are unconditionally defined, so this patch updates the format character to the correct ones for ints and unsigned ints.
Link: https://github.com/ClangBuiltLinux/linux/issues/378
Signed-off-by: Louis Taylor louis@kragniz.eu Signed-off-by: Steve French stfrench@microsoft.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/cifs_dfs_ref.c | 4 ++-- fs/cifs/smb1ops.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 6b61df117fd4..563e2f6268c3 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -271,9 +271,9 @@ static void dump_referral(const struct dfs_info3_param *ref) { cifs_dbg(FYI, "DFS: ref path: %s\n", ref->path_name); cifs_dbg(FYI, "DFS: node path: %s\n", ref->node_name); - cifs_dbg(FYI, "DFS: fl: %hd, srv_type: %hd\n", + cifs_dbg(FYI, "DFS: fl: %d, srv_type: %d\n", ref->flags, ref->server_type); - cifs_dbg(FYI, "DFS: ref_flags: %hd, path_consumed: %hd\n", + cifs_dbg(FYI, "DFS: ref_flags: %d, path_consumed: %d\n", ref->ref_flag, ref->path_consumed); }
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 378151e09e91..47db8eb6cbcf 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -308,7 +308,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) remaining = tgt_total_cnt - total_in_tgt;
if (remaining < 0) { - cifs_dbg(FYI, "Server sent too much data. tgt_total_cnt=%hu total_in_tgt=%hu\n", + cifs_dbg(FYI, "Server sent too much data. tgt_total_cnt=%hu total_in_tgt=%u\n", tgt_total_cnt, total_in_tgt); return -EPROTO; }
From: "Jason Cai (Xiang Feng)" jason.cai.kern@gmail.com
[ Upstream commit 70de2cbda8a5d788284469e755f8b097d339c240 ]
Invoking dm_get_device() twice on the same device path with different modes is dangerous. Because in that case, upgrade_mode() will alloc a new 'dm_dev' and free the old one, which may be referenced by a previous caller. Dereferencing the dangling pointer will trigger kernel NULL pointer dereference.
The following two cases can reproduce this issue. Actually, they are invalid setups that must be disallowed, e.g.:
1. Creating a thin-pool with read_only mode, and the same device as both metadata and data.
dmsetup create thinp --table \ "0 41943040 thin-pool /dev/vdb /dev/vdb 128 0 1 read_only"
BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 ... Call Trace: new_read+0xfb/0x110 [dm_bufio] dm_bm_read_lock+0x43/0x190 [dm_persistent_data] ? kmem_cache_alloc_trace+0x15c/0x1e0 __create_persistent_data_objects+0x65/0x3e0 [dm_thin_pool] dm_pool_metadata_open+0x8c/0xf0 [dm_thin_pool] pool_ctr.cold.79+0x213/0x913 [dm_thin_pool] ? realloc_argv+0x50/0x70 [dm_mod] dm_table_add_target+0x14e/0x330 [dm_mod] table_load+0x122/0x2e0 [dm_mod] ? dev_status+0x40/0x40 [dm_mod] ctl_ioctl+0x1aa/0x3e0 [dm_mod] dm_ctl_ioctl+0xa/0x10 [dm_mod] do_vfs_ioctl+0xa2/0x600 ? handle_mm_fault+0xda/0x200 ? __do_page_fault+0x26c/0x4f0 ksys_ioctl+0x60/0x90 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x55/0x150 entry_SYSCALL_64_after_hwframe+0x44/0xa9
2. Creating a external snapshot using the same thin-pool device.
dmsetup create thinp --table \ "0 41943040 thin-pool /dev/vdc /dev/vdb 128 0 2 ignore_discard" dmsetup message /dev/mapper/thinp 0 "create_thin 0" dmsetup create snap --table \ "0 204800 thin /dev/mapper/thinp 0 /dev/mapper/thinp"
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 ... Call Trace: ? __alloc_pages_nodemask+0x13c/0x2e0 retrieve_status+0xa5/0x1f0 [dm_mod] ? dm_get_live_or_inactive_table.isra.7+0x20/0x20 [dm_mod] table_status+0x61/0xa0 [dm_mod] ctl_ioctl+0x1aa/0x3e0 [dm_mod] dm_ctl_ioctl+0xa/0x10 [dm_mod] do_vfs_ioctl+0xa2/0x600 ksys_ioctl+0x60/0x90 ? ksys_write+0x4f/0xb0 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x55/0x150 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Signed-off-by: Jason Cai (Xiang Feng) jason.cai@linux.alibaba.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-thin.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index cd4220ee7004..435a2ee4a392 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3283,6 +3283,13 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) as.argc = argc; as.argv = argv;
+ /* make sure metadata and data are different devices */ + if (!strcmp(argv[0], argv[1])) { + ti->error = "Error setting metadata or data device"; + r = -EINVAL; + goto out_unlock; + } + /* * Set default pool features. */ @@ -4167,6 +4174,12 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) tc->sort_bio_list = RB_ROOT;
if (argc == 3) { + if (!strcmp(argv[0], argv[2])) { + ti->error = "Error setting origin device"; + r = -EINVAL; + goto bad_origin_dev; + } + r = dm_get_device(ti, argv[2], FMODE_READ, &origin_dev); if (r) { ti->error = "Error opening origin device";
From: Chao Yu yuchao0@huawei.com
[ Upstream commit 500e0b28ecd3c5aade98f3c3a339d18dcb166bb6 ]
We use below condition to check inline_xattr_size boundary:
if (!F2FS_OPTION(sbi).inline_xattr_size || F2FS_OPTION(sbi).inline_xattr_size >= DEF_ADDRS_PER_INODE - F2FS_TOTAL_EXTRA_ATTR_SIZE - DEF_INLINE_RESERVED_SIZE - DEF_MIN_INLINE_SIZE)
There is there problems in that check: - we should allow inline_xattr_size equaling to min size of inline {data,dentry} area. - F2FS_TOTAL_EXTRA_ATTR_SIZE and inline_xattr_size are based on different size unit, previous one is 4 bytes, latter one is 1 bytes. - DEF_MIN_INLINE_SIZE only indicate min size of inline data area, however, we need to consider min size of inline dentry area as well, minimal inline dentry should at least contain two entries: '.' and '..', so that min inline_dentry size is 40 bytes.
.bitmap 1 * 1 = 1 .reserved 1 * 1 = 1 .dentry 11 * 2 = 22 .filename 8 * 2 = 16 total 40
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 1 - fs/f2fs/super.c | 13 +++++++------ include/linux/f2fs_fs.h | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 42aef5c94927..a3ba20e5946f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -450,7 +450,6 @@ struct f2fs_flush_device {
/* for inline stuff */ #define DEF_INLINE_RESERVED_SIZE 1 -#define DEF_MIN_INLINE_SIZE 1 static inline int get_extra_isize(struct inode *inode); static inline int get_inline_xattr_addrs(struct inode *inode); #define MAX_INLINE_DATA(inode) (sizeof(__le32) * \ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 7c9de4a7b794..d9b0e183fa50 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -822,12 +822,13 @@ static int parse_options(struct super_block *sb, char *options) "set with inline_xattr option"); return -EINVAL; } - if (!F2FS_OPTION(sbi).inline_xattr_size || - F2FS_OPTION(sbi).inline_xattr_size >= - DEF_ADDRS_PER_INODE - - F2FS_TOTAL_EXTRA_ATTR_SIZE - - DEF_INLINE_RESERVED_SIZE - - DEF_MIN_INLINE_SIZE) { + if (F2FS_OPTION(sbi).inline_xattr_size < + sizeof(struct f2fs_xattr_header) / sizeof(__le32) || + F2FS_OPTION(sbi).inline_xattr_size > + DEF_ADDRS_PER_INODE - + F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - + DEF_INLINE_RESERVED_SIZE - + MIN_INLINE_DENTRY_SIZE / sizeof(__le32)) { f2fs_msg(sb, KERN_ERR, "inline xattr size is out of range"); return -EINVAL; diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index f70f8ac9c4f4..40fec5f94949 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -489,12 +489,12 @@ typedef __le32 f2fs_hash_t;
/* * space utilization of regular dentry and inline dentry (w/o extra reservation) - * regular dentry inline dentry - * bitmap 1 * 27 = 27 1 * 23 = 23 - * reserved 1 * 3 = 3 1 * 7 = 7 - * dentry 11 * 214 = 2354 11 * 182 = 2002 - * filename 8 * 214 = 1712 8 * 182 = 1456 - * total 4096 3488 + * regular dentry inline dentry (def) inline dentry (min) + * bitmap 1 * 27 = 27 1 * 23 = 23 1 * 1 = 1 + * reserved 1 * 3 = 3 1 * 7 = 7 1 * 1 = 1 + * dentry 11 * 214 = 2354 11 * 182 = 2002 11 * 2 = 22 + * filename 8 * 214 = 1712 8 * 182 = 1456 8 * 2 = 16 + * total 4096 3488 40 * * Note: there are more reserved space in inline dentry than in regular * dentry, when converting inline dentry we should handle this carefully. @@ -506,6 +506,7 @@ typedef __le32 f2fs_hash_t; #define SIZE_OF_RESERVED (PAGE_SIZE - ((SIZE_OF_DIR_ENTRY + \ F2FS_SLOT_LEN) * \ NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) +#define MIN_INLINE_DENTRY_SIZE 40 /* just include '.' and '..' entries */
/* One directory entry slot representing F2FS_SLOT_LEN-sized file name */ struct f2fs_dir_entry {
From: Namjae Jeon linkinjeon@gmail.com
[ Upstream commit 969ae8e8d4ee54c99134d3895f2adf96047f5bee ]
Old windows version or Netapp SMB server will return NT_STATUS_NOT_SUPPORTED since they do not allow or implement FSCTL_VALIDATE_NEGOTIATE_INFO. The client should accept the response provided it's properly signed.
See https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-di...
and
MS-SMB2 validate negotiate response processing: https://msdn.microsoft.com/en-us/library/hh880630.aspx
Samba client had already handled it. https://bugzilla.samba.org/attachment.cgi?id=13285&action=edit
Signed-off-by: Namjae Jeon linkinjeon@gmail.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/smb2pdu.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a2d701775c49..073dd1ad1fe1 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -881,8 +881,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen); - - if (rc != 0) { + if (rc == -EOPNOTSUPP) { + /* + * Old Windows versions or Netapp SMB server can return + * not supported error. Client should accept it. + */ + cifs_dbg(VFS, "Server does not support validate negotiate\n"); + return 0; + } else if (rc != 0) { cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); rc = -EIO; goto out_free_inbuf;
From: Yao Liu yotta.liu@ucloud.cn
[ Upstream commit 68e2672f8fbd1e04982b8d2798dd318bf2515dd2 ]
There is a NULL pointer dereference of devname in strspn()
The oops looks something like:
CIFS: Attempting to mount (null) BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 ... RIP: 0010:strspn+0x0/0x50 ... Call Trace: ? cifs_parse_mount_options+0x222/0x1710 [cifs] ? cifs_get_volume_info+0x2f/0x80 [cifs] cifs_setup_volume_info+0x20/0x190 [cifs] cifs_get_volume_info+0x50/0x80 [cifs] cifs_smb3_do_mount+0x59/0x630 [cifs] ? ida_alloc_range+0x34b/0x3d0 cifs_do_mount+0x11/0x20 [cifs] mount_fs+0x52/0x170 vfs_kern_mount+0x6b/0x170 do_mount+0x216/0xdc0 ksys_mount+0x83/0xd0 __x64_sys_mount+0x25/0x30 do_syscall_64+0x65/0x220 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fix this by adding a NULL check on devname in cifs_parse_devname()
Signed-off-by: Yao Liu yotta.liu@ucloud.cn Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/connect.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a5ea742654aa..f31339db45fd 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1347,6 +1347,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol) const char *delims = "/\"; size_t len;
+ if (unlikely(!devname || !*devname)) { + cifs_dbg(VFS, "Device name not specified.\n"); + return -EINVAL; + } + /* make sure we have a valid UNC double delimiter prefix */ len = strspn(devname, delims); if (len != 2)
From: Slavomir Kaslev kaslevs@vmware.com
[ Upstream commit ee5e001196d1345b8fee25925ff5f1d67936081e ]
The current implementation of splice() and tee() ignores O_NONBLOCK set on pipe file descriptors and checks only the SPLICE_F_NONBLOCK flag for blocking on pipe arguments. This is inconsistent since splice()-ing from/to non-pipe file descriptors does take O_NONBLOCK into consideration.
Fix this by promoting O_NONBLOCK, when set on a pipe, to SPLICE_F_NONBLOCK.
Some context for how the current implementation of splice() leads to inconsistent behavior. In the ongoing work[1] to add VM tracing capability to trace-cmd we stream tracing data over named FIFOs or vsockets from guests back to the host.
When we receive SIGINT from user to stop tracing, we set O_NONBLOCK on the input file descriptor and set SPLICE_F_NONBLOCK for the next call to splice(). If splice() was blocked waiting on data from the input FIFO, after SIGINT splice() restarts with the same arguments (no SPLICE_F_NONBLOCK) and blocks again instead of returning -EAGAIN when no data is available.
This differs from the splice() behavior when reading from a vsocket or when we're doing a traditional read()/write() loop (trace-cmd's --nosplice argument).
With this patch applied we get the same behavior in all situations after setting O_NONBLOCK which also matches the behavior of doing a read()/write() loop instead of splice().
This change does have potential of breaking users who don't expect EAGAIN from splice() when SPLICE_F_NONBLOCK is not set. OTOH programs that set O_NONBLOCK and don't anticipate EAGAIN are arguably buggy[2].
[1] https://github.com/skaslev/trace-cmd/tree/vsock [2] https://github.com/torvalds/linux/blob/d47e3da1759230e394096fd742aad423c291b...
Signed-off-by: Slavomir Kaslev kaslevs@vmware.com Reviewed-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/splice.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/fs/splice.c b/fs/splice.c index 29e92b506394..7769181aa1a6 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1119,6 +1119,9 @@ static long do_splice(struct file *in, loff_t __user *off_in, if (ipipe == opipe) return -EINVAL;
+ if ((in->f_flags | out->f_flags) & O_NONBLOCK) + flags |= SPLICE_F_NONBLOCK; + return splice_pipe_to_pipe(ipipe, opipe, len, flags); }
@@ -1144,6 +1147,9 @@ static long do_splice(struct file *in, loff_t __user *off_in, if (unlikely(ret < 0)) return ret;
+ if (in->f_flags & O_NONBLOCK) + flags |= SPLICE_F_NONBLOCK; + file_start_write(out); ret = do_splice_from(ipipe, out, &offset, len, flags); file_end_write(out); @@ -1168,6 +1174,9 @@ static long do_splice(struct file *in, loff_t __user *off_in, offset = in->f_pos; }
+ if (out->f_flags & O_NONBLOCK) + flags |= SPLICE_F_NONBLOCK; + pipe_lock(opipe); ret = wait_for_space(opipe, flags); if (!ret) @@ -1717,6 +1726,9 @@ static long do_tee(struct file *in, struct file *out, size_t len, * copying the data. */ if (ipipe && opipe && ipipe != opipe) { + if ((in->f_flags | out->f_flags) & O_NONBLOCK) + flags |= SPLICE_F_NONBLOCK; + /* * Keep going, unless we encounter an error. The ipipe/opipe * ordering doesn't really matter.
From: Li RongQing lirongqing@baidu.com
[ Upstream commit a9f5e78c403d2d62ade4f4c85040efc85f4049b8 ]
Check the result of dereferencing base_chain->stats, instead of result of this_cpu_ptr with NULL.
base_chain->stats maybe be changed to NULL when a chain is updated and a new NULL counter can be attached.
And we do not need to check returning of this_cpu_ptr since base_chain->stats is from percpu allocator if it is non-NULL, this_cpu_ptr returns a valid value.
And fix two sparse error by replacing rcu_access_pointer and rcu_dereference with READ_ONCE under rcu_read_lock.
Thanks for Eric's help to finish this patch.
Fixes: 009240940e84c1 ("netfilter: nf_tables: don't assume chain stats are set when jumplabel is set") Signed-off-by: Eric Dumazet eric.dumazet@gmail.com Signed-off-by: Zhang Yu zhangyu31@baidu.com Signed-off-by: Li RongQing lirongqing@baidu.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_tables_core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 60f258f2c707..a3850414dba2 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -98,21 +98,23 @@ static noinline void nft_update_chain_stats(const struct nft_chain *chain, const struct nft_pktinfo *pkt) { struct nft_base_chain *base_chain; + struct nft_stats __percpu *pstats; struct nft_stats *stats;
base_chain = nft_base_chain(chain); - if (!rcu_access_pointer(base_chain->stats)) - return;
- local_bh_disable(); - stats = this_cpu_ptr(rcu_dereference(base_chain->stats)); - if (stats) { + rcu_read_lock(); + pstats = READ_ONCE(base_chain->stats); + if (pstats) { + local_bh_disable(); + stats = this_cpu_ptr(pstats); u64_stats_update_begin(&stats->syncp); stats->pkts++; stats->bytes += pkt->skb->len; u64_stats_update_end(&stats->syncp); + local_bh_enable(); } - local_bh_enable(); + rcu_read_unlock(); }
struct nft_jumpstack {
From: Florian Westphal fw@strlen.de
[ Upstream commit be0502a3f2e94211a8809a09ecbc3a017189b8fb ]
TCP resets cause instant transition from established to closed state provided the reset is in-window. Endpoints that implement RFC 5961 require resets to match the next expected sequence number. RST segments that are in-window (but that do not match RCV.NXT) are ignored, and a "challenge ACK" is sent back.
Main problem for conntrack is that its a middlebox, i.e. whereas an end host might have ACK'd SEQ (and would thus accept an RST with this sequence number), conntrack might not have seen this ACK (yet).
Therefore we can't simply flag RSTs with non-exact match as invalid.
This updates RST processing as follows:
1. If the connection is in a state other than ESTABLISHED, nothing is changed, RST is subject to normal in-window check.
2. If the RSTs sequence number either matches exactly RCV.NXT, connection state moves to CLOSE.
3. The same applies if the RST sequence number aligns with a previous packet in the same direction.
In all other cases, the connection remains in ESTABLISHED state. If the normal-in-window check passes, the timeout will be lowered to that of CLOSE.
If the peer sends a challenge ack, connection timeout will be reset.
If the challenge ACK triggers another RST (RST was valid after all), this 2nd RST will match expected sequence and conntrack state changes to CLOSE.
If no challenge ACK is received, the connection will time out after CLOSE seconds (10 seconds by default), just like without this patch.
Packetdrill test case:
0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 0.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 0.000 bind(3, ..., ...) = 0 0.000 listen(3, 1) = 0
0.100 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7> 0.100 > S. 0:0(0) ack 1 win 64240 <mss 1460,nop,nop,sackOK,nop,wscale 7> 0.200 < . 1:1(0) ack 1 win 257 0.200 accept(3, ..., ...) = 4
// Receive a segment. 0.210 < P. 1:1001(1000) ack 1 win 46 0.210 > . 1:1(0) ack 1001
// Application writes 1000 bytes. 0.250 write(4, ..., 1000) = 1000 0.250 > P. 1:1001(1000) ack 1001
// First reset, old sequence. Conntrack (correctly) considers this // invalid due to failed window validation (regardless of this patch). 0.260 < R 2:2(0) ack 1001 win 260
// 2nd reset, but too far ahead sequence. Same: correctly handled // as invalid. 0.270 < R 99990001:99990001(0) ack 1001 win 260
// in-window, but not exact sequence. // Current Linux kernels might reply with a challenge ack, and do not // remove connection. // Without this patch, conntrack state moves to CLOSE. // With patch, timeout is lowered like CLOSE, but connection stays // in ESTABLISHED state. 0.280 < R 1010:1010(0) ack 1001 win 260
// Expect challenge ACK 0.281 > . 1001:1001(0) ack 1001 win 501
// With or without this patch, RST will cause connection // to move to CLOSE (sequence number matches) // 0.282 < R 1001:1001(0) ack 1001 win 260
// ACK 0.300 < . 1001:1001(0) ack 1001 win 257
// more data could be exchanged here, connection // is still established
// Client closes the connection. 0.610 < F. 1001:1001(0) ack 1001 win 260 0.650 > . 1001:1001(0) ack 1002
// Close the connection without reading outstanding data 0.700 close(4) = 0
// so one more reset. Will be deemed acceptable with patch as well: // connection is already closing. 0.701 > R. 1001:1001(0) ack 1002 win 501 // End packetdrill test case.
With patch, this generates following conntrack events: [NEW] 120 SYN_SENT src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [UNREPLIED] [UPDATE] 60 SYN_RECV src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [UPDATE] 432000 ESTABLISHED src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [ASSURED] [UPDATE] 120 FIN_WAIT src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [ASSURED] [UPDATE] 60 CLOSE_WAIT src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [ASSURED] [UPDATE] 10 CLOSE src=10.0.2.1 dst=10.0.0.1 sport=5437 dport=80 [ASSURED]
Without patch, first RST moves connection to close, whereas socket state does not change until FIN is received. [NEW] 120 SYN_SENT src=10.0.2.1 dst=10.0.0.1 sport=5141 dport=80 [UNREPLIED] [UPDATE] 60 SYN_RECV src=10.0.2.1 dst=10.0.0.1 sport=5141 dport=80 [UPDATE] 432000 ESTABLISHED src=10.0.2.1 dst=10.0.0.1 sport=5141 dport=80 [ASSURED] [UPDATE] 10 CLOSE src=10.0.2.1 dst=10.0.0.1 sport=5141 dport=80 [ASSURED]
Cc: Jozsef Kadlecsik kadlec@blackhole.kfki.hu Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_proto_tcp.c | 50 ++++++++++++++++++++------ 1 file changed, 40 insertions(+), 10 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 247b89784a6f..842f3f86fb2e 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -769,6 +769,12 @@ static int tcp_error(struct net *net, struct nf_conn *tmpl, return NF_ACCEPT; }
+static bool nf_conntrack_tcp_established(const struct nf_conn *ct) +{ + return ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED && + test_bit(IPS_ASSURED_BIT, &ct->status); +} + /* Returns verdict for packet, or -1 for invalid. */ static int tcp_packet(struct nf_conn *ct, const struct sk_buff *skb, @@ -963,16 +969,38 @@ static int tcp_packet(struct nf_conn *ct, new_state = TCP_CONNTRACK_ESTABLISHED; break; case TCP_CONNTRACK_CLOSE: - if (index == TCP_RST_SET - && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) - && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) { - /* Invalid RST */ - spin_unlock_bh(&ct->lock); - nf_ct_l4proto_log_invalid(skb, ct, "invalid rst"); - return -NF_ACCEPT; + if (index != TCP_RST_SET) + break; + + if (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) { + u32 seq = ntohl(th->seq); + + if (before(seq, ct->proto.tcp.seen[!dir].td_maxack)) { + /* Invalid RST */ + spin_unlock_bh(&ct->lock); + nf_ct_l4proto_log_invalid(skb, ct, "invalid rst"); + return -NF_ACCEPT; + } + + if (!nf_conntrack_tcp_established(ct) || + seq == ct->proto.tcp.seen[!dir].td_maxack) + break; + + /* Check if rst is part of train, such as + * foo:80 > bar:4379: P, 235946583:235946602(19) ack 42 + * foo:80 > bar:4379: R, 235946602:235946602(0) ack 42 + */ + if (ct->proto.tcp.last_index == TCP_ACK_SET && + ct->proto.tcp.last_dir == dir && + seq == ct->proto.tcp.last_end) + break; + + /* ... RST sequence number doesn't match exactly, keep + * established state to allow a possible challenge ACK. + */ + new_state = old_state; } - if (index == TCP_RST_SET - && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status) + if (((test_bit(IPS_SEEN_REPLY_BIT, &ct->status) && ct->proto.tcp.last_index == TCP_SYN_SET) || (!test_bit(IPS_ASSURED_BIT, &ct->status) && ct->proto.tcp.last_index == TCP_ACK_SET)) @@ -988,7 +1016,7 @@ static int tcp_packet(struct nf_conn *ct, * segments we ignored. */ goto in_window; } - /* Just fall through */ + break; default: /* Keep compilers happy. */ break; @@ -1023,6 +1051,8 @@ static int tcp_packet(struct nf_conn *ct, if (ct->proto.tcp.retrans >= tn->tcp_max_retrans && timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) timeout = timeouts[TCP_CONNTRACK_RETRANS]; + else if (unlikely(index == TCP_RST_SET)) + timeout = timeouts[TCP_CONNTRACK_CLOSE]; else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) & IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
From: luojiajun luojiajun3@huawei.com
[ Upstream commit 6e876c3dd205d30b0db6850e97a03d75457df007 ]
In jbd2_journal_commit_transaction(), if we are in abort mode, we may flush the buffer without setting descriptor block checksum by goto start_journal_io. Then fs is mounted, jbd2_descriptor_block_csum_verify() failed.
[ 271.379811] EXT4-fs (vdd): shut down requested (2) [ 271.381827] Aborting journal on device vdd-8. [ 271.597136] JBD2: Invalid checksum recovering block 22199 in log [ 271.598023] JBD2: recovery failed [ 271.598484] EXT4-fs (vdd): error loading journal
Fix this problem by keep setting descriptor block checksum if the descriptor buffer is not NULL.
This checksum problem can be reproduced by xfstests generic/388.
Signed-off-by: luojiajun luojiajun3@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jbd2/commit.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 150cc030b4d7..65ea0355a4f6 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -691,9 +691,11 @@ void jbd2_journal_commit_transaction(journal_t *journal) the last tag we set up. */
tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG); - - jbd2_descriptor_block_csum_set(journal, descriptor); start_journal_io: + if (descriptor) + jbd2_descriptor_block_csum_set(journal, + descriptor); + for (i = 0; i < bufs; i++) { struct buffer_head *bh = wbuf[i]; /*
From: Carlos Maiolino cmaiolino@redhat.com
[ Upstream commit dce30ca9e3b676fb288c33c1f4725a0621361185 ]
guard_bio_eod() can truncate a segment in bio to allow it to do IO on odd last sectors of a device.
It already checks if the IO starts past EOD, but it does not consider the possibility of an IO request starting within device boundaries can contain more than one segment past EOD.
In such cases, truncated_bytes can be bigger than PAGE_SIZE, and will underflow bvec->bv_len.
Fix this by checking if truncated_bytes is lower than PAGE_SIZE.
This situation has been found on filesystems such as isofs and vfat, which doesn't check the device size before mount, if the device is smaller than the filesystem itself, a readahead on such filesystem, which spans EOD, can trigger this situation, leading a call to zero_user() with a wrong size possibly corrupting memory.
I didn't see any crash, or didn't let the system run long enough to check if memory corruption will be hit somewhere, but adding instrumentation to guard_bio_end() to check truncated_bytes size, was enough to see the error.
The following script can trigger the error.
MNT=/mnt IMG=./DISK.img DEV=/dev/loop0
mkfs.vfat $IMG mount $IMG $MNT cp -R /etc $MNT &> /dev/null umount $MNT
losetup -D
losetup --find --show --sizelimit 16247280 $IMG mount $DEV $MNT
find $MNT -type f -exec cat {} + >/dev/null
Kudos to Eric Sandeen for coming up with the reproducer above
Reviewed-by: Ming Lei ming.lei@redhat.com Signed-off-by: Carlos Maiolino cmaiolino@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/fs/buffer.c b/fs/buffer.c index c083c4b3c1e7..a550e0d8e965 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3027,6 +3027,13 @@ void guard_bio_eod(int op, struct bio *bio) /* Uhhuh. We've got a bio that straddles the device size! */ truncated_bytes = bio->bi_iter.bi_size - (maxsector << 9);
+ /* + * The bio contains more than one segment which spans EOD, just return + * and let IO layer turn it into an EIO + */ + if (truncated_bytes > bvec->bv_len) + return; + /* Truncate the bio.. */ bio->bi_iter.bi_size -= truncated_bytes; bvec->bv_len -= truncated_bytes;
From: Tony Jones tonyj@suse.de
[ Upstream commit 7c5b019e3a638a5a290b0ec020f6ca83d2ec2aaa ]
Fix buffer overflow observed when running perf test.
The overflow is when trying to evaluate "1ULL << (64 - 1)" which is resulting in -9223372036854775808 which overflows the 20 character buffer.
If is possible this bug has been reported before but I still don't see any fix checked in:
See: https://www.spinics.net/lists/linux-perf-users/msg07714.html
Reported-by: Michael Sartain mikesart@fastmail.com Reported-by: Mathias Krause minipli@googlemail.com Signed-off-by: Tony Jones tonyj@suse.de Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org Cc: Frederic Weisbecker fweisbec@gmail.com Fixes: f7d82350e597 ("tools/events: Add files to create libtraceevent.a") Link: http://lkml.kernel.org/r/20190228015532.8941-1-tonyj@suse.de Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/traceevent/event-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 75de355a63d6..10985d991ed2 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -2416,7 +2416,7 @@ static int arg_num_eval(struct print_arg *arg, long long *val) static char *arg_eval (struct print_arg *arg) { long long val; - static char buf[20]; + static char buf[24];
switch (arg->type) { case PRINT_ATOM:
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
[ Upstream commit 95c80bc6952b6a5badc7b702d23e5bf14d251e7c ]
Dongdong reported a deadlock triggered by a hotplug event during a sysfs "remove" operation:
pciehp 0000:00:0c.0:pcie004: Slot(0-1): Link Up # echo 1 > 0000:00:0c.0/remove
PME and hotplug share an MSI/MSI-X vector. The sysfs "remove" side is:
remove_store pci_stop_and_remove_bus_device_locked pci_lock_rescan_remove pci_stop_and_remove_bus_device ... pcie_pme_remove pcie_pme_suspend synchronize_irq # wait for hotplug IRQ handler pci_unlock_rescan_remove
The hotplug side is:
pciehp_ist pciehp_handle_presence_or_link_change pciehp_configure_device pci_lock_rescan_remove # wait for pci_unlock_rescan_remove()
INFO: task bash:10913 blocked for more than 120 seconds.
# ps -ax |grep D PID TTY STAT TIME COMMAND 10913 ttyAMA0 Ds+ 0:00 -bash 14022 ? D 0:00 [irq/745-pciehp]
# cat /proc/14022/stack __switch_to+0x94/0xd8 pci_lock_rescan_remove+0x20/0x28 pciehp_configure_device+0x30/0x140 pciehp_handle_presence_or_link_change+0x324/0x458 pciehp_ist+0x1dc/0x1e0
# cat /proc/10913/stack __switch_to+0x94/0xd8 synchronize_irq+0x8c/0xc0 pcie_pme_suspend+0xa4/0x118 pcie_pme_remove+0x20/0x40 pcie_port_remove_service+0x3c/0x58 ... pcie_port_device_remove+0x2c/0x48 pcie_portdrv_remove+0x68/0x78 pci_device_remove+0x48/0x120 ... pci_stop_bus_device+0x84/0xc0 pci_stop_and_remove_bus_device_locked+0x24/0x40 remove_store+0xa4/0xb8 dev_attr_store+0x44/0x60 sysfs_kf_write+0x58/0x80
It is incorrect to call pcie_pme_suspend() from pcie_pme_remove() for two reasons.
First, pcie_pme_suspend() calls synchronize_irq(), which will wait for the native hotplug interrupt handler as well as for the PME one, because they share one IRQ (as per the spec). That may deadlock if hotplug is signaled while pcie_pme_remove() is running and the latter calls pci_lock_rescan_remove() before the former.
Second, if pcie_pme_suspend() figures out that wakeup needs to be enabled for the port, it will return without disabling the interrupt as expected by pcie_pme_remove() which was overlooked by commit c7b5a4e6e8fb ("PCI / PM: Fix native PME handling during system suspend/resume").
To fix that, rework pcie_pme_remove() to disable the PME interrupt, clear its status and prevent the PME worker function from re-enabling it before calling free_irq() on it, which should be sufficient.
Fixes: c7b5a4e6e8fb ("PCI / PM: Fix native PME handling during system suspend/resume") Link: https://lore.kernel.org/linux-pci/c7697e7c-e1af-13e4-8491-0a3996e6ab5d@huawe... Reported-by: Dongdong Liu liudongdong3@huawei.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com [bhelgaas: add URL and deadlock details from Dongdong] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/pme.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 3ed67676ea2a..e85c5a8206c4 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -363,6 +363,16 @@ static bool pcie_pme_check_wakeup(struct pci_bus *bus) return false; }
+static void pcie_pme_disable_interrupt(struct pci_dev *port, + struct pcie_pme_service_data *data) +{ + spin_lock_irq(&data->lock); + pcie_pme_interrupt_enable(port, false); + pcie_clear_root_pme_status(port); + data->noirq = true; + spin_unlock_irq(&data->lock); +} + /** * pcie_pme_suspend - Suspend PCIe PME service device. * @srv: PCIe service device to suspend. @@ -387,11 +397,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) return 0; }
- spin_lock_irq(&data->lock); - pcie_pme_interrupt_enable(port, false); - pcie_clear_root_pme_status(port); - data->noirq = true; - spin_unlock_irq(&data->lock); + pcie_pme_disable_interrupt(port, data);
synchronize_irq(srv->irq);
@@ -427,9 +433,11 @@ static int pcie_pme_resume(struct pcie_device *srv) */ static void pcie_pme_remove(struct pcie_device *srv) { - pcie_pme_suspend(srv); + struct pcie_pme_service_data *data = get_service_data(srv); + + pcie_pme_disable_interrupt(srv->port, data); free_irq(srv->irq, srv); - kfree(get_service_data(srv)); + kfree(data); }
static struct pcie_port_service_driver pcie_pme_driver = {
From: Alexei Avshalom Lazar ailizaro@codeaurora.org
[ Upstream commit de77a53c2d1e8fb3621e63e8e1f0f0c9a1a99ff7 ]
ies1 or ies2 might be null when code inside _wil_cfg80211_merge_extra_ies access them. Add explicit check for null and make sure ies1/ies2 are not accessed in such a case.
spos might be null and be accessed inside _wil_cfg80211_merge_extra_ies. Add explicit check for null in the while condition statement and make sure spos is not accessed in such a case.
Signed-off-by: Alexei Avshalom Lazar ailizaro@codeaurora.org Signed-off-by: Maya Erez merez@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wil6210/cfg80211.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index f79c337105cb..2daf33342b23 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1420,6 +1420,12 @@ static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len, u8 *buf, *dpos; const u8 *spos;
+ if (!ies1) + ies1_len = 0; + + if (!ies2) + ies2_len = 0; + if (ies1_len == 0 && ies2_len == 0) { *merged_ies = NULL; *merged_len = 0; @@ -1429,17 +1435,19 @@ static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len, buf = kmalloc(ies1_len + ies2_len, GFP_KERNEL); if (!buf) return -ENOMEM; - memcpy(buf, ies1, ies1_len); + if (ies1) + memcpy(buf, ies1, ies1_len); dpos = buf + ies1_len; spos = ies2; - while (spos + 1 < ies2 + ies2_len) { + while (spos && (spos + 1 < ies2 + ies2_len)) { /* IE tag at offset 0, length at offset 1 */ u16 ielen = 2 + spos[1];
if (spos + ielen > ies2 + ies2_len) break; if (spos[0] == WLAN_EID_VENDOR_SPECIFIC && - !_wil_cfg80211_find_ie(ies1, ies1_len, spos, ielen)) { + (!ies1 || !_wil_cfg80211_find_ie(ies1, ies1_len, + spos, ielen))) { memcpy(dpos, spos, ielen); dpos += ielen; }
From: Wen Yang wen.yang99@zte.com.cn
[ Upstream commit 34e022d8b780a03902d82fb3997ba7c7b1f40c81 ]
The call to of_find_node_by_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/net/wireless/mediatek/mt76/eeprom.c:58:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 48, but without a corresponding object release within this function. ./drivers/net/wireless/mediatek/mt76/eeprom.c:61:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 48, but without a corresponding object release within this function. ./drivers/net/wireless/mediatek/mt76/eeprom.c:67:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 48, but without a corresponding object release within this function. ./drivers/net/wireless/mediatek/mt76/eeprom.c:70:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 48, but without a corresponding object release within this function. ./drivers/net/wireless/mediatek/mt76/eeprom.c:72:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 48, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Felix Fietkau nbd@nbd.name Cc: Lorenzo Bianconi lorenzo.bianconi83@gmail.com Cc: Kalle Valo kvalo@codeaurora.org Cc: "David S. Miller" davem@davemloft.net Cc: Matthias Brugger matthias.bgg@gmail.com Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/eeprom.c | 24 ++++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index 530e5593765c..a1529920d877 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -54,22 +54,30 @@ mt76_get_of_eeprom(struct mt76_dev *dev, int len) part = np->name;
mtd = get_mtd_device_nm(part); - if (IS_ERR(mtd)) - return PTR_ERR(mtd); + if (IS_ERR(mtd)) { + ret = PTR_ERR(mtd); + goto out_put_node; + }
- if (size <= sizeof(*list)) - return -EINVAL; + if (size <= sizeof(*list)) { + ret = -EINVAL; + goto out_put_node; + }
offset = be32_to_cpup(list); ret = mtd_read(mtd, offset, len, &retlen, dev->eeprom.data); put_mtd_device(mtd); if (ret) - return ret; + goto out_put_node;
- if (retlen < len) - return -EINVAL; + if (retlen < len) { + ret = -EINVAL; + goto out_put_node; + }
- return 0; +out_put_node: + of_node_put(np); + return ret; #else return -ENOENT; #endif
From: Julia Lawall Julia.Lawall@lip6.fr
[ Upstream commit 8c2b43d2d85b48a97d2f8279278a4aac5b45f925 ]
Add an of_node_put when a tested device node is not available.
The semantic patch that fixes this problem is as follows (http://coccinelle.lip6.fr):
// <smpl> @@ identifier f; local idexpression e; expression x; @@
e = f(...); ... when != of_node_put(e) when != x = e when != e = x when any if (<+...of_device_is_available(e)...+>) { ... when != of_node_put(e) ( return e; | + of_node_put(e); return ...; ) } // </smpl>
Fixes: 5343e674f32fb ("crypto4xx: integrate ppc4xx-rng into crypto4xx") Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/amcc/crypto4xx_trng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/amcc/crypto4xx_trng.c b/drivers/crypto/amcc/crypto4xx_trng.c index 5e63742b0d22..53ab1f140a26 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.c +++ b/drivers/crypto/amcc/crypto4xx_trng.c @@ -80,8 +80,10 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev)
/* Find the TRNG device node and map it */ trng = of_find_matching_node(NULL, ppc4xx_trng_match); - if (!trng || !of_device_is_available(trng)) + if (!trng || !of_device_is_available(trng)) { + of_node_put(trng); return; + }
dev->trng_base = of_iomap(trng, 0); of_node_put(trng);
From: Eric Biggers ebiggers@google.com
[ Upstream commit 41798036430015ad45137db2d4c213cd77fd0251 ]
The cavium/zip implementation of the deflate compression algorithm is incorrectly being registered under the generic driver name, which prevents the generic implementation from being registered with the crypto API when CONFIG_CRYPTO_DEV_CAVIUM_ZIP=y. Similarly the lzs algorithm (which does not currently have a generic implementation...) is incorrectly being registered as lzs-generic.
Fix the naming collision by adding a suffix "-cavium" to the cra_driver_name of the cavium/zip algorithms.
Fixes: 640035a2dc55 ("crypto: zip - Add ThunderX ZIP driver core") Cc: Mahipal Challa mahipalreddy2006@gmail.com Cc: Jan Glauber jglauber@cavium.com Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/cavium/zip/zip_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c index be055b9547f6..6183f9128a8a 100644 --- a/drivers/crypto/cavium/zip/zip_main.c +++ b/drivers/crypto/cavium/zip/zip_main.c @@ -351,6 +351,7 @@ static struct pci_driver zip_driver = {
static struct crypto_alg zip_comp_deflate = { .cra_name = "deflate", + .cra_driver_name = "deflate-cavium", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, .cra_ctxsize = sizeof(struct zip_kernel_ctx), .cra_priority = 300, @@ -365,6 +366,7 @@ static struct crypto_alg zip_comp_deflate = {
static struct crypto_alg zip_comp_lzs = { .cra_name = "lzs", + .cra_driver_name = "lzs-cavium", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, .cra_ctxsize = sizeof(struct zip_kernel_ctx), .cra_priority = 300, @@ -384,7 +386,7 @@ static struct scomp_alg zip_scomp_deflate = { .decompress = zip_scomp_decompress, .base = { .cra_name = "deflate", - .cra_driver_name = "deflate-scomp", + .cra_driver_name = "deflate-scomp-cavium", .cra_module = THIS_MODULE, .cra_priority = 300, } @@ -397,7 +399,7 @@ static struct scomp_alg zip_scomp_lzs = { .decompress = zip_scomp_decompress, .base = { .cra_name = "lzs", - .cra_driver_name = "lzs-scomp", + .cra_driver_name = "lzs-scomp-cavium", .cra_module = THIS_MODULE, .cra_priority = 300, }
From: Paul Kocialkowski paul.kocialkowski@bootlin.com
[ Upstream commit 68ef236274793066b9ba3154b16c0acc1c891e5c ]
According to the chipidea driver bindings, the USB PHY is specified via the "phys" phandle node. However, this only takes effect for USB PHYs that use the common PHY framework. For legacy USB PHYs, a simple lookup based on the USB PHY type is done instead.
This does not play out well when more than one USB PHY is registered, since the first registered PHY matching the type will always be returned regardless of what the driver was bound to.
Fix this by looking up the PHY based on the "phys" phandle node. Although generic PHYs are rather matched by their "phys-name" and not the "phys" phandle directly, there is no helper for similar lookup on legacy PHYs and it's probably not worth the effort to add it.
When no legacy USB PHY is found by phandle, fallback to grabbing any registered USB2 PHY. This ensures backward compatibility if some users were actually relying on this mechanism.
Signed-off-by: Paul Kocialkowski paul.kocialkowski@bootlin.com Signed-off-by: Peter Chen peter.chen@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/chipidea/core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 85fc6db48e44..159b897c5e80 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -935,8 +935,15 @@ static int ci_hdrc_probe(struct platform_device *pdev) } else if (ci->platdata->usb_phy) { ci->usb_phy = ci->platdata->usb_phy; } else { + ci->usb_phy = devm_usb_get_phy_by_phandle(dev->parent, "phys", + 0); ci->phy = devm_phy_get(dev->parent, "usb-phy"); - ci->usb_phy = devm_usb_get_phy(dev->parent, USB_PHY_TYPE_USB2); + + /* Fallback to grabbing any registered USB2 PHY */ + if (IS_ERR(ci->usb_phy) && + PTR_ERR(ci->usb_phy) != -EPROBE_DEFER) + ci->usb_phy = devm_usb_get_phy(dev->parent, + USB_PHY_TYPE_USB2);
/* if both generic PHY and USB PHY layers aren't enabled */ if (PTR_ERR(ci->phy) == -ENOSYS &&
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit 11f5acce2fa43b015a8120fa7620fa4efd0a2952 ]
We store 2 multilevel tables in iommu_table - one for the hardware and one with the corresponding userspace addresses. Before allocating the tables, the iommu_table_group_ops::get_table_size() hook returns the combined size of the two and VFIO SPAPR TCE IOMMU driver adjusts the locked_vm counter correctly. When the table is actually allocated, the amount of allocated memory is stored in iommu_table::it_allocated_size and used to decrement the locked_vm counter when we release the memory used by the table; .get_table_size() and .create_table() calculate it independently but the result is expected to be the same.
However the allocator does not add the userspace table size to .it_allocated_size so when we destroy the table because of VFIO PCI unplug (i.e. VFIO container is gone but the userspace keeps running), we decrement locked_vm by just a half of size of memory we are releasing.
To make things worse, since we enabled on-demand allocation of indirect levels, it_allocated_size contains only the amount of memory actually allocated at the table creation time which can just be a fraction. It is not a problem with incrementing locked_vm (as get_table_size() value is used) but it is with decrementing.
As the result, we leak locked_vm and may not be able to allocate more IOMMU tables after few iterations of hotplug/unplug.
This sets it_allocated_size in the pnv_pci_ioda2_ops::create_table() hook to what pnv_pci_ioda2_get_table_size() returns so from now on we have a single place which calculates the maximum memory a table can occupy. The original meaning of it_allocated_size is somewhat lost now though.
We do not ditch it_allocated_size whatsoever here and we do not call get_table_size() from vfio_iommu_spapr_tce.c when decrementing locked_vm as we may have multiple IOMMU groups per container and even though they all are supposed to have the same get_table_size() implementation, there is a small chance for failure or confusion.
Fixes: 090bad39b237 ("powerpc/powernv: Add indirect levels to it_userspace") Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: David Gibson david@gibson.dropbear.id.au Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/pci-ioda-tce.c | 1 - arch/powerpc/platforms/powernv/pci-ioda.c | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda-tce.c b/arch/powerpc/platforms/powernv/pci-ioda-tce.c index 7639b2168755..f5adb6b756f7 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda-tce.c +++ b/arch/powerpc/platforms/powernv/pci-ioda-tce.c @@ -313,7 +313,6 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, page_shift); tbl->it_level_size = 1ULL << (level_shift - 3); tbl->it_indirect_levels = levels - 1; - tbl->it_allocated_size = total_allocated; tbl->it_userspace = uas; tbl->it_nid = nid;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index cde710297a4e..326ca6288bb1 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2603,8 +2603,13 @@ static long pnv_pci_ioda2_create_table_userspace( int num, __u32 page_shift, __u64 window_size, __u32 levels, struct iommu_table **ptbl) { - return pnv_pci_ioda2_create_table(table_group, + long ret = pnv_pci_ioda2_create_table(table_group, num, page_shift, window_size, levels, true, ptbl); + + if (!ret) + (*ptbl)->it_allocated_size = pnv_pci_ioda2_get_table_size( + page_shift, window_size, levels); + return ret; }
static void pnv_ioda2_take_ownership(struct iommu_table_group *table_group)
From: Benjamin Block bblock@linux.ibm.com
[ Upstream commit 1749ef00f7312679f76d5e9104c5d1e22a829038 ]
We had a test-report where, under memory pressure, adding LUNs to the systems would fail (the tests add LUNs strictly in sequence):
[ 5525.853432] scsi 0:0:1:1088045124: Direct-Access IBM 2107900 .148 PQ: 0 ANSI: 5 [ 5525.853826] scsi 0:0:1:1088045124: alua: supports implicit TPGS [ 5525.853830] scsi 0:0:1:1088045124: alua: device naa.6005076303ffd32700000000000044da port group 0 rel port 43 [ 5525.853931] sd 0:0:1:1088045124: Attached scsi generic sg10 type 0 [ 5525.854075] sd 0:0:1:1088045124: [sdk] Disabling DIF Type 1 protection [ 5525.855495] sd 0:0:1:1088045124: [sdk] 2097152 512-byte logical blocks: (1.07 GB/1.00 GiB) [ 5525.855606] sd 0:0:1:1088045124: [sdk] Write Protect is off [ 5525.855609] sd 0:0:1:1088045124: [sdk] Mode Sense: ed 00 00 08 [ 5525.855795] sd 0:0:1:1088045124: [sdk] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 5525.857838] sdk: sdk1 [ 5525.859468] sd 0:0:1:1088045124: [sdk] Attached SCSI disk [ 5525.865073] sd 0:0:1:1088045124: alua: transition timeout set to 60 seconds [ 5525.865078] sd 0:0:1:1088045124: alua: port group 00 state A preferred supports tolusnA [ 5526.015070] sd 0:0:1:1088045124: alua: port group 00 state A preferred supports tolusnA [ 5526.015213] sd 0:0:1:1088045124: alua: port group 00 state A preferred supports tolusnA [ 5526.587439] scsi_alloc_sdev: Allocation failure during SCSI scanning, some SCSI devices might not be configured [ 5526.588562] scsi_alloc_sdev: Allocation failure during SCSI scanning, some SCSI devices might not be configured
Looking at the code of scsi_alloc_sdev(), and all the calling contexts, there seems to be no reason to use GFP_ATMOIC here. All the different call-contexts use a mutex at some point, and nothing in between that requires no sleeping, as far as I could see. Additionally, the code that later allocates the block queue for the device (scsi_mq_alloc_queue()) already uses GFP_KERNEL.
There are similar allocations in two other functions: scsi_probe_and_add_lun(), and scsi_add_lun(),; that can also be done with GFP_KERNEL.
Here is the contexts for the three functions so far:
scsi_alloc_sdev() scsi_probe_and_add_lun() scsi_sequential_lun_scan() __scsi_scan_target() scsi_scan_target() mutex_lock() scsi_scan_channel() scsi_scan_host_selected() mutex_lock() scsi_report_lun_scan() __scsi_scan_target() ... __scsi_add_device() mutex_lock() __scsi_scan_target() ... scsi_report_lun_scan() ... scsi_get_host_dev() mutex_lock()
scsi_probe_and_add_lun() ...
scsi_add_lun() scsi_probe_and_add_lun() ...
So replace all these, and give them a bit of a better chance to succeed, with more chances of reclaim.
Signed-off-by: Benjamin Block bblock@linux.ibm.com Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_scan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 78ca63dfba4a..9a7e3a3bd5ce 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -220,7 +220,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size, - GFP_ATOMIC); + GFP_KERNEL); if (!sdev) goto out;
@@ -796,7 +796,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, */ sdev->inquiry = kmemdup(inq_result, max_t(size_t, sdev->inquiry_len, 36), - GFP_ATOMIC); + GFP_KERNEL); if (sdev->inquiry == NULL) return SCSI_SCAN_NO_RESPONSE;
@@ -1087,7 +1087,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, if (!sdev) goto out;
- result = kmalloc(result_len, GFP_ATOMIC | + result = kmalloc(result_len, GFP_KERNEL | ((shost->unchecked_isa_dma) ? __GFP_DMA : 0)); if (!result) goto out_free_sdev;
From: Masahiro Yamada yamada.masahiro@socionext.com
[ Upstream commit 9390dff66a52d1a60c6e517d8fa6cdbdffc83cb1 ]
If include/config/auto.conf.cmd is lost for some reasons, it is not self-healing, so the top Makefile misses to run syncconfig. Move include/config/auto.conf.cmd to the target side.
I used a pattern rule instead of a normal rule here although it is a bit gross.
If the rule were written with a normal rule like this,
include/config/auto.conf \ include/config/auto.conf.cmd \ include/config/tristate.conf: $(KCONFIG_CONFIG) $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
... syncconfig would be executed per target.
Using a pattern rule makes sure that syncconfig is executed just once because Make assumes the recipe will create all of the targets.
Here is a quote from the GNU Make manual [1]:
"Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and recipe. If a pattern rule has multiple targets, make knows that the rule's recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets. When searching for a pattern rule to match a target, the target patterns of a rule other than the one that matches the target in need of a rule are incidental: make worries only about giving a recipe and prerequisites to the file presently in question. However, when this file's recipe is run, the other targets are marked as having been updated themselves."
[1]: https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index 3b1c6cff6700..c35c1b0aa661 100644 --- a/Makefile +++ b/Makefile @@ -626,12 +626,15 @@ ifeq ($(may-sync-config),1) -include include/config/auto.conf.cmd
# To avoid any implicit rule to kick in, define an empty command -$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; +$(KCONFIG_CONFIG): ;
# The actual configuration files used during the build are stored in # include/generated/ and include/config/. Update them if .config is newer than # include/config/auto.conf (which mirrors .config). -include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd +# +# This exploits the 'multi-target pattern rule' trick. +# The syncconfig should be executed only once to make all the targets. +%/auto.conf %/auto.conf.cmd %/tristate.conf: $(KCONFIG_CONFIG) $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig else # External modules and some install targets need include/generated/autoconf.h
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit e7140639b1de65bba435a6bd772d134901141f86 ]
When building with -Wsometimes-uninitialized, Clang warns:
arch/powerpc/xmon/ppc-dis.c:157:7: warning: variable 'opcode' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if (cpu_has_feature(CPU_FTRS_POWER9)) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/xmon/ppc-dis.c:167:7: note: uninitialized use occurs here if (opcode == NULL) ^~~~~~ arch/powerpc/xmon/ppc-dis.c:157:3: note: remove the 'if' if its condition is always true if (cpu_has_feature(CPU_FTRS_POWER9)) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/xmon/ppc-dis.c:132:38: note: initialize the variable 'opcode' to silence this warning const struct powerpc_opcode *opcode; ^ = NULL 1 warning generated.
This warning seems to make no sense on the surface because opcode is set to NULL right below this statement. However, there is a comma instead of semicolon to end the dialect assignment, meaning that the opcode assignment only happens in the if statement. Properly terminate that line so that Clang no longer warns.
Fixes: 5b102782c7f4 ("powerpc/xmon: Enable disassembly files (compilation changes)") Signed-off-by: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/xmon/ppc-dis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c index 9deea5ee13f6..27f1e6415036 100644 --- a/arch/powerpc/xmon/ppc-dis.c +++ b/arch/powerpc/xmon/ppc-dis.c @@ -158,7 +158,7 @@ int print_insn_powerpc (unsigned long insn, unsigned long memaddr) dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 - | PPC_OPCODE_VSX | PPC_OPCODE_VSX3), + | PPC_OPCODE_VSX | PPC_OPCODE_VSX3);
/* Get the major opcode of the insn. */ opcode = NULL;
From: Sai Prakash Ranjan saiprakash.ranjan@codeaurora.org
[ Upstream commit 5666dfd1d8a45a167f0d8b4ef47ea7f780b1f24a ]
SDM845 has ETMv4.2 and can use the existing etm4x driver. But the current etm driver checks only for ETMv4.0 and errors out for other etm4x versions. This patch adds this missing support to enable SoC's with ETMv4x to use same driver by checking only the ETM architecture major version number.
Without this change, we get below error during etm probe:
/ # dmesg | grep etm [ 6.660093] coresight-etm4x: probe of 7040000.etm failed with error -22 [ 6.666902] coresight-etm4x: probe of 7140000.etm failed with error -22 [ 6.673708] coresight-etm4x: probe of 7240000.etm failed with error -22 [ 6.680511] coresight-etm4x: probe of 7340000.etm failed with error -22 [ 6.687313] coresight-etm4x: probe of 7440000.etm failed with error -22 [ 6.694113] coresight-etm4x: probe of 7540000.etm failed with error -22 [ 6.700914] coresight-etm4x: probe of 7640000.etm failed with error -22 [ 6.707717] coresight-etm4x: probe of 7740000.etm failed with error -22
With this change, etm probe is successful:
/ # dmesg | grep etm [ 6.659198] coresight-etm4x 7040000.etm: CPU0: ETM v4.2 initialized [ 6.665848] coresight-etm4x 7140000.etm: CPU1: ETM v4.2 initialized [ 6.672493] coresight-etm4x 7240000.etm: CPU2: ETM v4.2 initialized [ 6.679129] coresight-etm4x 7340000.etm: CPU3: ETM v4.2 initialized [ 6.685770] coresight-etm4x 7440000.etm: CPU4: ETM v4.2 initialized [ 6.692403] coresight-etm4x 7540000.etm: CPU5: ETM v4.2 initialized [ 6.699024] coresight-etm4x 7640000.etm: CPU6: ETM v4.2 initialized [ 6.705646] coresight-etm4x 7740000.etm: CPU7: ETM v4.2 initialized
Signed-off-by: Sai Prakash Ranjan saiprakash.ranjan@codeaurora.org Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/coresight/coresight-etm4x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 1d94ebec027b..2bce7cf0b0af 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -54,7 +54,8 @@ static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
static bool etm4_arch_supported(u8 arch) { - switch (arch) { + /* Mask out the minor version number */ + switch (arch & 0xf0) { case ETM_ARCH_V4: break; default:
From: Lubomir Rintel lkundrak@v3.sk
[ Upstream commit fe9ed6d2483fda55465f32924fb15bce0fac3fac ]
Like the other OF-enabled drivers, use the port number from the firmware if the devicetree specifies an alias:
aliases { ... serial2 = &uart2; /* Should be ttyS2 */ }
This is how the deprecated pxa.c driver behaved, switching to 8250_pxa messes up the numbering.
Signed-off-by: Lubomir Rintel lkundrak@v3.sk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_pxa.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c index b9bcbe20a2be..c47188860e32 100644 --- a/drivers/tty/serial/8250/8250_pxa.c +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -113,6 +113,10 @@ static int serial_pxa_probe(struct platform_device *pdev) if (ret) return ret;
+ ret = of_alias_get_id(pdev->dev.of_node, "serial"); + if (ret >= 0) + uart.port.line = ret; + uart.port.type = PORT_XSCALE; uart.port.iotype = UPIO_MEM32; uart.port.mapbase = mmres->start;
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 74ffe79ae538283bbf7c155e62339f1e5c87b55a ]
Mostly unwind is done with irqs enabled however SLUB may call it with irqs disabled while creating a new SLUB cache.
I had system freeze while loading a module which called kmem_cache_create() on init. That means SLUB's __slab_alloc() disabled interrupts and then
->new_slab_objects() ->new_slab() ->setup_object() ->setup_object_debug() ->init_tracking() ->set_track() ->save_stack_trace() ->save_stack_trace_tsk() ->walk_stackframe() ->unwind_frame() ->unwind_find_idx() =>spin_lock_irqsave(&unwind_lock);
Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/kernel/unwind.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 0bee233fef9a..314cfb232a63 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -93,7 +93,7 @@ extern const struct unwind_idx __start_unwind_idx[]; static const struct unwind_idx *__origin_unwind_idx; extern const struct unwind_idx __stop_unwind_idx[];
-static DEFINE_SPINLOCK(unwind_lock); +static DEFINE_RAW_SPINLOCK(unwind_lock); static LIST_HEAD(unwind_tables);
/* Convert a prel31 symbol to an absolute address */ @@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) /* module unwind tables */ struct unwind_table *table;
- spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_for_each_entry(table, &unwind_tables, list) { if (addr >= table->begin_addr && addr < table->end_addr) { @@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) break; } } - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags); }
pr_debug("%s: idx = %p\n", __func__, idx); @@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, tab->begin_addr = text_addr; tab->end_addr = text_addr + text_size;
- spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_add_tail(&tab->list, &unwind_tables); - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags);
return tab; } @@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_table *tab) if (!tab) return;
- spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_del(&tab->list); - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags);
kfree(tab); }
From: Nicolas Boichat drinkcat@chromium.org
[ Upstream commit 032ebd8548c9d05e8d2bdc7a7ec2fe29454b0ad0 ]
L1 tables are allocated with __get_dma_pages, and therefore already ignored by kmemleak.
Without this, the kernel would print this error message on boot, when the first L1 table is allocated:
[ 2.810533] kmemleak: Trying to color unknown object at 0xffffffd652388000 as Black [ 2.818190] CPU: 5 PID: 39 Comm: kworker/5:0 Tainted: G S 4.19.16 #8 [ 2.831227] Workqueue: events deferred_probe_work_func [ 2.836353] Call trace: ... [ 2.852532] paint_ptr+0xa0/0xa8 [ 2.855750] kmemleak_ignore+0x38/0x6c [ 2.859490] __arm_v7s_alloc_table+0x168/0x1f4 [ 2.863922] arm_v7s_alloc_pgtable+0x114/0x17c [ 2.868354] alloc_io_pgtable_ops+0x3c/0x78 ...
Fixes: e5fc9753b1a8314 ("iommu/io-pgtable: Add ARMv7 short descriptor support") Signed-off-by: Nicolas Boichat drinkcat@chromium.org Acked-by: Will Deacon will.deacon@arm.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/io-pgtable-arm-v7s.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index b5948ba6b3b3..7a3ce176f47f 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -217,7 +217,8 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, if (dma != phys) goto out_unmap; } - kmemleak_ignore(table); + if (lvl == 2) + kmemleak_ignore(table); return table;
out_unmap:
From: "Aneesh Kumar K.V" aneesh.kumar@linux.ibm.com
[ Upstream commit 5330367fa300742a97e20e953b1f77f48392faae ]
After we ALIGN up the address we need to make sure we didn't overflow and resulted in zero address. In that case, we need to make sure that the returned address is greater than mmap_min_addr.
This fixes selftest va_128TBswitch --run-hugetlb reporting failures when run as non root user for
mmap(-1, MAP_HUGETLB)
The bug is that a non-root user requesting address -1 will be given address 0 which will then fail, whereas they should have been given something else that would have succeeded.
We also avoid the first mmap(-1, MAP_HUGETLB) returning NULL address as mmap address with this change. So we think this is not a security issue, because it only affects whether we choose an address below mmap_min_addr, not whether we actually allow that address to be mapped. ie. there are existing capability checks to prevent a user mapping below mmap_min_addr and those will still be honoured even without this fix.
Fixes: 484837601d4d ("powerpc/mm: Add radix support for hugetlb") Reviewed-by: Laurent Dufour ldufour@linux.vnet.ibm.com Signed-off-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/hugetlbpage-radix.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/hugetlbpage-radix.c b/arch/powerpc/mm/hugetlbpage-radix.c index 2486bee0f93e..97c7a39ebc00 100644 --- a/arch/powerpc/mm/hugetlbpage-radix.c +++ b/arch/powerpc/mm/hugetlbpage-radix.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/mm.h> #include <linux/hugetlb.h> +#include <linux/security.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/cacheflush.h> @@ -73,7 +74,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (addr) { addr = ALIGN(addr, huge_page_size(h)); vma = find_vma(mm, addr); - if (high_limit - len >= addr && + if (high_limit - len >= addr && addr >= mmap_min_addr && (!vma || addr + len <= vm_start_gap(vma))) return addr; } @@ -83,7 +84,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr, */ info.flags = VM_UNMAPPED_AREA_TOPDOWN; info.length = len; - info.low_limit = PAGE_SIZE; + info.low_limit = max(PAGE_SIZE, mmap_min_addr); info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW); info.align_mask = PAGE_MASK & ~huge_page_mask(h); info.align_offset = 0;
From: Qu Wenruo wqu@suse.com
[ Upstream commit f5fef4593653dfa2a865c485bb81415de51d5c99 ]
[BUG] Btrfs qgroup will still hit EDQUOT under the following case:
$ dev=/dev/test/test $ mnt=/mnt/btrfs $ umount $mnt &> /dev/null $ umount $dev &> /dev/null
$ mkfs.btrfs -f $dev $ mount $dev $mnt -o nospace_cache
$ btrfs subv create $mnt/subv $ btrfs quota enable $mnt $ btrfs quota rescan -w $mnt $ btrfs qgroup limit -e 1G $mnt/subv
$ fallocate -l 900M $mnt/subv/padding $ sync
$ rm $mnt/subv/padding
# Hit EDQUOT $ xfs_io -f -c "pwrite 0 512M" $mnt/subv/real_file
[CAUSE] Since commit a514d63882c3 ("btrfs: qgroup: Commit transaction in advance to reduce early EDQUOT"), btrfs is not forced to commit transaction to reclaim more quota space.
Instead, we just check pertrans metadata reservation against some threshold and try to do asynchronously transaction commit.
However in above case, the pertrans metadata reservation is pretty small thus it will never trigger asynchronous transaction commit.
[FIX] Instead of only accounting pertrans metadata reservation, we calculate how much free space we have, and if there isn't much free space left, commit transaction asynchronously to try to free some space.
This may slow down the fs when we have less than 32M free qgroup space, but should reduce a lot of false EDQUOT, so the cost should be acceptable.
Signed-off-by: Qu Wenruo wqu@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/qgroup.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index e1fcb28ad4cc..e46e83e87600 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2427,16 +2427,15 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, /* * Two limits to commit transaction in advance. * - * For RATIO, it will be 1/RATIO of the remaining limit - * (excluding data and prealloc meta) as threshold. + * For RATIO, it will be 1/RATIO of the remaining limit as threshold. * For SIZE, it will be in byte unit as threshold. */ -#define QGROUP_PERTRANS_RATIO 32 -#define QGROUP_PERTRANS_SIZE SZ_32M +#define QGROUP_FREE_RATIO 32 +#define QGROUP_FREE_SIZE SZ_32M static bool qgroup_check_limits(struct btrfs_fs_info *fs_info, const struct btrfs_qgroup *qg, u64 num_bytes) { - u64 limit; + u64 free; u64 threshold;
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) && @@ -2455,20 +2454,21 @@ static bool qgroup_check_limits(struct btrfs_fs_info *fs_info, */ if ((qg->lim_flags & (BTRFS_QGROUP_LIMIT_MAX_RFER | BTRFS_QGROUP_LIMIT_MAX_EXCL))) { - if (qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) - limit = qg->max_excl; - else - limit = qg->max_rfer; - threshold = (limit - qg->rsv.values[BTRFS_QGROUP_RSV_DATA] - - qg->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC]) / - QGROUP_PERTRANS_RATIO; - threshold = min_t(u64, threshold, QGROUP_PERTRANS_SIZE); + if (qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) { + free = qg->max_excl - qgroup_rsv_total(qg) - qg->excl; + threshold = min_t(u64, qg->max_excl / QGROUP_FREE_RATIO, + QGROUP_FREE_SIZE); + } else { + free = qg->max_rfer - qgroup_rsv_total(qg) - qg->rfer; + threshold = min_t(u64, qg->max_rfer / QGROUP_FREE_RATIO, + QGROUP_FREE_SIZE); + }
/* * Use transaction_kthread to commit transaction, so we no * longer need to bother nested transaction nor lock context. */ - if (qg->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > threshold) + if (free < threshold) btrfs_commit_transaction_locksafe(fs_info); }
From: Aaro Koskinen aaro.koskinen@iki.fi
[ Upstream commit a6327b5e57fdc679c842588c3be046c0b39cc127 ]
When running OMAP1 kernel on QEMU, MMC access is annoyingly noisy:
MMC: CTO of 0xff and 0xfe cannot be used! MMC: CTO of 0xff and 0xfe cannot be used! MMC: CTO of 0xff and 0xfe cannot be used! [ad inf.]
Emulator warnings appear to be valid. The TI document SPRU680 [1] ("OMAP5910 Dual-Core Processor MultiMedia Card/Secure Data Memory Card (MMC/SD) Reference Guide") page 36 states that the maximum timeout is 253 cycles and "0xff and 0xfe cannot be used".
Fix by using 0xfd as the maximum timeout.
Tested using QEMU 2.5 (Siemens SX1 machine, OMAP310), and also checked on real hardware using Palm TE (OMAP310), Nokia 770 (OMAP1710) and Nokia N810 (OMAP2420) that MMC works as before.
[1] http://www.ti.com/lit/ug/spru680/spru680.pdf
Fixes: 730c9b7e6630f ("[MMC] Add OMAP MMC host driver") Signed-off-by: Aaro Koskinen aaro.koskinen@iki.fi Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index c60a7625b1fa..b2873a2432b6 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -920,7 +920,7 @@ static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_reques reg &= ~(1 << 5); OMAP_MMC_WRITE(host, SDIO, reg); /* Set maximum timeout */ - OMAP_MMC_WRITE(host, CTO, 0xff); + OMAP_MMC_WRITE(host, CTO, 0xfd); }
static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
From: Andrew Lunn andrew@lunn.ch
[ Upstream commit f6d9758b12660484b6639364cc406da92a918c96 ]
The following false positive lockdep splat has been observed.
====================================================== WARNING: possible circular locking dependency detected 4.20.0+ #302 Not tainted ------------------------------------------------------ systemd-udevd/160 is trying to acquire lock: edea6080 (&chip->reg_lock){+.+.}, at: __setup_irq+0x640/0x704
but task is already holding lock: edff0340 (&desc->request_mutex){+.+.}, at: __setup_irq+0xa0/0x704
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&desc->request_mutex){+.+.}: mutex_lock_nested+0x1c/0x24 __setup_irq+0xa0/0x704 request_threaded_irq+0xd0/0x150 mv88e6xxx_probe+0x41c/0x694 [mv88e6xxx] mdio_probe+0x2c/0x54 really_probe+0x200/0x2c4 driver_probe_device+0x5c/0x174 __driver_attach+0xd8/0xdc bus_for_each_dev+0x58/0x7c bus_add_driver+0xe4/0x1f0 driver_register+0x7c/0x110 mdio_driver_register+0x24/0x58 do_one_initcall+0x74/0x2e8 do_init_module+0x60/0x1d0 load_module+0x1968/0x1ff4 sys_finit_module+0x8c/0x98 ret_fast_syscall+0x0/0x28 0xbedf2ae8
-> #0 (&chip->reg_lock){+.+.}: __mutex_lock+0x50/0x8b8 mutex_lock_nested+0x1c/0x24 __setup_irq+0x640/0x704 request_threaded_irq+0xd0/0x150 mv88e6xxx_g2_irq_setup+0xcc/0x1b4 [mv88e6xxx] mv88e6xxx_probe+0x44c/0x694 [mv88e6xxx] mdio_probe+0x2c/0x54 really_probe+0x200/0x2c4 driver_probe_device+0x5c/0x174 __driver_attach+0xd8/0xdc bus_for_each_dev+0x58/0x7c bus_add_driver+0xe4/0x1f0 driver_register+0x7c/0x110 mdio_driver_register+0x24/0x58 do_one_initcall+0x74/0x2e8 do_init_module+0x60/0x1d0 load_module+0x1968/0x1ff4 sys_finit_module+0x8c/0x98 ret_fast_syscall+0x0/0x28 0xbedf2ae8
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&desc->request_mutex); lock(&chip->reg_lock); lock(&desc->request_mutex); lock(&chip->reg_lock);
&desc->request_mutex refer to two different mutex. #1 is the GPIO for the chip interrupt. #2 is the chained interrupt between global 1 and global 2.
Add lockdep classes to the GPIO interrupt to avoid this.
Reported-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net
Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c078c791f481..dabe89968a78 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -442,12 +442,20 @@ static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip) { + static struct lock_class_key lock_key; + static struct lock_class_key request_key; int err;
err = mv88e6xxx_g1_irq_setup_common(chip); if (err) return err;
+ /* These lock classes tells lockdep that global 1 irqs are in + * a different category than their parent GPIO, so it won't + * report false recursion. + */ + irq_set_lockdep_class(chip->irq, &lock_key, &request_key); + err = request_threaded_irq(chip->irq, NULL, mv88e6xxx_g1_irq_thread_fn, IRQF_ONESHOT,
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 135e7245479addc6b1f5d031e3d7e2ddb3d2b109 ]
Provide precision hints to snprintf() since we know the destination buffer size of the RX/TX ring names are IFNAMSIZ + 5 - 1. This fixes the following warnings:
drivers/net/ethernet/intel/e1000e/netdev.c: In function 'e1000_request_msix': drivers/net/ethernet/intel/e1000e/netdev.c:2109:13: warning: 'snprintf' output may be truncated before the last format character [-Wformat-truncation=] "%s-rx-0", netdev->name); ^ drivers/net/ethernet/intel/e1000e/netdev.c:2107:3: note: 'snprintf' output between 6 and 21 bytes into a destination of size 20 snprintf(adapter->rx_ring->name, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sizeof(adapter->rx_ring->name) - 1, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "%s-rx-0", netdev->name); ~~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/ethernet/intel/e1000e/netdev.c:2125:13: warning: 'snprintf' output may be truncated before the last format character [-Wformat-truncation=] "%s-tx-0", netdev->name); ^ drivers/net/ethernet/intel/e1000e/netdev.c:2123:3: note: 'snprintf' output between 6 and 21 bytes into a destination of size 20 snprintf(adapter->tx_ring->name, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sizeof(adapter->tx_ring->name) - 1, ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "%s-tx-0", netdev->name); ~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 3ba0c90e7055..e3945469b5c8 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2106,7 +2106,7 @@ static int e1000_request_msix(struct e1000_adapter *adapter) if (strlen(netdev->name) < (IFNAMSIZ - 5)) snprintf(adapter->rx_ring->name, sizeof(adapter->rx_ring->name) - 1, - "%s-rx-0", netdev->name); + "%.14s-rx-0", netdev->name); else memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ); err = request_irq(adapter->msix_entries[vector].vector, @@ -2122,7 +2122,7 @@ static int e1000_request_msix(struct e1000_adapter *adapter) if (strlen(netdev->name) < (IFNAMSIZ - 5)) snprintf(adapter->tx_ring->name, sizeof(adapter->tx_ring->name) - 1, - "%s-tx-0", netdev->name); + "%.14s-tx-0", netdev->name); else memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ); err = request_irq(adapter->msix_entries[vector].vector,
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit ab2c4e2581ad32c28627235ff0ae8c5a5ea6899f ]
Give precision identifiers to the two snprintf() formatting the priority and TC strings to avoid producing these two warnings:
drivers/net/ethernet/mellanox/mlxsw/spectrum.c: In function 'mlxsw_sp_port_get_prio_strings': drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2132:37: warning: '%d' directive output may be truncated writing between 1 and 3 bytes into a region of size between 0 and 31 [-Wformat-truncation=] snprintf(*p, ETH_GSTRING_LEN, "%s_%d", ^~ drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2132:3: note: 'snprintf' output between 3 and 36 bytes into a destination of size 32 snprintf(*p, ETH_GSTRING_LEN, "%s_%d", ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mlxsw_sp_port_hw_prio_stats[i].str, prio); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/ethernet/mellanox/mlxsw/spectrum.c: In function 'mlxsw_sp_port_get_tc_strings': drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2143:37: warning: '%d' directive output may be truncated writing between 1 and 11 bytes into a region of size between 0 and 31 [-Wformat-truncation=] snprintf(*p, ETH_GSTRING_LEN, "%s_%d", ^~ drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2143:3: note: 'snprintf' output between 3 and 44 bytes into a destination of size 32 snprintf(*p, ETH_GSTRING_LEN, "%s_%d", ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mlxsw_sp_port_hw_tc_stats[i].str, tc); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Ido Schimmel idosch@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index a12b5710891e..f9bef030ee05 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1988,7 +1988,7 @@ static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio) int i;
for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) { - snprintf(*p, ETH_GSTRING_LEN, "%s_%d", + snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d", mlxsw_sp_port_hw_prio_stats[i].str, prio); *p += ETH_GSTRING_LEN; } @@ -1999,7 +1999,7 @@ static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc) int i;
for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) { - snprintf(*p, ETH_GSTRING_LEN, "%s_%d", + snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d", mlxsw_sp_port_hw_tc_stats[i].str, tc); *p += ETH_GSTRING_LEN; }
From: Yang Fan nullptr.cpp@gmail.com
[ Upstream commit 4d9b2864a415fec39150bc13efc730c7eb88711e ]
Commit ae7c8cba3221 ("platform/x86: ideapad-laptop: add lenovo RESCUER R720-15IKBN to no_hw_rfkill_list") added DMI_MATCH(DMI_BOARD_NAME, "80WW") for Lenovo RESCUER R720-15IKBN.
But DMI_BOARD_NAME does not match 80WW on Lenovo RESCUER R720-15IKBN, thus cause Wireless LAN still be hard blocked.
On Lenovo RESCUER R720-15IKBN: ~$ cat /sys/class/dmi/id/sys_vendor LENOVO ~$ cat /sys/class/dmi/id/board_name Provence-5R3 ~$ cat /sys/class/dmi/id/product_name 80WW ~$ cat /sys/class/dmi/id/product_version Lenovo R720-15IKBN
So on Lenovo RESCUER R720-15IKBN: DMI_SYS_VENDOR should match "LENOVO", DMI_BOARD_NAME should match "Provence-5R3", DMI_PRODUCT_NAME should match "80WW", DMI_PRODUCT_VERSION should match "Lenovo R720-15IKBN".
Fix it, and in according with other entries in no_hw_rfkill_list, use DMI_PRODUCT_VERSION instead of DMI_BOARD_NAME.
Fixes: ae7c8cba3221 ("platform/x86: ideapad-laptop: add lenovo RESCUER R720-15IKBN to no_hw_rfkill_list") Signed-off-by: Yang Fan nullptr.cpp@gmail.com Signed-off-by: Darren Hart (VMware) dvhart@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/ideapad-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index d4f1259ff5a2..62d4b94e2531 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -989,7 +989,7 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { .ident = "Lenovo RESCUER R720-15IKBN", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "80WW"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo R720-15IKBN"), }, }, {
From: Vadim Pasternak vadimp@mellanox.com
[ Upstream commit e4c275f77624961b56cce397814d9d770a45ac59 ]
Fix the following KASAN warning produced when booting a 64-bit kernel: [ 13.334750] BUG: KASAN: stack-out-of-bounds in find_first_bit+0x19/0x70 [ 13.342166] Read of size 8 at addr ffff880235067178 by task kworker/2:1/42 [ 13.342176] CPU: 2 PID: 42 Comm: kworker/2:1 Not tainted 4.20.0-rc1+ #106 [ 13.342179] Hardware name: Mellanox Technologies Ltd. MSN2740/Mellanox x86 SFF board, BIOS 5.6.5 06/07/2016 [ 13.342190] Workqueue: events deferred_probe_work_func [ 13.342194] Call Trace: [ 13.342206] dump_stack+0xc7/0x15b [ 13.342214] ? show_regs_print_info+0x5/0x5 [ 13.342220] ? kmsg_dump_rewind_nolock+0x59/0x59 [ 13.342234] ? _raw_write_lock_irqsave+0x100/0x100 [ 13.351593] print_address_description+0x73/0x260 [ 13.351603] kasan_report+0x260/0x380 [ 13.351611] ? find_first_bit+0x19/0x70 [ 13.351619] find_first_bit+0x19/0x70 [ 13.351630] mlxreg_hotplug_work_handler+0x73c/0x920 [mlxreg_hotplug] [ 13.351639] ? __lock_text_start+0x8/0x8 [ 13.351646] ? _raw_write_lock_irqsave+0x80/0x100 [ 13.351656] ? mlxreg_hotplug_remove+0x1e0/0x1e0 [mlxreg_hotplug] [ 13.351663] ? regmap_volatile+0x40/0xb0 [ 13.351668] ? regcache_write+0x4c/0x90 [ 13.351676] ? mlxplat_mlxcpld_reg_write+0x24/0x30 [mlx_platform] [ 13.351681] ? _regmap_write+0xea/0x220 [ 13.351688] ? __mutex_lock_slowpath+0x10/0x10 [ 13.351696] ? devm_add_action+0x70/0x70 [ 13.351701] ? mutex_unlock+0x1d/0x40 [ 13.351710] mlxreg_hotplug_probe+0x82e/0x989 [mlxreg_hotplug] [ 13.351723] ? mlxreg_hotplug_work_handler+0x920/0x920 [mlxreg_hotplug] [ 13.351731] ? sysfs_do_create_link_sd.isra.2+0xf4/0x190 [ 13.351737] ? sysfs_rename_link_ns+0xf0/0xf0 [ 13.351743] ? devres_close_group+0x2b0/0x2b0 [ 13.351749] ? pinctrl_put+0x20/0x20 [ 13.351755] ? acpi_dev_pm_attach+0x2c/0xd0 [ 13.351763] platform_drv_probe+0x70/0xd0 [ 13.351771] really_probe+0x480/0x6e0 [ 13.351778] ? device_attach+0x10/0x10 [ 13.351784] ? __lock_text_start+0x8/0x8 [ 13.351790] ? _raw_write_lock_irqsave+0x80/0x100 [ 13.351797] ? _raw_write_lock_irqsave+0x80/0x100 [ 13.351806] ? __driver_attach+0x190/0x190 [ 13.351812] driver_probe_device+0x17d/0x1a0 [ 13.351819] ? __driver_attach+0x190/0x190 [ 13.351825] bus_for_each_drv+0xd6/0x130 [ 13.351831] ? bus_rescan_devices+0x20/0x20 [ 13.351837] ? __mutex_lock_slowpath+0x10/0x10 [ 13.351845] __device_attach+0x18c/0x230 [ 13.351852] ? device_bind_driver+0x70/0x70 [ 13.351859] ? __mutex_lock_slowpath+0x10/0x10 [ 13.351866] bus_probe_device+0xea/0x110 [ 13.351874] deferred_probe_work_func+0x1c9/0x290 [ 13.351882] ? driver_deferred_probe_add+0x1d0/0x1d0 [ 13.351889] ? preempt_notifier_dec+0x20/0x20 [ 13.351897] ? read_word_at_a_time+0xe/0x20 [ 13.351904] ? strscpy+0x151/0x290 [ 13.351912] ? set_work_pool_and_clear_pending+0x9c/0xf0 [ 13.351918] ? __switch_to_asm+0x34/0x70 [ 13.351924] ? __switch_to_asm+0x40/0x70 [ 13.351929] ? __switch_to_asm+0x34/0x70 [ 13.351935] ? __switch_to_asm+0x40/0x70 [ 13.351942] process_one_work+0x5cc/0xa00 [ 13.351952] ? pwq_dec_nr_in_flight+0x1e0/0x1e0 [ 13.351960] ? pci_mmcfg_check_reserved+0x80/0xb8 [ 13.351967] ? run_rebalance_domains+0x250/0x250 [ 13.351980] ? stack_access_ok+0x35/0x80 [ 13.351986] ? deref_stack_reg+0xa1/0xe0 [ 13.351994] ? schedule+0xcd/0x250 [ 13.352000] ? worker_enter_idle+0x2d6/0x330 [ 13.352006] ? __schedule+0xeb0/0xeb0 [ 13.352014] ? fork_usermode_blob+0x130/0x130 [ 13.352019] ? mutex_lock+0xa7/0x100 [ 13.352026] ? _raw_spin_lock_irq+0x98/0xf0 [ 13.352032] ? _raw_read_unlock_irqrestore+0x30/0x30 [ 13.352037] i2c i2c-2: Added multiplexed i2c bus 11 [ 13.352043] worker_thread+0x181/0xa80 [ 13.352052] ? __switch_to_asm+0x34/0x70 [ 13.352058] ? __switch_to_asm+0x40/0x70 [ 13.352064] ? process_one_work+0xa00/0xa00 [ 13.352070] ? __switch_to_asm+0x34/0x70 [ 13.352076] ? __switch_to_asm+0x40/0x70 [ 13.352081] ? __switch_to_asm+0x34/0x70 [ 13.352086] ? __switch_to_asm+0x40/0x70 [ 13.352092] ? __switch_to_asm+0x34/0x70 [ 13.352097] ? __switch_to_asm+0x40/0x70 [ 13.352105] ? __schedule+0x3d6/0xeb0 [ 13.352112] ? migrate_swap_stop+0x470/0x470 [ 13.352119] ? save_stack+0x89/0xb0 [ 13.352127] ? kmem_cache_alloc_trace+0xe5/0x570 [ 13.352132] ? kthread+0x59/0x1d0 [ 13.352138] ? ret_from_fork+0x35/0x40 [ 13.352154] ? __schedule+0xeb0/0xeb0 [ 13.352161] ? remove_wait_queue+0x150/0x150 [ 13.352169] ? _raw_write_lock_irqsave+0x80/0x100 [ 13.352175] ? __lock_text_start+0x8/0x8 [ 13.352183] ? process_one_work+0xa00/0xa00 [ 13.352188] kthread+0x1a4/0x1d0 [ 13.352195] ? kthread_create_worker_on_cpu+0xc0/0xc0 [ 13.352202] ret_from_fork+0x35/0x40
[ 13.353879] The buggy address belongs to the page: [ 13.353885] page:ffffea0008d419c0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 [ 13.353890] flags: 0x2ffff8000000000() [ 13.353897] raw: 02ffff8000000000 ffffea0008d419c8 ffffea0008d419c8 0000000000000000 [ 13.353903] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 [ 13.353905] page dumped because: kasan: bad access detected
[ 13.353908] Memory state around the buggy address: [ 13.353912] ffff880235067000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 13.353917] ffff880235067080: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 [ 13.353921] >ffff880235067100: f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04 [ 13.353923] ^ [ 13.353927] ffff880235067180: f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 00 00 00 00 00 [ 13.353931] ffff880235067200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 13.353933] ==================================================================
The warning is caused by the below loop: for_each_set_bit(bit, (unsigned long *)&asserted, 8) { while "asserted" is declared as 'unsigned'.
The casting of 32-bit unsigned integer pointer to a 64-bit unsigned long pointer. There are two problems here. It causes the access of four extra byte, which can corrupt memory The 32-bit pointer address may not be 64-bit aligned.
The fix changes variable "asserted" to "unsigned long".
Fixes: 1f976f6978bf ("platform/x86: Move Mellanox platform hotplug driver to platform/mellanox") Signed-off-by: Vadim Pasternak vadimp@mellanox.com Signed-off-by: Darren Hart (VMware) dvhart@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/mellanox/mlxreg-hotplug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c index b6d44550d98c..eca16d00e310 100644 --- a/drivers/platform/mellanox/mlxreg-hotplug.c +++ b/drivers/platform/mellanox/mlxreg-hotplug.c @@ -248,7 +248,8 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, struct mlxreg_core_item *item) { struct mlxreg_core_data *data; - u32 asserted, regval, bit; + unsigned long asserted; + u32 regval, bit; int ret;
/* @@ -281,7 +282,7 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, asserted = item->cache ^ regval; item->cache = regval;
- for_each_set_bit(bit, (unsigned long *)&asserted, 8) { + for_each_set_bit(bit, &asserted, 8) { data = item->data + bit; if (regval & BIT(bit)) { if (item->inversed)
From: Dongli Zhang dongli.zhang@oracle.com
[ Upstream commit 758a58d0bc67457f1215321a536226654a830eeb ]
Commit 0da03cab87e6 ("loop: Fix deadlock when calling blkdev_reread_part()") moves blkdev_reread_part() out of the loop_ctl_mutex. However, GENHD_FL_NO_PART_SCAN is set before __blkdev_reread_part(). As a result, __blkdev_reread_part() will fail the check of GENHD_FL_NO_PART_SCAN and will not rescan the loop device to delete all partitions.
Below are steps to reproduce the issue:
step1 # dd if=/dev/zero of=tmp.raw bs=1M count=100 step2 # losetup -P /dev/loop0 tmp.raw step3 # parted /dev/loop0 mklabel gpt step4 # parted -a none -s /dev/loop0 mkpart primary 64s 1 step5 # losetup -d /dev/loop0
Step5 will not be able to delete /dev/loop0p1 (introduced by step4) and there is below kernel warning message:
[ 464.414043] __loop_clr_fd: partition scan of loop0 failed (rc=-22)
This patch sets GENHD_FL_NO_PART_SCAN after blkdev_reread_part().
Fixes: 0da03cab87e6 ("loop: Fix deadlock when calling blkdev_reread_part()") Signed-off-by: Dongli Zhang dongli.zhang@oracle.com Reviewed-by: Jan Kara jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/loop.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c9c2bcc36e26..fc83a8f21ce3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1090,16 +1090,12 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); } mapping_set_gfp_mask(filp->f_mapping, gfp); - lo->lo_state = Lo_unbound; /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); blk_mq_unfreeze_queue(lo->lo_queue);
partscan = lo->lo_flags & LO_FLAGS_PARTSCAN && bdev; lo_number = lo->lo_number; - lo->lo_flags = 0; - if (!part_shift) - lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; loop_unprepare_queue(lo); out_unlock: mutex_unlock(&loop_ctl_mutex); @@ -1121,6 +1117,23 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) /* Device is gone, no point in returning error */ err = 0; } + + /* + * lo->lo_state is set to Lo_unbound here after above partscan has + * finished. + * + * There cannot be anybody else entering __loop_clr_fd() as + * lo->lo_backing_file is already cleared and Lo_rundown state + * protects us from all the other places trying to change the 'lo' + * device. + */ + mutex_lock(&loop_ctl_mutex); + lo->lo_flags = 0; + if (!part_shift) + lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; + lo->lo_state = Lo_unbound; + mutex_unlock(&loop_ctl_mutex); + /* * Need not hold loop_ctl_mutex to fput backing file. * Calling fput holding loop_ctl_mutex triggers a circular
From: Håkon Bugge haakon.bugge@oracle.com
[ Upstream commit 2612d723aadcf8281f9bf8305657129bd9f3cd57 ]
Using CX-3 virtual functions, either from a bare-metal machine or pass-through from a VM, MAD packets are proxied through the PF driver.
Since the VF drivers have separate name spaces for MAD Transaction Ids (TIDs), the PF driver has to re-map the TIDs and keep the book keeping in a cache.
Following the RDMA Connection Manager (CM) protocol, it is clear when an entry has to evicted form the cache. But life is not perfect, remote peers may die or be rebooted. Hence, it's a timeout to wipe out a cache entry, when the PF driver assumes the remote peer has gone.
During workloads where a high number of QPs are destroyed concurrently, excessive amount of CM DREQ retries has been observed
The problem can be demonstrated in a bare-metal environment, where two nodes have instantiated 8 VFs each. This using dual ported HCAs, so we have 16 vPorts per physical server.
64 processes are associated with each vPort and creates and destroys one QP for each of the remote 64 processes. That is, 1024 QPs per vPort, all in all 16K QPs. The QPs are created/destroyed using the CM.
When tearing down these 16K QPs, excessive CM DREQ retries (and duplicates) are observed. With some cat/paste/awk wizardry on the infiniband_cm sysfs, we observe as sum of the 16 vPorts on one of the nodes:
cm_rx_duplicates: dreq 2102 cm_rx_msgs: drep 1989 dreq 6195 rep 3968 req 4224 rtu 4224 cm_tx_msgs: drep 4093 dreq 27568 rep 4224 req 3968 rtu 3968 cm_tx_retries: dreq 23469
Note that the active/passive side is equally distributed between the two nodes.
Enabling pr_debug in cm.c gives tons of:
[171778.814239] <mlx4_ib> mlx4_ib_multiplex_cm_handler: id{slave: 1,sl_cm_id: 0xd393089f} is NULL!
By increasing the CM_CLEANUP_CACHE_TIMEOUT from 5 to 30 seconds, the tear-down phase of the application is reduced from approximately 90 to 50 seconds. Retries/duplicates are also significantly reduced:
cm_rx_duplicates: dreq 2460 [] cm_tx_retries: dreq 3010 req 47
Increasing the timeout further didn't help, as these duplicates and retries stems from a too short CMA timeout, which was 20 (~4 seconds) on the systems. By increasing the CMA timeout to 22 (~17 seconds), the numbers fell down to about 10 for both of them.
Adjustment of the CMA timeout is not part of this commit.
Signed-off-by: Håkon Bugge haakon.bugge@oracle.com Acked-by: Jack Morgenstein jackm@dev.mellanox.co.il Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx4/cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c index fedaf8260105..8c79a480f2b7 100644 --- a/drivers/infiniband/hw/mlx4/cm.c +++ b/drivers/infiniband/hw/mlx4/cm.c @@ -39,7 +39,7 @@
#include "mlx4_ib.h"
-#define CM_CLEANUP_CACHE_TIMEOUT (5 * HZ) +#define CM_CLEANUP_CACHE_TIMEOUT (30 * HZ)
struct id_map_entry { struct rb_node node;
From: Katsuhiro Suzuki katsuhiro@katsuster.net
[ Upstream commit d13501a2bedfbea0983cc868d3f1dc692627f60d ]
Custom approximation of fractional-divider may not need parent clock rate checking. For example Rockchip SoCs work fine using grand parent clock rate even if target rate is greater than parent.
This patch checks parent clock rate only if CLK_SET_RATE_PARENT flag is set.
For detailed example, clock tree of Rockchip I2S audio hardware. - Clock rate of CPLL is 1.2GHz, GPLL is 491.52MHz. - i2s1_div is integer divider can divide N (N is 1~128). Input clock is CPLL or GPLL. Initial divider value is N = 1. Ex) PLL = CPLL, N = 10, i2s1_div output rate is CPLL / 10 = 1.2GHz / 10 = 120MHz - i2s1_frac is fractional divider can divide input to x/y, x and y are 16bit integer.
CPLL --> | selector | ---> i2s1_div -+--> | selector | --> I2S1 MCLK GPLL --> | | ,--------------' | | `--> i2s1_frac ---> | |
Clock mux system try to choose suitable one from i2s1_div and i2s1_frac for master clock (MCLK) of I2S1.
Bad scenario as follows: - Try to set MCLK to 8.192MHz (32kHz audio replay) Candidate setting is - i2s1_div: GPLL / 60 = 8.192MHz i2s1_div candidate is exactly same as target clock rate, so mux choose this clock source. i2s1_div output rate is changed 491.52MHz -> 8.192MHz
- After that try to set to 11.2896MHz (44.1kHz audio replay) Candidate settings are - i2s1_div : CPLL / 107 = 11.214945MHz - i2s1_frac: i2s1_div = 8.192MHz This is because clk_fd_round_rate() thinks target rate (11.2896MHz) is higher than parent rate (i2s1_div = 8.192MHz) and returns parent clock rate.
Above is current upstreamed behavior. Clock mux system choose i2s1_div, but this clock rate is not acceptable for I2S driver, so users cannot replay audio.
Expected behavior is: - Try to set master clock to 11.2896MHz (44.1kHz audio replay) Candidate settings are - i2s1_div : CPLL / 107 = 11.214945MHz - i2s1_frac: i2s1_div * 147/6400 = 11.2896MHz Change i2s1_div to GPLL / 1 = 491.52MHz at same time.
If apply this commit, clk_fd_round_rate() calls custom approximate function of Rockchip even if target rate is higher than parent. Custom function changes both grand parent (i2s1_div) and parent (i2s_frac) settings at same time. Clock mux system can choose i2s1_frac and audio works fine.
Signed-off-by: Katsuhiro Suzuki katsuhiro@katsuster.net Reviewed-by: Heiko Stuebner heiko@sntech.de [sboyd@kernel.org: Make function into a macro instead] Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-fractional-divider.c | 2 +- include/linux/clk-provider.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index fdf625fb10fa..083daa293280 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -77,7 +77,7 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long m, n; u64 ret;
- if (!rate || rate >= *parent_rate) + if (!rate || (!clk_hw_can_set_rate_parent(hw) && rate >= *parent_rate)) return *parent_rate;
if (fd->approximation) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 08b1aa70a38d..d1b6d2c3ada6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -782,6 +782,9 @@ unsigned int __clk_get_enable_count(struct clk *clk); unsigned long clk_hw_get_rate(const struct clk_hw *hw); unsigned long __clk_get_flags(struct clk *clk); unsigned long clk_hw_get_flags(const struct clk_hw *hw); +#define clk_hw_can_set_rate_parent(hw) \ + (clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT) + bool clk_hw_is_prepared(const struct clk_hw *hw); bool clk_hw_rate_is_protected(const struct clk_hw *hw); bool clk_hw_is_enabled(const struct clk_hw *hw);
From: Wei Li liwei391@huawei.com
[ Upstream commit 11db1ad4513d6205d2519e1a30ff4cef746e3243 ]
The output of "perf annotate -l --stdio xxx" changed since commit 425859ff0de33 ("perf annotate: No need to calculate notes->start twice") removed notes->start assignment in symbol__calc_lines(). It will get failed in find_address_in_section() from symbol__tty_annotate() subroutine as the a2l->addr is wrong. So the annotate summary doesn't report the line number of source code correctly.
Before fix:
liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ cat common_while_1.c void hotspot_1(void) { volatile int i;
for (i = 0; i < 0x10000000; i++); for (i = 0; i < 0x10000000; i++); for (i = 0; i < 0x10000000; i++); }
int main(void) { hotspot_1();
return 0; } liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ gcc common_while_1.c -g -o common_while_1
liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ sudo ./perf record ./common_while_1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.488 MB perf.data (12498 samples) ] liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ sudo ./perf annotate -l -s hotspot_1 --stdio
Sorted summary for file /home/liwei/main_code/hulk_work/hulk/tools/perf/common_while_1 ----------------------------------------------
19.30 common_while_1[32] 19.03 common_while_1[4e] 19.01 common_while_1[16] 5.04 common_while_1[13] 4.99 common_while_1[4b] 4.78 common_while_1[2c] 4.77 common_while_1[10] 4.66 common_while_1[2f] 4.59 common_while_1[51] 4.59 common_while_1[35] 4.52 common_while_1[19] 4.20 common_while_1[56] 0.51 common_while_1[48] Percent | Source code & Disassembly of common_while_1 for cycles:ppp (12480 samples, percent: local period) ----------------------------------------------------------------------------------------------------------------- : : : : Disassembly of section .text: : : 00000000000005fa <hotspot_1>: : hotspot_1(): : void hotspot_1(void) : { 0.00 : 5fa: push %rbp 0.00 : 5fb: mov %rsp,%rbp : volatile int i; : : for (i = 0; i < 0x10000000; i++); 0.00 : 5fe: movl $0x0,-0x4(%rbp) 0.00 : 605: jmp 610 <hotspot_1+0x16> 0.00 : 607: mov -0x4(%rbp),%eax common_while_1[10] 4.77 : 60a: add $0x1,%eax common_while_1[13] 5.04 : 60d: mov %eax,-0x4(%rbp) common_while_1[16] 19.01 : 610: mov -0x4(%rbp),%eax common_while_1[19] 4.52 : 613: cmp $0xfffffff,%eax 0.00 : 618: jle 607 <hotspot_1+0xd> : for (i = 0; i < 0x10000000; i++); ...
After fix:
liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ sudo ./perf record ./common_while_1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.488 MB perf.data (12500 samples) ] liwei@euler:~/main_code/hulk_work/hulk/tools/perf$ sudo ./perf annotate -l -s hotspot_1 --stdio
Sorted summary for file /home/liwei/main_code/hulk_work/hulk/tools/perf/common_while_1 ----------------------------------------------
33.34 common_while_1.c:5 33.34 common_while_1.c:6 33.32 common_while_1.c:7 Percent | Source code & Disassembly of common_while_1 for cycles:ppp (12482 samples, percent: local period) ----------------------------------------------------------------------------------------------------------------- : : : : Disassembly of section .text: : : 00000000000005fa <hotspot_1>: : hotspot_1(): : void hotspot_1(void) : { 0.00 : 5fa: push %rbp 0.00 : 5fb: mov %rsp,%rbp : volatile int i; : : for (i = 0; i < 0x10000000; i++); 0.00 : 5fe: movl $0x0,-0x4(%rbp) 0.00 : 605: jmp 610 <hotspot_1+0x16> 0.00 : 607: mov -0x4(%rbp),%eax common_while_1.c:5 4.70 : 60a: add $0x1,%eax 4.89 : 60d: mov %eax,-0x4(%rbp) common_while_1.c:5 19.03 : 610: mov -0x4(%rbp),%eax common_while_1.c:5 4.72 : 613: cmp $0xfffffff,%eax 0.00 : 618: jle 607 <hotspot_1+0xd> : for (i = 0; i < 0x10000000; i++); 0.00 : 61a: movl $0x0,-0x4(%rbp) 0.00 : 621: jmp 62c <hotspot_1+0x32> 0.00 : 623: mov -0x4(%rbp),%eax common_while_1.c:6 4.54 : 626: add $0x1,%eax 4.73 : 629: mov %eax,-0x4(%rbp) common_while_1.c:6 19.54 : 62c: mov -0x4(%rbp),%eax common_while_1.c:6 4.54 : 62f: cmp $0xfffffff,%eax ...
Signed-off-by: Wei Li liwei391@huawei.com Acked-by: Jiri Olsa jolsa@kernel.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Fixes: 425859ff0de33 ("perf annotate: No need to calculate notes->start twice") Link: http://lkml.kernel.org/r/20190221095716.39529-1-liwei391@huawei.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/annotate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 28cd6a17491b..dfee110b3a58 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1862,6 +1862,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, struct annotation_options *options, struct arch **parch) { + struct annotation *notes = symbol__annotation(sym); struct annotate_args args = { .privsize = privsize, .evsel = evsel, @@ -1892,6 +1893,7 @@ int symbol__annotate(struct symbol *sym, struct map *map,
args.ms.map = map; args.ms.sym = sym; + notes->start = map__rip_2objdump(map, sym->start);
return symbol__disassemble(sym, &args); } @@ -2746,8 +2748,6 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *ev
symbol__calc_percent(sym, evsel);
- notes->start = map__rip_2objdump(map, sym->start); - annotation__set_offsets(notes, size); annotation__mark_jump_targets(notes, sym); annotation__compute_ipc(notes, size);
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 8d1667200850f8753c0265fa4bd25c9a6e5f94ce ]
The apq8016 driver leaves the of-node refcount at aborting from the loop of for_each_child_of_node() in the error path. Not only the iterator node of for_each_child_of_node(), the children nodes referred from it for codec and cpu have to be properly unreferenced.
Fixes: bdb052e81f62 ("ASoC: qcom: add apq8016 sound card support") Cc: Patrick Lai plai@codeaurora.org Cc: Banajit Goswami bgoswami@codeaurora.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/qcom/apq8016_sbc.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index 1dd23bba1bed..4b559932adc3 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -164,41 +164,52 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
if (!cpu || !codec) { dev_err(dev, "Can't find cpu/codec DT node\n"); - return ERR_PTR(-EINVAL); + ret = -EINVAL; + goto error; }
link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); if (!link->cpu_of_node) { dev_err(card->dev, "error getting cpu phandle\n"); - return ERR_PTR(-EINVAL); + ret = -EINVAL; + goto error; }
ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); if (ret) { dev_err(card->dev, "error getting cpu dai name\n"); - return ERR_PTR(ret); + goto error; }
ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
if (ret < 0) { dev_err(card->dev, "error getting codec dai name\n"); - return ERR_PTR(ret); + goto error; }
link->platform_of_node = link->cpu_of_node; ret = of_property_read_string(np, "link-name", &link->name); if (ret) { dev_err(card->dev, "error getting codec dai_link name\n"); - return ERR_PTR(ret); + goto error; }
link->stream_name = link->name; link->init = apq8016_sbc_dai_init; link++; + + of_node_put(cpu); + of_node_put(codec); }
return data; + + error: + of_node_put(np); + of_node_put(cpu); + of_node_put(codec); + return ERR_PTR(ret); }
static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = {
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 70b773219a32c7b8f3e53e041bc023ad99fd81f4 ]
Although qcom_snd_parse_of() tries to manage the of-node refcount, there are still a few places that lead to the unblanced refcount in the error code path. Namely,
- for_each_child_of_node() needs to unreference the iterator node if aborting the loop in the middle, - cpu, codec and platform node objects have to be unreferenced at each iteration, - platform and codec node objects have to be referred before jumping to the error handling code that unreference them unconditionally.
This patch tries to address these by moving the assignment of platform and codec node objects to the beginning of the loop and adding the of_node_put() calls adequately.
Fixes: c25e295cd77b ("ASoC: qcom: Add support to parse common audio device nodes") Cc: Patrick Lai plai@codeaurora.org Cc: Banajit Goswami bgoswami@codeaurora.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/qcom/common.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index 4715527054e5..5661025e8cec 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -42,6 +42,9 @@ int qcom_snd_parse_of(struct snd_soc_card *card) link = card->dai_link; for_each_child_of_node(dev->of_node, np) { cpu = of_get_child_by_name(np, "cpu"); + platform = of_get_child_by_name(np, "platform"); + codec = of_get_child_by_name(np, "codec"); + if (!cpu) { dev_err(dev, "Can't find cpu DT node\n"); ret = -EINVAL; @@ -63,8 +66,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card) goto err; }
- platform = of_get_child_by_name(np, "platform"); - codec = of_get_child_by_name(np, "codec"); if (codec && platform) { link->platform_of_node = of_parse_phandle(platform, "sound-dai", @@ -100,10 +101,15 @@ int qcom_snd_parse_of(struct snd_soc_card *card) link->dpcm_capture = 1; link->stream_name = link->name; link++; + + of_node_put(cpu); + of_node_put(codec); + of_node_put(platform); }
return 0; err: + of_node_put(np); of_node_put(cpu); of_node_put(codec); of_node_put(platform);
From: Erwan Velu erwanaliasr1@gmail.com
[ Upstream commit 1222d527f314c86a3b59a522115d62facc5a7965 ]
There is some rare cases where CPB (and possibly IDA) are missing on processors.
This is the case fixed by commit f7f3dc00f612 ("x86/cpu/AMD: Fix erratum 1076 (CPB bit)") and following.
In such context, the boost status isn't reported by /sys/devices/system/cpu/cpufreq/boost.
This commit is about printing a message to report that the CPU doesn't expose the boost capabilities.
This message could help debugging platforms hit by this phenomena.
Signed-off-by: Erwan Velu e.velu@criteo.com [ rjw: Change the message text somewhat ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/acpi-cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index b61f4ec43e06..aca30f45172e 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -911,8 +911,10 @@ static void __init acpi_cpufreq_boost_init(void) { int ret;
- if (!(boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA))) + if (!(boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA))) { + pr_debug("Boost capabilities not present in the processor\n"); return; + }
acpi_cpufreq_driver.set_boost = set_boost; acpi_cpufreq_driver.boost_enabled = boost_state(0);
From: Ross Lagerwall ross.lagerwall@citrix.com
[ Upstream commit 45b14a4ffcc1e0b5caa246638f942cbe7eaea7ad ]
When checking a generic status block, we iterate over all the generic data blocks. The loop condition only checks that the start of the generic data block is valid (within estatus->data_length) but not the whole block. Because the size of data blocks (excluding error data) may vary depending on the revision and the revision is contained within the data block, ensure that enough of the current data block is valid before dereferencing any members otherwise an out-of-bounds access may occur if estatus->data_length is invalid.
This relies on the fact that struct acpi_hest_generic_data_v300 is a superset of the earlier version. Also rework the other checks to avoid potential underflow.
Signed-off-by: Ross Lagerwall ross.lagerwall@citrix.com Acked-by: Borislav Petkov bp@suse.de Tested-by: Tyler Baicar baicar.tyler@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/cper.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index a7902fccdcfa..6090d25dce85 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -546,19 +546,24 @@ EXPORT_SYMBOL_GPL(cper_estatus_check_header); int cper_estatus_check(const struct acpi_hest_generic_status *estatus) { struct acpi_hest_generic_data *gdata; - unsigned int data_len, gedata_len; + unsigned int data_len, record_size; int rc;
rc = cper_estatus_check_header(estatus); if (rc) return rc; + data_len = estatus->data_length;
apei_estatus_for_each_section(estatus, gdata) { - gedata_len = acpi_hest_get_error_length(gdata); - if (gedata_len > data_len - acpi_hest_get_size(gdata)) + if (sizeof(struct acpi_hest_generic_data) > data_len) + return -EINVAL; + + record_size = acpi_hest_get_record_size(gdata); + if (record_size > data_len) return -EINVAL; - data_len -= acpi_hest_get_record_size(gdata); + + data_len -= record_size; } if (data_len) return -EINVAL;
From: Sebastian Ott sebott@linux.ibm.com
[ Upstream commit 0ff06c44efeede4acd068847d3bf8cf894b6c664 ]
Prior to dma unmap/free operations the ism driver tries to ensure that the memory is no longer accessed by the HW. When errors during deregistration of memory regions from the HW occur the ism driver will not unmap/free this memory.
When we receive notification from the hypervisor that a PCI function has been detached we can no longer access the device and would never unmap/free these memory regions which led to complaints by the DMA debug API.
Treat this kind of errors during the deregistration of memory regions from the HW as success since it is already ensured that the memory is no longer accessed by HW.
Reported-by: Karsten Graul kgraul@linux.ibm.com Reported-by: Hans Wippel hwippel@linux.ibm.com Signed-off-by: Sebastian Ott sebott@linux.ibm.com Signed-off-by: Martin Schwidefsky schwidefsky@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/ism_drv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 8684bcec8ff4..00cc96341411 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -141,10 +141,13 @@ static int register_ieq(struct ism_dev *ism)
static int unregister_sba(struct ism_dev *ism) { + int ret; + if (!ism->sba) return 0;
- if (ism_cmd_simple(ism, ISM_UNREG_SBA)) + ret = ism_cmd_simple(ism, ISM_UNREG_SBA); + if (ret && ret != ISM_ERROR) return -EIO;
dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, @@ -158,10 +161,13 @@ static int unregister_sba(struct ism_dev *ism)
static int unregister_ieq(struct ism_dev *ism) { + int ret; + if (!ism->ieq) return 0;
- if (ism_cmd_simple(ism, ISM_UNREG_IEQ)) + ret = ism_cmd_simple(ism, ISM_UNREG_IEQ); + if (ret && ret != ISM_ERROR) return -EIO;
dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, @@ -288,7 +294,7 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb) cmd.request.dmb_tok = dmb->dmb_tok;
ret = ism_cmd(ism, &cmd); - if (ret) + if (ret && ret != ISM_ERROR) goto out;
ism_free_dmb(ism, dmb);
From: Jason Yan yanaijie@huawei.com
[ Upstream commit bcf3b67d16a4c8ffae0aa79de5853435e683945c ]
when create DMA pool for cmd frames failed, we should return -ENOMEM, instead of 0. In some case in:
megasas_init_adapter_fusion()
-->megasas_alloc_cmds() -->megasas_create_frame_pool create DMA pool failed, --> megasas_free_cmds() [1]
-->megasas_alloc_cmds_fusion() failed, then goto fail_alloc_cmds. -->megasas_free_cmds() [2]
we will call megasas_free_cmds twice, [1] will kfree cmd_list, [2] will use cmd_list.it will cause a problem:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffffc000f70000 [00000000] *pgd=0000001fbf893003, *pud=0000001fbf893003, *pmd=0000001fbf894003, *pte=006000006d000707 Internal error: Oops: 96000005 [#1] SMP Modules linked in: CPU: 18 PID: 1 Comm: swapper/0 Not tainted task: ffffffdfb9290000 ti: ffffffdfb923c000 task.ti: ffffffdfb923c000 PC is at megasas_free_cmds+0x30/0x70 LR is at megasas_free_cmds+0x24/0x70 ... Call trace: [<ffffffc0005b779c>] megasas_free_cmds+0x30/0x70 [<ffffffc0005bca74>] megasas_init_adapter_fusion+0x2f4/0x4d8 [<ffffffc0005b926c>] megasas_init_fw+0x2dc/0x760 [<ffffffc0005b9ab0>] megasas_probe_one+0x3c0/0xcd8 [<ffffffc0004a5abc>] local_pci_probe+0x4c/0xb4 [<ffffffc0004a5c40>] pci_device_probe+0x11c/0x14c [<ffffffc00053a5e4>] driver_probe_device+0x1ec/0x430 [<ffffffc00053a92c>] __driver_attach+0xa8/0xb0 [<ffffffc000538178>] bus_for_each_dev+0x74/0xc8 [<ffffffc000539e88>] driver_attach+0x28/0x34 [<ffffffc000539a18>] bus_add_driver+0x16c/0x248 [<ffffffc00053b234>] driver_register+0x6c/0x138 [<ffffffc0004a5350>] __pci_register_driver+0x5c/0x6c [<ffffffc000ce3868>] megasas_init+0xc0/0x1a8 [<ffffffc000082a58>] do_one_initcall+0xe8/0x1ec [<ffffffc000ca7be8>] kernel_init_freeable+0x1c8/0x284 [<ffffffc0008d90b8>] kernel_init+0x1c/0xe4
Signed-off-by: Jason Yan yanaijie@huawei.com Acked-by: Sumit Saxena sumit.saxena@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/megaraid/megaraid_sas_base.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index f6de7526ded5..acb503ea8f0c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4155,6 +4155,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) if (megasas_create_frame_pool(instance)) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n"); megasas_free_cmds(instance); + return -ENOMEM; }
return 0;
From: Sedat Dilek sedat.dilek@gmail.com
[ Upstream commit 8beb90aaf334a6efa3e924339926b5f93a234dbb ]
commit 1917d42d14b7 ("fcoe: use enum for fip_mode") introduces a separate enum for the fip_mode that shall be used during initialisation handling until it is passed to fcoe_ctrl_link_up to set the initial fip_state. That change was incomplete and gcc quietly converted in various places between the fip_mode and the fip_state enum values with implicit enum conversions, which fortunately cannot cause any issues in the actual code's execution.
clang however warns about these implicit enum conversions in the scsi drivers. This commit consolidates the use of the two enums, guided by clang's enum-conversion warnings.
This commit now completes the use of the fip_mode: It expects and uses fip_mode in {bnx2fc,fcoe}_interface_create and fcoe_ctlr_init, and it calls fcoe_ctrl_set_set() with the correct values in fcoe_ctlr_link_up(). It also breaks the association between FIP_MODE_AUTO and FIP_ST_AUTO to indicate these two enums are distinct.
Link: https://github.com/ClangBuiltLinux/linux/issues/151 Fixes: 1917d42d14b7 ("fcoe: use enum for fip_mode") Reported-by: Dmitry Golovin dima@golovin.in Original-by: Lukas Bulwahn lukas.bulwahn@gmail.com CC: Lukas Bulwahn lukas.bulwahn@gmail.com CC: Nick Desaulniers ndesaulniers@google.com CC: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Nathan Chancellor natechancellor@gmail.com Tested-by: Nathan Chancellor natechancellor@gmail.com Suggested-by: Johannes Thumshirn jthumshirn@suse.de Signed-off-by: Sedat Dilek sedat.dilek@gmail.com Signed-off-by: Hannes Reinecke hare@suse.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 2 +- drivers/scsi/fcoe/fcoe.c | 2 +- drivers/scsi/fcoe/fcoe_ctlr.c | 7 +++++-- drivers/scsi/fcoe/fcoe_transport.c | 2 +- drivers/scsi/qedf/qedf_main.c | 2 +- include/scsi/libfcoe.h | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 3f97ec4aac4b..780651c4fc0c 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1445,7 +1445,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) static struct bnx2fc_interface * bnx2fc_interface_create(struct bnx2fc_hba *hba, struct net_device *netdev, - enum fip_state fip_mode) + enum fip_mode fip_mode) { struct fcoe_ctlr_device *ctlr_dev; struct bnx2fc_interface *interface; diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index f46b312d04bc..6768b2e8148a 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -390,7 +390,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, * Returns: pointer to a struct fcoe_interface or NULL on error */ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, - enum fip_state fip_mode) + enum fip_mode fip_mode) { struct fcoe_ctlr_device *ctlr_dev; struct fcoe_ctlr *ctlr; diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 54da3166da8d..7dc4ffa24430 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -147,7 +147,7 @@ static void fcoe_ctlr_map_dest(struct fcoe_ctlr *fip) * fcoe_ctlr_init() - Initialize the FCoE Controller instance * @fip: The FCoE controller to initialize */ -void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode) +void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_mode mode) { fcoe_ctlr_set_state(fip, FIP_ST_LINK_WAIT); fip->mode = mode; @@ -454,7 +454,10 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) mutex_unlock(&fip->ctlr_mutex); fc_linkup(fip->lp); } else if (fip->state == FIP_ST_LINK_WAIT) { - fcoe_ctlr_set_state(fip, fip->mode); + if (fip->mode == FIP_MODE_NON_FIP) + fcoe_ctlr_set_state(fip, FIP_ST_NON_FIP); + else + fcoe_ctlr_set_state(fip, FIP_ST_AUTO); switch (fip->mode) { default: LIBFCOE_FIP_DBG(fip, "invalid mode %d\n", fip->mode); diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index f4909cd206d3..f15d5e1d56b1 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -873,7 +873,7 @@ static int fcoe_transport_create(const char *buffer, int rc = -ENODEV; struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - enum fip_state fip_mode = (enum fip_state)(long)kp->arg; + enum fip_mode fip_mode = (enum fip_mode)kp->arg;
mutex_lock(&ft_mutex);
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 0a5dd5595dd3..cd61905ca2f5 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -1418,7 +1418,7 @@ static struct libfc_function_template qedf_lport_template = {
static void qedf_fcoe_ctlr_setup(struct qedf_ctx *qedf) { - fcoe_ctlr_init(&qedf->ctlr, FIP_ST_AUTO); + fcoe_ctlr_init(&qedf->ctlr, FIP_MODE_AUTO);
qedf->ctlr.send = qedf_fip_send; qedf->ctlr.get_src_addr = qedf_get_src_mac; diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index cb8a273732cf..bb8092fa1e36 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -79,7 +79,7 @@ enum fip_state { * It must not change after fcoe_ctlr_init() sets it. */ enum fip_mode { - FIP_MODE_AUTO = FIP_ST_AUTO, + FIP_MODE_AUTO, FIP_MODE_NON_FIP, FIP_MODE_FABRIC, FIP_MODE_VN2VN, @@ -250,7 +250,7 @@ struct fcoe_rport { };
/* FIP API functions */ -void fcoe_ctlr_init(struct fcoe_ctlr *, enum fip_state); +void fcoe_ctlr_init(struct fcoe_ctlr *, enum fip_mode); void fcoe_ctlr_destroy(struct fcoe_ctlr *); void fcoe_ctlr_link_up(struct fcoe_ctlr *); int fcoe_ctlr_link_down(struct fcoe_ctlr *);
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit d8d2f174bcc2c26c3485c70e0c6fe22b27bce739 ]
[Why] The stream->mode_changed flag can persist in the following sequence of atomic commits:
Commit 1: Enable CRTC0 (mode_changed = true), Enable CRTC1 (mode_changed = true)
Commit 2: Disable CRTC1 (mode_changed = false)
In this sequence we want to keep the exiting CRTC0 but it's not in the atomic state for the commit since it hasn't been modified. In this case the stream->mode_changed flag persists as true and we don't re-program the planes for the existing stream.
[How] The flag needs to be cleared and it makes the most sense to do it within DC after the state has been committed. Nothing following dc_commit_state should think that the stream's mode has changed.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Leo Li sunpeng.li@amd.com Acked-by: Tony Cheng Tony.Cheng@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 9045e6fa0780..bb0cda727605 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -958,6 +958,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c /* pplib is notified if disp_num changed */ dc->hwss.set_bandwidth(dc, context, true);
+ for (i = 0; i < context->stream_count; i++) + context->streams[i]->mode_changed = false; + dc_release_state(dc->current_state);
dc->current_state = context;
From: Thomas Richter tmricht@linux.ibm.com
[ Upstream commit 03d309711d687460d1345de8a0363f45b1c8cd11 ]
Commit 489338a717a0 ("perf tests evsel-tp-sched: Fix bitwise operator") causes test case 14 "Parse sched tracepoints fields" to fail on s390.
This test succeeds on x86.
In fact this test now fails on all architectures with type char treated as type unsigned char.
The root cause is the signed-ness of character arrays in the tracepoints sched_switch for structure members prev_comm and next_comm.
On s390 the output of:
[root@m35lp76 perf]# cat /sys/kernel/debug/tracing/events/sched/sched_switch/format name: sched_switch ID: 287 format: field:unsigned short common_type; offset:0; size:2; signed:0; ... field:char prev_comm[16]; offset:8; size:16; signed:0; ... field:char next_comm[16]; offset:40; size:16; signed:0;
reveals the character arrays prev_comm and next_comm are per default unsigned char and have values in the range of 0..255.
On x86 both fields are signed as this output shows: [root@f29]# cat /sys/kernel/debug/tracing/events/sched/sched_switch/format name: sched_switch ID: 287 format: field:unsigned short common_type; offset:0; size:2; signed:0; ... field:char prev_comm[16]; offset:8; size:16; signed:1; ... field:char next_comm[16]; offset:40; size:16; signed:1;
and the character arrays prev_comm and next_comm are per default signed char and have values in the range of -1..127. The implementation of type char is architecture specific.
Since the character arrays in both tracepoints sched_switch and sched_wakeup should contain ascii characters, simply omit the check for signedness in the test case.
Output before:
[root@m35lp76 perf]# ./perf test -F 14 14: Parse sched tracepoints fields : --- start --- sched:sched_switch: "prev_comm" signedness(0) is wrong, should be 1 sched:sched_switch: "next_comm" signedness(0) is wrong, should be 1 sched:sched_wakeup: "comm" signedness(0) is wrong, should be 1 ---- end ---- 14: Parse sched tracepoints fields : FAILED! [root@m35lp76 perf]#
Output after:
[root@m35lp76 perf]# ./perf test -Fv 14 14: Parse sched tracepoints fields : --- start --- ---- end ---- Parse sched tracepoints fields: Ok [root@m35lp76 perf]#
Fixes: 489338a717a0 ("perf tests evsel-tp-sched: Fix bitwise operator")
Signed-off-by: Thomas Richter tmricht@linux.ibm.com Cc: Heiko Carstens heiko.carstens@de.ibm.com Cc: Hendrik Brueckner brueckner@linux.vnet.ibm.com Cc: Martin Schwidefsky schwidefsky@de.ibm.com Link: http://lkml.kernel.org/r/20190219153639.31267-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/evsel-tp-sched.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 67bcbf876776..d0406116c905 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -43,7 +43,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes return -1; }
- if (perf_evsel__test_field(evsel, "prev_comm", 16, true)) + if (perf_evsel__test_field(evsel, "prev_comm", 16, false)) ret = -1;
if (perf_evsel__test_field(evsel, "prev_pid", 4, true)) @@ -55,7 +55,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes if (perf_evsel__test_field(evsel, "prev_state", sizeof(long), true)) ret = -1;
- if (perf_evsel__test_field(evsel, "next_comm", 16, true)) + if (perf_evsel__test_field(evsel, "next_comm", 16, false)) ret = -1;
if (perf_evsel__test_field(evsel, "next_pid", 4, true)) @@ -73,7 +73,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes return -1; }
- if (perf_evsel__test_field(evsel, "comm", 16, true)) + if (perf_evsel__test_field(evsel, "comm", 16, false)) ret = -1;
if (perf_evsel__test_field(evsel, "pid", 4, true))
From: Brian Norris briannorris@chromium.org
[ Upstream commit 6f21ab30469d670de620f758330aca9f3433f693 ]
As it is, doing something like
# iw phy phy0 interface add foobar type ibss
on a firmware that doesn't have ad-hoc support just yields failures of HostCmd_CMD_SET_BSS_MODE, which happened to return a '-1' error code (-EPERM? not really right...) and sometimes may even crash the firmware along the way.
Let's parse the firmware capability flag while registering the wiphy, so we don't allow attempting IBSS at all, and we get a proper -EOPNOTSUPP from nl80211 instead.
Fixes: e267e71e68ae ("mwifiex: Disable adhoc feature based on firmware capability") Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index adc88433faa8..2d87ebbfa4da 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -4282,11 +4282,13 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy->mgmt_stypes = mwifiex_mgmt_stypes; wiphy->max_remain_on_channel_duration = 5000; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_AP);
+ if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info)) + wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz; if (adapter->config_bands & BAND_A) wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz; @@ -4346,11 +4348,13 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
- wiphy->features |= NL80211_FEATURE_HT_IBSS | - NL80211_FEATURE_INACTIVITY_TIMER | + wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER | NL80211_FEATURE_LOW_PRIORITY_SCAN | NL80211_FEATURE_NEED_OBSS_SCAN;
+ if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info)) + wiphy->features |= NL80211_FEATURE_HT_IBSS; + if (ISSUPP_RANDOM_MAC(adapter->fw_cap_info)) wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR | NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
From: He Kuang hekuang@huawei.com
[ Upstream commit 7346195e8643482968f547483e0d823ec1982fab ]
We can't assume inlined symbols with the same name are equal, because their address range may be different. This will cause the symbols with different addresses be shadowed when adding to the hist entry, and lead to ERANGE error when checking the symbol address during sample parse, the addr should be within the range of [sym.start, sym.end].
The error message is like: "0x36aea60 [0x8]: failed to process type: 68".
The second parameter of symbol__new() is the length of the fake symbol for the inline frame, which is the subtraction of the end and start address of base_sym.
Signed-off-by: He Kuang hekuang@huawei.com Acked-by: Jiri Olsa jolsa@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Milian Wolff milian.wolff@kdab.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Fixes: aa441895f7b4 ("perf report: Compare symbol name for inlined frames when sorting") Link: http://lkml.kernel.org/r/20190219130531.15692-1-hekuang@huawei.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/sort.c | 10 ++++++++-- tools/perf/util/srcline.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b284276ec963..46daa22b86e3 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -229,8 +229,14 @@ static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r) if (sym_l == sym_r) return 0;
- if (sym_l->inlined || sym_r->inlined) - return strcmp(sym_l->name, sym_r->name); + if (sym_l->inlined || sym_r->inlined) { + int ret = strcmp(sym_l->name, sym_r->name); + + if (ret) + return ret; + if ((sym_l->start <= sym_r->end) && (sym_l->end >= sym_r->start)) + return 0; + }
if (sym_l->start != sym_r->start) return (int64_t)(sym_r->start - sym_l->start); diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index e767c4a9d4d2..af3f9b9f1e8b 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -104,7 +104,7 @@ static struct symbol *new_inline_sym(struct dso *dso, } else { /* create a fake symbol for the inline frame */ inline_sym = symbol__new(base_sym ? base_sym->start : 0, - base_sym ? base_sym->end : 0, + base_sym ? (base_sym->end - base_sym->start) : 0, base_sym ? base_sym->binding : 0, base_sym ? base_sym->type : 0, funcname);
From: Wen Yang yellowriver2010@hotmail.com
[ Upstream commit 8fa857da9744f513036df1c43ab57f338941ae7d ]
The of_find_device_by_node() takes a reference to the underlying device structure, we should release that reference.
Detected by coccinelle with the following warnings: ./sound/soc/fsl/imx-sgtl5000.c:169:1-7: ERROR: missing put_device; call of_find_device_by_node on line 105, but without a corresponding object release within this function. ./sound/soc/fsl/imx-sgtl5000.c:177:1-7: ERROR: missing put_device; call of_find_device_by_node on line 105, but without a corresponding object release within this function.
Signed-off-by: Wen Yang yellowriver2010@hotmail.com Cc: Timur Tabi timur@kernel.org Cc: Nicolin Chen nicoleotsuka@gmail.com Cc: Xiubo Li Xiubo.Lee@gmail.com Cc: Fabio Estevam festevam@gmail.com Cc: Liam Girdwood lgirdwood@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: Shawn Guo shawnguo@kernel.org Cc: Sascha Hauer s.hauer@pengutronix.de Cc: Pengutronix Kernel Team kernel@pengutronix.de Cc: NXP Linux Team linux-imx@nxp.com Cc: alsa-devel@alsa-project.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-sgtl5000.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index c29200cf755a..9b9a7ec52905 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -108,6 +108,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) ret = -EPROBE_DEFER; goto fail; } + put_device(&ssi_pdev->dev); codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev) { dev_err(&pdev->dev, "failed to find codec platform device\n");
From: Akinobu Mita akinobu.mita@gmail.com
[ Upstream commit 12aceee1f412c3ddc7750155fec06c906f14ab51 ]
The runtime PM of this device is enabled after v4l2_ctrl_handler_setup(), and this makes this device's runtime PM usage count a negative value.
The ov7740_set_ctrl() tries to do something only if the device's runtime PM usage counter is nonzero.
ov7740_set_ctrl() { if (!pm_runtime_get_if_in_use(&client->dev)) return 0;
<do something>;
pm_runtime_put(&client->dev);
return ret; }
However, the ov7740_set_ctrl() is called by v4l2_ctrl_handler_setup() while the runtime PM of this device is not yet enabled. In this case, the pm_runtime_get_if_in_use() returns -EINVAL (!= 0).
Therefore we can't bail out of this function and the usage count is decreased by pm_runtime_put() without increment.
This fixes this problem by enabling the runtime PM of this device before v4l2_ctrl_handler_setup() so that the ov7740_set_ctrl() is always called when the runtime PM is enabled.
Cc: Wenyou Yang wenyou.yang@microchip.com Signed-off-by: Akinobu Mita akinobu.mita@gmail.com Tested-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/ov7740.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index 605f3e25ad82..f5a1ee90a6c5 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c @@ -1101,6 +1101,9 @@ static int ov7740_probe(struct i2c_client *client, if (ret) return ret;
+ pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + ret = ov7740_detect(ov7740); if (ret) goto error_detect; @@ -1123,8 +1126,6 @@ static int ov7740_probe(struct i2c_client *client, if (ret) goto error_async_register;
- pm_runtime_set_active(&client->dev); - pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev);
return 0; @@ -1134,6 +1135,8 @@ static int ov7740_probe(struct i2c_client *client, error_init_controls: ov7740_free_controls(ov7740); error_detect: + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); ov7740_set_power(ov7740, 0); media_entity_cleanup(&ov7740->subdev.entity);
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 43c145195c7fc3025ee7ecfc67112ac1c82af7c2 ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/sh_veu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 1d274c64de09..03ee9839a03e 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c @@ -273,13 +273,13 @@ static void sh_veu_process(struct sh_veu_dev *veu, static void sh_veu_device_run(void *priv) { struct sh_veu_dev *veu = priv; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf;
src_buf = v4l2_m2m_next_src_buf(veu->m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(veu->m2m_ctx);
if (src_buf && dst_buf) - sh_veu_process(veu, src_buf, dst_buf); + sh_veu_process(veu, &src_buf->vb2_buf, &dst_buf->vb2_buf); }
/* ========== video ioctls ========== */
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 4a88f89885c7cf65c62793f385261a6e3315178a ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 04fd2e0493c0..29daecf8de7d 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -793,14 +793,14 @@ static void skip(struct s5p_jpeg_buffer *buf, long len); static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); struct s5p_jpeg_buffer jpeg_buffer; unsigned int word; int c, x, components;
jpeg_buffer.size = 2; /* Ls */ jpeg_buffer.data = - (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sos + 2; + (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2; jpeg_buffer.curr = 0;
word = 0; @@ -830,14 +830,14 @@ static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx) static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); struct s5p_jpeg_buffer jpeg_buffer; unsigned int word; int c, i, n, j;
for (j = 0; j < ctx->out_q.dht.n; ++j) { jpeg_buffer.size = ctx->out_q.dht.len[j]; - jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) + + jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.dht.marker[j]; jpeg_buffer.curr = 0;
@@ -889,13 +889,13 @@ static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx) static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); struct s5p_jpeg_buffer jpeg_buffer; int c, x, components;
jpeg_buffer.size = ctx->out_q.sof_len; jpeg_buffer.data = - (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sof; + (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sof; jpeg_buffer.curr = 0;
skip(&jpeg_buffer, 5); /* P, Y, X */ @@ -920,14 +920,14 @@ static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx) static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); struct s5p_jpeg_buffer jpeg_buffer; unsigned int word; int c, i, j;
for (j = 0; j < ctx->out_q.dqt.n; ++j) { jpeg_buffer.size = ctx->out_q.dqt.len[j]; - jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) + + jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.dqt.marker[j]; jpeg_buffer.curr = 0;
@@ -2072,15 +2072,15 @@ static void s5p_jpeg_device_run(void *priv) { struct s5p_jpeg_ctx *ctx = priv; struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; unsigned long src_addr, dst_addr, flags;
spin_lock_irqsave(&ctx->jpeg->slock, flags);
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); - dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
s5p_jpeg_reset(jpeg->regs); s5p_jpeg_poweron(jpeg->regs); @@ -2153,7 +2153,7 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; struct s5p_jpeg_fmt *fmt; - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb; struct s5p_jpeg_addr jpeg_addr = {}; u32 pix_size, padding_bytes = 0;
@@ -2172,7 +2172,7 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); }
- jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0); + jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
if (fmt->colplanes == 2) { jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes; @@ -2190,7 +2190,7 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb; unsigned int jpeg_addr = 0;
if (ctx->mode == S5P_JPEG_ENCODE) @@ -2198,7 +2198,7 @@ static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) else vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); if (jpeg->variant->version == SJPEG_EXYNOS5433 && ctx->mode == S5P_JPEG_DECODE) jpeg_addr += ctx->out_q.sos; @@ -2314,7 +2314,7 @@ static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; struct s5p_jpeg_fmt *fmt; - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb; struct s5p_jpeg_addr jpeg_addr = {}; u32 pix_size;
@@ -2328,7 +2328,7 @@ static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) fmt = ctx->cap_q.fmt; }
- jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0); + jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
if (fmt->colplanes == 2) { jpeg_addr.cb = jpeg_addr.y + pix_size; @@ -2346,7 +2346,7 @@ static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) { struct s5p_jpeg *jpeg = ctx->jpeg; - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb; unsigned int jpeg_addr = 0;
if (ctx->mode == S5P_JPEG_ENCODE) @@ -2354,7 +2354,7 @@ static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) else vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0); exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr); }
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit da2d3a4e4adabc6ccfb100bc9abd58ee9cd6c4b7 ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rockchip/rga/rga.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index ab5a6f95044a..86a76f35a9a1 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -43,7 +43,7 @@ static void device_run(void *prv) { struct rga_ctx *ctx = prv; struct rockchip_rga *rga = ctx->rga; - struct vb2_buffer *src, *dst; + struct vb2_v4l2_buffer *src, *dst; unsigned long flags;
spin_lock_irqsave(&rga->ctrl_lock, flags); @@ -53,8 +53,8 @@ static void device_run(void *prv) src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- rga_buf_map(src); - rga_buf_map(dst); + rga_buf_map(&src->vb2_buf); + rga_buf_map(&dst->vb2_buf);
rga_hw_start(rga);
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 30fa627b32230737bc3f678067e2adfecf956987 ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/s5p-g2d/g2d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index e901201b6fcc..1f58574d0b96 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -487,7 +487,7 @@ static void device_run(void *prv) { struct g2d_ctx *ctx = prv; struct g2d_dev *dev = ctx->dev; - struct vb2_buffer *src, *dst; + struct vb2_v4l2_buffer *src, *dst; unsigned long flags; u32 cmd = 0;
@@ -502,10 +502,10 @@ static void device_run(void *prv) spin_lock_irqsave(&dev->ctrl_lock, flags);
g2d_set_src_size(dev, &ctx->in); - g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); + g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0));
g2d_set_dst_size(dev, &ctx->out); - g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); + g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0));
g2d_set_rop4(dev, ctx->rop); g2d_set_flip(dev, ctx->flip);
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 8d20dcefe471763f23ad538369ec65b51993ffff ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mx2_emmaprp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 64195c4ddeaf..419e1cb10dc6 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -274,7 +274,7 @@ static void emmaprp_device_run(void *priv) { struct emmaprp_ctx *ctx = priv; struct emmaprp_q_data *s_q_data, *d_q_data; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; struct emmaprp_dev *pcdev = ctx->dev; unsigned int s_width, s_height; unsigned int d_width, d_height; @@ -294,8 +294,8 @@ static void emmaprp_device_run(void *priv) d_height = d_q_data->height; d_size = d_width * d_height;
- p_in = vb2_dma_contig_plane_dma_addr(src_buf, 0); - p_out = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + p_in = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + p_out = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); if (!p_in || !p_out) { v4l2_err(&pcdev->v4l2_dev, "Acquiring kernel pointers to buffers failed\n");
From: Ezequiel Garcia ezequiel@collabora.com
[ Upstream commit 1b275e4e8b70dbff9850874b30831c1bd8d3c504 ]
Fix the assigned type of mem2mem buffer handling API. Namely, these functions:
v4l2_m2m_next_buf v4l2_m2m_last_buf v4l2_m2m_buf_remove v4l2_m2m_next_src_buf v4l2_m2m_next_dst_buf v4l2_m2m_last_src_buf v4l2_m2m_last_dst_buf v4l2_m2m_src_buf_remove v4l2_m2m_dst_buf_remove
return a struct vb2_v4l2_buffer, and not a struct vb2_buffer.
Fixing this is necessary to fix the mem2mem buffer handling API, changing the return to the correct struct vb2_v4l2_buffer instead of a void pointer.
Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 4f24da8afecc..11429633b2fb 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -702,7 +702,7 @@ static void mtk_jpeg_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); }
-static void *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, +static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, enum v4l2_buf_type type) { if (V4L2_TYPE_IS_OUTPUT(type)) @@ -714,7 +714,7 @@ static void *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, static int mtk_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb; int ret = 0;
ret = pm_runtime_get_sync(ctx->jpeg->dev); @@ -724,14 +724,14 @@ static int mtk_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) return 0; err: while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_QUEUED); + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_QUEUED); return ret; }
static void mtk_jpeg_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); - struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vb;
/* * STREAMOFF is an acknowledgment for source change event. @@ -743,7 +743,7 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) struct mtk_jpeg_src_buf *src_buf;
vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - src_buf = mtk_jpeg_vb2_to_srcbuf(vb); + src_buf = mtk_jpeg_vb2_to_srcbuf(&vb->vb2_buf); mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param); ctx->state = MTK_JPEG_RUNNING; } else if (V4L2_TYPE_IS_OUTPUT(q->type)) { @@ -751,7 +751,7 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) }
while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
pm_runtime_put_sync(ctx->jpeg->dev); } @@ -807,7 +807,7 @@ static void mtk_jpeg_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; struct mtk_jpeg_dev *jpeg = ctx->jpeg; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; unsigned long flags; struct mtk_jpeg_src_buf *jpeg_src_buf; @@ -817,11 +817,11 @@ static void mtk_jpeg_device_run(void *priv)
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) { - for (i = 0; i < dst_buf->num_planes; i++) - vb2_set_plane_payload(dst_buf, i, 0); + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, 0); buf_state = VB2_BUF_STATE_DONE; goto dec_end; } @@ -833,8 +833,8 @@ static void mtk_jpeg_device_run(void *priv) return; }
- mtk_jpeg_set_dec_src(ctx, src_buf, &bs); - if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, dst_buf, &fb)) + mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); + if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) goto dec_end;
spin_lock_irqsave(&jpeg->hw_lock, flags); @@ -849,8 +849,8 @@ static void mtk_jpeg_device_run(void *priv) dec_end: v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state); - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); }
@@ -921,7 +921,7 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) { struct mtk_jpeg_dev *jpeg = priv; struct mtk_jpeg_ctx *ctx; - struct vb2_buffer *src_buf, *dst_buf; + struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_jpeg_src_buf *jpeg_src_buf; enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; u32 dec_irq_ret; @@ -938,7 +938,7 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) mtk_jpeg_dec_reset(jpeg->dec_reg_base); @@ -948,15 +948,15 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) goto dec_end; }
- for (i = 0; i < dst_buf->num_planes; i++) - vb2_set_plane_payload(dst_buf, i, + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, jpeg_src_buf->dec_param.comp_size[i]);
buf_state = VB2_BUF_STATE_DONE;
dec_end: - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state); - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); return IRQ_HANDLED; }
From: Lorenzo Bianconi lorenzo.bianconi@redhat.com
[ Upstream commit b3098121c42caaf3aea239b8655cf52d45be116f ]
Do not call mt76u_queues_deinit routine in mt76u_alloc_queues error path since it will be run in mt76x0u_register_device or mt76x2u_register_device error path. Current implementation triggers the following kernel warning:
[ 67.005516] WARNING: CPU: 2 PID: 761 at lib/refcount.c:187 refcount_sub_and_test_checked+0xa4/0xb8 [ 67.019513] refcount_t: underflow; use-after-free. [ 67.099872] Hardware name: BCM2835 [ 67.106268] Backtrace: [ 67.111584] [<8010c91c>] (dump_backtrace) from [<8010cc00>] (show_stack+0x20/0x24) [ 67.124974] r6:60000013 r5:ffffffff r4:00000000 r3:a50bade6 [ 67.132226] [<8010cbe0>] (show_stack) from [<807ca5f4>] (dump_stack+0xc8/0x114) [ 67.141225] [<807ca52c>] (dump_stack) from [<8011e65c>] (__warn+0xf4/0x120) [ 67.149849] r9:000000bb r8:804d0138 r7:00000009 r6:8099dc84 r5:00000000 r4:b66c7b58 [ 67.160767] [<8011e568>] (__warn) from [<8011e6d0>] (warn_slowpath_fmt+0x48/0x50) [ 67.171436] r9:7f65e128 r8:80d1419c r7:80c0bac4 r6:b97b3044 r5:b7368e00 r4:00000000 [ 67.182433] [<8011e68c>] (warn_slowpath_fmt) from [<804d0138>] (refcount_sub_and_test_checked+0xa4/0xb8) [ 67.195221] r3:80c91c25 r2:8099dc94 [ 67.200370] r4:00000000 [ 67.204397] [<804d0094>] (refcount_sub_and_test_checked) from [<804d0164>] (refcount_dec_and_test_checked+0x18/0x1c) [ 67.218046] r4:b7368e00 r3:00000001 [ 67.223125] [<804d014c>] (refcount_dec_and_test_checked) from [<805db49c>] (usb_free_urb+0x20/0x4c) [ 67.235358] [<805db47c>] (usb_free_urb) from [<7f639804>] (mt76u_buf_free+0x98/0xac [mt76_usb]) [ 67.247302] r4:00000001 r3:00000001 [ 67.252468] [<7f63976c>] (mt76u_buf_free [mt76_usb]) from [<7f639ef8>] (mt76u_queues_deinit+0x44/0x100 [mt76_usb]) [ 67.266102] r8:b8fe8600 r7:b5dac480 r6:b5dace20 r5:00000001 r4:00000000 r3:00000080 [ 67.277132] [<7f639eb4>] (mt76u_queues_deinit [mt76_usb]) from [<7f65c040>] (mt76x0u_cleanup+0x40/0x4c [mt76x0u]) [ 67.290737] r7:b5dac480 r6:b8fe8600 r5:ffffffea r4:b5dace20 [ 67.298069] [<7f65c000>] (mt76x0u_cleanup [mt76x0u]) from [<7f65c564>] (mt76x0u_probe+0x1f0/0x354 [mt76x0u]) [ 67.311174] r4:b5dace20 r3:00000000 [ 67.316312] [<7f65c374>] (mt76x0u_probe [mt76x0u]) from [<805e0b6c>] (usb_probe_interface+0x104/0x240) [ 67.328915] r7:00000000 r6:7f65e034 r5:b6634800 r4:b8fe8620 [ 67.336276] [<805e0a68>] (usb_probe_interface) from [<8056a8bc>] (really_probe+0x224/0x2f8) [ 67.347965] r10:b65f0a00 r9:00000019 r8:7f65e034 r7:80d3e124 r6:00000000 r5:80d3e120 [ 67.359175] r4:b8fe8620 r3:805e0a68 [ 67.364384] [<8056a698>] (really_probe) from [<8056ab60>] (driver_probe_device+0x6c/0x180) [ 67.375974] r10:b65f0a00 r9:7f65e2c0 r8:b8fe8620 r7:00000000 r6:7f65e034 r5:7f65e034 [ 67.387170] r4:b8fe8620 r3:00000000 [ 67.392378] [<8056aaf4>] (driver_probe_device) from [<8056ad54>] (__driver_attach+0xe0/0xe4) [ 67.404097] r9:7f65e2c0 r8:7f65d22c r7:00000000 r6:b8fe8654 r5:7f65e034 r4:b8fe8620 [ 67.415122] [<8056ac74>] (__driver_attach) from [<8056880c>] (bus_for_each_dev+0x68/0xa0) [ 67.426628] r6:8056ac74 r5:7f65e034 r4:00000000 r3:00000027 [ 67.434017] [<805687a4>] (bus_for_each_dev) from [<8056a1cc>] (driver_attach+0x28/0x30) [ 67.445394] r6:80c6ddc8 r5:b7368f80 r4:7f65e034 [ 67.451703] [<8056a1a4>] (driver_attach) from [<80569c24>] (bus_add_driver+0x194/0x21c) [ 67.463081] [<80569a90>] (bus_add_driver) from [<8056b504>] (driver_register+0x8c/0x124) [ 67.474560] r7:80c6ddc8 r6:7f65e034 r5:00000000 r4:7f65e034 [ 67.481964] [<8056b478>] (driver_register) from [<805df510>] (usb_register_driver+0x74/0x140) [ 67.493901] r5:00000000 r4:7f65e000 [ 67.499131] [<805df49c>] (usb_register_driver) from [<7f661024>] (mt76x0_driver_init+0x24/0x1000 [mt76x0u]) [ 67.512258] r9:00000001 r8:7f65e308 r7:00000000 r6:80c08d48 r5:7f661000 r4:7f65e2c0 [ 67.523404] [<7f661000>] (mt76x0_driver_init [mt76x0u]) from [<80102f6c>] (do_one_initcall+0x4c/0x210) [ 67.536142] [<80102f20>] (do_one_initcall) from [<801ae63c>] (do_init_module+0x6c/0x21c) [ 67.547639] r8:7f65e308 r7:80c08d48 r6:b65f0ac0 r5:7f65e2c0 r4:7f65e2c0 [ 67.556129] [<801ae5d0>] (do_init_module) from [<801ad68c>] (load_module+0x1d10/0x2304)
Fixes: b40b15e1521f ("mt76: add usb support to mt76 layer") Signed-off-by: Lorenzo Bianconi lorenzo.bianconi@redhat.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/usb.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 79e59f2379a2..8d40e92fb6f2 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -796,16 +796,9 @@ int mt76u_alloc_queues(struct mt76_dev *dev)
err = mt76u_alloc_rx(dev); if (err < 0) - goto err; - - err = mt76u_alloc_tx(dev); - if (err < 0) - goto err; + return err;
- return 0; -err: - mt76u_queues_deinit(dev); - return err; + return mt76u_alloc_tx(dev); } EXPORT_SYMBOL_GPL(mt76u_alloc_queues);
From: Jeremy Cline jcline@redhat.com
[ Upstream commit 32a7b4cbe93b0a0ef7e63d31ca69ce54736c4412 ]
The hci_dev struct hdev is referenced in work queues and timers started by open() in some protocols. This creates a race between the initialization function and the work or timer which can result hdev being dereferenced while it is still null.
The syzbot report contains a reliable reproducer which causes a null pointer dereference of hdev in hci_uart_write_work() by making the memory allocation for hdev fail.
To fix this, ensure hdev is valid from before calling a protocol's open() until after calling a protocol's close().
Reported-by: syzbot+257790c15bcdef6fe00c@syzkaller.appspotmail.com Signed-off-by: Jeremy Cline jcline@redhat.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_ldisc.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index ea6238ed5c0e..8776906cafca 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -207,11 +207,11 @@ void hci_uart_init_work(struct work_struct *work) err = hci_register_dev(hu->hdev); if (err < 0) { BT_ERR("Can't register HCI device"); + clear_bit(HCI_UART_PROTO_READY, &hu->flags); + hu->proto->close(hu); hdev = hu->hdev; hu->hdev = NULL; hci_free_dev(hdev); - clear_bit(HCI_UART_PROTO_READY, &hu->flags); - hu->proto->close(hu); return; }
@@ -616,6 +616,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, static int hci_uart_register_dev(struct hci_uart *hu) { struct hci_dev *hdev; + int err;
BT_DBG("");
@@ -659,11 +660,22 @@ static int hci_uart_register_dev(struct hci_uart *hu) else hdev->dev_type = HCI_PRIMARY;
+ /* Only call open() for the protocol after hdev is fully initialized as + * open() (or a timer/workqueue it starts) may attempt to reference it. + */ + err = hu->proto->open(hu); + if (err) { + hu->hdev = NULL; + hci_free_dev(hdev); + return err; + } + if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) return 0;
if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); + hu->proto->close(hu); hu->hdev = NULL; hci_free_dev(hdev); return -ENODEV; @@ -683,17 +695,12 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) if (!p) return -EPROTONOSUPPORT;
- err = p->open(hu); - if (err) - return err; - hu->proto = p; set_bit(HCI_UART_PROTO_READY, &hu->flags);
err = hci_uart_register_dev(hu); if (err) { clear_bit(HCI_UART_PROTO_READY, &hu->flags); - p->close(hu); return err; }
From: Oleksandr Andrushchenko oleksandr_andrushchenko@epam.com
[ Upstream commit fa13e665e02874c0a5f4d06d6967ae34a6cb3d6a ]
If there are exported DMA buffers which are still in use and grant device is closed by either normal user-space close or by a signal this leads to the grant device context to be destroyed, thus making it not possible to correctly destroy those exported buffers when they are returned back to gntdev and makes the module crash:
[ 339.617540] [<ffff00000854c0d8>] dmabuf_exp_ops_release+0x40/0xa8 [ 339.617560] [<ffff00000867a6e8>] dma_buf_release+0x60/0x190 [ 339.617577] [<ffff0000082211f0>] __fput+0x88/0x1d0 [ 339.617589] [<ffff000008221394>] ____fput+0xc/0x18 [ 339.617607] [<ffff0000080ed4e4>] task_work_run+0x9c/0xc0 [ 339.617622] [<ffff000008089714>] do_notify_resume+0xfc/0x108
Fix this by referencing gntdev on each DMA buffer export and unreferencing on buffer release.
Signed-off-by: Oleksandr Andrushchenko oleksandr_andrushchenko@epam.com Reviewed-by: Boris Ostrovsky@oracle.com> Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/gntdev-dmabuf.c | 12 +++++++++++- drivers/xen/gntdev-dmabuf.h | 2 +- drivers/xen/gntdev.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c index cba6b586bfbd..d97fcfc5e558 100644 --- a/drivers/xen/gntdev-dmabuf.c +++ b/drivers/xen/gntdev-dmabuf.c @@ -80,6 +80,12 @@ struct gntdev_dmabuf_priv { struct list_head imp_list; /* This is the lock which protects dma_buf_xxx lists. */ struct mutex lock; + /* + * We reference this file while exporting dma-bufs, so + * the grant device context is not destroyed while there are + * external users alive. + */ + struct file *filp; };
/* DMA buffer export support. */ @@ -311,6 +317,7 @@ static void dmabuf_exp_release(struct kref *kref)
dmabuf_exp_wait_obj_signal(gntdev_dmabuf->priv, gntdev_dmabuf); list_del(&gntdev_dmabuf->next); + fput(gntdev_dmabuf->priv->filp); kfree(gntdev_dmabuf); }
@@ -423,6 +430,7 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args) mutex_lock(&args->dmabuf_priv->lock); list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list); mutex_unlock(&args->dmabuf_priv->lock); + get_file(gntdev_dmabuf->priv->filp); return 0;
fail: @@ -834,7 +842,7 @@ long gntdev_ioctl_dmabuf_imp_release(struct gntdev_priv *priv, return dmabuf_imp_release(priv->dmabuf_priv, op.fd); }
-struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void) +struct gntdev_dmabuf_priv *gntdev_dmabuf_init(struct file *filp) { struct gntdev_dmabuf_priv *priv;
@@ -847,6 +855,8 @@ struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void) INIT_LIST_HEAD(&priv->exp_wait_list); INIT_LIST_HEAD(&priv->imp_list);
+ priv->filp = filp; + return priv; }
diff --git a/drivers/xen/gntdev-dmabuf.h b/drivers/xen/gntdev-dmabuf.h index 7220a53d0fc5..3d9b9cf9d5a1 100644 --- a/drivers/xen/gntdev-dmabuf.h +++ b/drivers/xen/gntdev-dmabuf.h @@ -14,7 +14,7 @@ struct gntdev_dmabuf_priv; struct gntdev_priv;
-struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void); +struct gntdev_dmabuf_priv *gntdev_dmabuf_init(struct file *filp);
void gntdev_dmabuf_fini(struct gntdev_dmabuf_priv *priv);
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index b0b02a501167..9d8e02cfd480 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -600,7 +600,7 @@ static int gntdev_open(struct inode *inode, struct file *flip) mutex_init(&priv->lock);
#ifdef CONFIG_XEN_GNTDEV_DMABUF - priv->dmabuf_priv = gntdev_dmabuf_init(); + priv->dmabuf_priv = gntdev_dmabuf_init(flip); if (IS_ERR(priv->dmabuf_priv)) { ret = PTR_ERR(priv->dmabuf_priv); kfree(priv);
From: Aurelien Jarno aurelien@aurel32.net
[ Upstream commit cc4b1242d7e3b42eed73881fc749944146493e4f ]
The preadv2 and pwritev2 syscalls are supposed to emulate the readv and writev syscalls when offset == -1. Therefore the compat code should check for offset before calling do_compat_preadv64 and do_compat_pwritev64. This is the case for the preadv2 and pwritev2 syscalls, but handling of offset == -1 is missing in their 64-bit equivalent.
This patch fixes that, calling do_compat_readv and do_compat_writev when offset == -1. This fixes the following glibc tests on x32: - misc/tst-preadvwritev2 - misc/tst-preadvwritev64v2
Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: H.J. Lu hjl.tools@gmail.com Signed-off-by: Aurelien Jarno aurelien@aurel32.net Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/read_write.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/read_write.c b/fs/read_write.c index 8a2737f0d61d..562974a0616c 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1241,6 +1241,9 @@ COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, const struct compat_iovec __user *,vec, unsigned long, vlen, loff_t, pos, rwf_t, flags) { + if (pos == -1) + return do_compat_readv(fd, vec, vlen, flags); + return do_compat_preadv64(fd, vec, vlen, pos, flags); } #endif @@ -1347,6 +1350,9 @@ COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, const struct compat_iovec __user *,vec, unsigned long, vlen, loff_t, pos, rwf_t, flags) { + if (pos == -1) + return do_compat_writev(fd, vec, vlen, flags); + return do_compat_pwritev64(fd, vec, vlen, pos, flags); } #endif
From: Hong Liu hong.liu@intel.com
[ Upstream commit 0d28f49412405d87d3aae83da255070a46e67627 ]
When performing a warm reset in ishtp bus driver, the ishtp_cl_device will not be removed, its fw_client still points to the already freed ishtp_device.fw_clients array.
Later after driver finishing ishtp client enumeration, this dangling pointer may cause driver to bind the wrong ishtp_cl_device to the new client, causing wrong callback to be called for messages intended for the new client.
This helps in development of firmware where frequent switching of firmwares is required without Linux reboot.
Signed-off-by: Hong Liu hong.liu@intel.com Tested-by: Hongyan Song hongyan.song@intel.com Acked-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index 2623a567ffba..f546635e9ac9 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -623,7 +623,8 @@ int ishtp_cl_device_bind(struct ishtp_cl *cl) spin_lock_irqsave(&cl->dev->device_list_lock, flags); list_for_each_entry(cl_device, &cl->dev->device_list, device_link) { - if (cl_device->fw_client->client_id == cl->fw_client_id) { + if (cl_device->fw_client && + cl_device->fw_client->client_id == cl->fw_client_id) { cl->device = cl_device; rv = 0; break; @@ -683,6 +684,7 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev, spin_lock_irqsave(&ishtp_dev->device_list_lock, flags); list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list, device_link) { + cl_device->fw_client = NULL; if (warm_reset && cl_device->reference_count) continue;
From: Tejun Heo tj@kernel.org
[ Upstream commit b4ff1b44bcd384d22fcbac6ebaf9cc0d33debe50 ]
cgroup_rstat_cpu_pop_updated() is used to traverse the updated cgroups on flush. While it was only visiting updated ones in the subtree, it was visiting @root unconditionally. We can easily check whether @root is updated or not by looking at its ->updated_next just as with the cgroups in the subtree.
* Remove the unnecessary cgroup_parent() test. The system root cgroup is never updated and thus its ->updated_next is always NULL. No need to test whether cgroup_parent() exists in addition to ->updated_next.
* Terminate traverse if ->updated_next is NULL. This can only happen for subtree @root and there's no reason to visit it if it's not marked updated.
This reduces cpu consumption when reading a lot of rstat backed files. In a micro benchmark reading stat from ~1600 cgroups, the sys time was lowered by >40%.
Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/rstat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c index d503d1a9007c..bb95a35e8c2d 100644 --- a/kernel/cgroup/rstat.c +++ b/kernel/cgroup/rstat.c @@ -87,7 +87,6 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos, struct cgroup *root, int cpu) { struct cgroup_rstat_cpu *rstatc; - struct cgroup *parent;
if (pos == root) return NULL; @@ -115,8 +114,8 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos, * However, due to the way we traverse, @pos will be the first * child in most cases. The only exception is @root. */ - parent = cgroup_parent(pos); - if (parent && rstatc->updated_next) { + if (rstatc->updated_next) { + struct cgroup *parent = cgroup_parent(pos); struct cgroup_rstat_cpu *prstatc = cgroup_rstat_cpu(parent, cpu); struct cgroup_rstat_cpu *nrstatc; struct cgroup **nextp; @@ -140,9 +139,12 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos, * updated stat. */ smp_mb(); + + return pos; }
- return pos; + /* only happens for @root */ + return NULL; }
/* see cgroup_rstat_flush() */
From: Theodore Ts'o tytso@mit.edu
[ Upstream commit 538bcaa6261b77e71d37f5596c33127c1a3ec3f7 ]
The jbd2 superblock is lockless now, so there is probably a race condition between writing it so disk and modifing contents of it, which may lead to checksum error. The following race is the one case that we have captured.
jbd2 fsstress jbd2_journal_commit_transaction jbd2_journal_update_sb_log_tail jbd2_write_superblock jbd2_superblock_csum_set jbd2_journal_revoke jbd2_journal_set_features(revork) modify superblock submit_bh(checksum incorrect)
Fix this by locking the buffer head before modifing it. We always write the jbd2 superblock after we modify it, so this just means calling the lock_buffer() a little earlier.
This checksum corruption problem can be reproduced by xfstests generic/475.
Reported-by: zhangyi (F) yi.zhang@huawei.com Suggested-by: Jan Kara jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jbd2/journal.c | 52 ++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 8ef6b6daaa7a..88f2a49338a1 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1356,6 +1356,10 @@ static int journal_reset(journal_t *journal) return jbd2_journal_start_thread(journal); }
+/* + * This function expects that the caller will have locked the journal + * buffer head, and will return with it unlocked + */ static int jbd2_write_superblock(journal_t *journal, int write_flags) { struct buffer_head *bh = journal->j_sb_buffer; @@ -1365,7 +1369,6 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags) trace_jbd2_write_superblock(journal, write_flags); if (!(journal->j_flags & JBD2_BARRIER)) write_flags &= ~(REQ_FUA | REQ_PREFLUSH); - lock_buffer(bh); if (buffer_write_io_error(bh)) { /* * Oh, dear. A previous attempt to write the journal @@ -1424,6 +1427,7 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", tail_block, tail_tid);
+ lock_buffer(journal->j_sb_buffer); sb->s_sequence = cpu_to_be32(tail_tid); sb->s_start = cpu_to_be32(tail_block);
@@ -1454,18 +1458,17 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op) journal_superblock_t *sb = journal->j_superblock;
BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); - read_lock(&journal->j_state_lock); - /* Is it already empty? */ - if (sb->s_start == 0) { - read_unlock(&journal->j_state_lock); + lock_buffer(journal->j_sb_buffer); + if (sb->s_start == 0) { /* Is it already empty? */ + unlock_buffer(journal->j_sb_buffer); return; } + jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n", journal->j_tail_sequence);
sb->s_sequence = cpu_to_be32(journal->j_tail_sequence); sb->s_start = cpu_to_be32(0); - read_unlock(&journal->j_state_lock);
jbd2_write_superblock(journal, write_op);
@@ -1488,9 +1491,8 @@ void jbd2_journal_update_sb_errno(journal_t *journal) journal_superblock_t *sb = journal->j_superblock; int errcode;
- read_lock(&journal->j_state_lock); + lock_buffer(journal->j_sb_buffer); errcode = journal->j_errno; - read_unlock(&journal->j_state_lock); if (errcode == -ESHUTDOWN) errcode = 0; jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode); @@ -1894,28 +1896,27 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
sb = journal->j_superblock;
+ /* Load the checksum driver if necessary */ + if ((journal->j_chksum_driver == NULL) && + INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { + journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); + if (IS_ERR(journal->j_chksum_driver)) { + printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); + journal->j_chksum_driver = NULL; + return 0; + } + /* Precompute checksum seed for all metadata */ + journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, + sizeof(sb->s_uuid)); + } + + lock_buffer(journal->j_sb_buffer); + /* If enabling v3 checksums, update superblock */ if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { sb->s_checksum_type = JBD2_CRC32C_CHKSUM; sb->s_feature_compat &= ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); - - /* Load the checksum driver */ - if (journal->j_chksum_driver == NULL) { - journal->j_chksum_driver = crypto_alloc_shash("crc32c", - 0, 0); - if (IS_ERR(journal->j_chksum_driver)) { - printk(KERN_ERR "JBD2: Cannot load crc32c " - "driver.\n"); - journal->j_chksum_driver = NULL; - return 0; - } - - /* Precompute checksum seed for all metadata */ - journal->j_csum_seed = jbd2_chksum(journal, ~0, - sb->s_uuid, - sizeof(sb->s_uuid)); - } }
/* If enabling v1 checksums, downgrade superblock */ @@ -1927,6 +1928,7 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, sb->s_feature_compat |= cpu_to_be32(compat); sb->s_feature_ro_compat |= cpu_to_be32(ro); sb->s_feature_incompat |= cpu_to_be32(incompat); + unlock_buffer(journal->j_sb_buffer);
return 1; #undef COMPAT_FEATURE_ON
From: Michal Kazior michal@plume.com
[ Upstream commit 5ddb0869bfc1bca6cfc592c74c64a026f936638c ]
I've stumbled upon a kernel crash and the logs pointed me towards the lp5562 driver:
<4>[306013.841294] lp5562 0-0030: Direct firmware load for lp5562 failed with error -2 <4>[306013.894990] lp5562 0-0030: Falling back to user helper ... <3>[306073.924886] lp5562 0-0030: firmware request failed <1>[306073.939456] Unable to handle kernel NULL pointer dereference at virtual address 00000000 <4>[306074.251011] PC is at _raw_spin_lock+0x1c/0x58 <4>[306074.255539] LR is at release_firmware+0x6c/0x138 ...
After taking a look I noticed firmware_release() could be called with either NULL or a dangling pointer.
Fixes: 10c06d178df11 ("leds-lp55xx: support firmware interface") Signed-off-by: Michal Kazior michal@plume.com Signed-off-by: Jacek Anaszewski jacek.anaszewski@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/leds-lp55xx-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index 3d79a6380761..723f2f17497a 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c @@ -201,7 +201,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
if (!fw) { dev_err(dev, "firmware request failed\n"); - goto out; + return; }
/* handling firmware data is chip dependent */ @@ -214,9 +214,9 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
mutex_unlock(&chip->lock);
-out: /* firmware should be released for other channel use */ release_firmware(chip->fw); + chip->fw = NULL; }
static int lp55xx_request_firmware(struct lp55xx_chip *chip)
From: Thomas Richter tmricht@linux.ibm.com
[ Upstream commit 2187d87eacd46f6214ce3dc9cfd7a558375a4153 ]
On IBM z13 machine types 2964 and 2965 the descriptor sizes for sampling and diagnostic sampling entries might be missing in the trailer entry and are set to zero.
This leads to a perf report failure when processing diagnostic sampling entries.
This patch adds missing descriptor sizes when the trailer entry contains zero for these fields.
Output before: [root@s38lp82 perf]# ./perf report --stdio | fgrep Samples 0xabbf0 [0x8]: failed to process type: 68 Error: failed to process sample [root@s38lp82 perf]#
Output after: [root@s38lp82 perf]# ./perf report --stdio | fgrep Samples # Total Lost Samples: 0 # Samples: 3K of event 'SF_CYCLES_BASIC_DIAG' # Samples: 162 of event 'CF_DIAG' [root@s38lp82 perf]#
Fixes: 2b1444f2e28b ("perf report: Add raw report support for s390 auxiliary trace")
Signed-off-by: Thomas Richter tmricht@linux.ibm.com Reviewed-by: Hendrik Brueckner brueckner@linux.ibm.com Cc: Heiko Carstens heiko.carstens@de.ibm.com Cc: Martin Schwidefsky schwidefsky@de.ibm.com Link: http://lkml.kernel.org/r/20190211100627.85714-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/s390-cpumsf.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index aa7f8c11fbb7..910f2621d211 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -294,6 +294,11 @@ static bool s390_cpumsf_validate(int machine_type, *dsdes = 85; *bsdes = 32; break; + case 2964: + case 2965: + *dsdes = 112; + *bsdes = 32; + break; default: /* Illegal trailer entry */ return false;
From: Sara Sharon sara.sharon@intel.com
[ Upstream commit c6ac9f9fb98851f47b978a9476594fc3c477a34d ]
Allocator swaps the pending requests with 0 when it starts working. This means that relying on it n RX path to decide if to move to emergency is not always a good idea, since it may be zero, but there are still a lot of unallocated RBs in the system. Change allocator to decrement the pending requests on real time. It is more expensive since it accesses the atomic variable more times, but it gives the RX path a better idea of the system's status.
Reported-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Sara Sharon sara.sharon@intel.com Fixes: 868a1e863f95 ("iwlwifi: pcie: avoid empty free RB queue") Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index d4a31e014c82..b2905f01b7df 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -502,7 +502,7 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; struct list_head local_empty; - int pending = atomic_xchg(&rba->req_pending, 0); + int pending = atomic_read(&rba->req_pending);
IWL_DEBUG_RX(trans, "Pending allocation requests = %d\n", pending);
@@ -557,11 +557,13 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) i++; }
+ atomic_dec(&rba->req_pending); pending--; + if (!pending) { - pending = atomic_xchg(&rba->req_pending, 0); + pending = atomic_read(&rba->req_pending); IWL_DEBUG_RX(trans, - "Pending allocation requests = %d\n", + "Got more pending allocation requests = %d\n", pending); }
@@ -573,12 +575,15 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) spin_unlock(&rba->lock);
atomic_inc(&rba->req_ready); + }
spin_lock(&rba->lock); /* return unused rbds to the allocator empty list */ list_splice_tail(&local_empty, &rba->rbd_empty); spin_unlock(&rba->lock); + + IWL_DEBUG_RX(trans, "%s, exit.\n", __func__); }
/*
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit cecf3e3e0803462335e25d083345682518097334 ]
This commit refactors the chassis-type detection introduced by commit 53fa1f6e8a59 ("ACPI / video: Only default only_lcd to true on Win8-ready _desktops_") (where desktop means anything without a builtin screen).
The DMI chassis_type is an unsigned integer, so rather then doing a whole bunch of string-compares on it, convert it to an int and feed the result to a switch case.
Note the switch case uses hex values, this is done because the spec uses hex values too. This changes the check for "Main Server Chassis" from checking for 11 decimal to 11 hexadecimal, this is a bug fix, the original check for 11 decimal was wrong.
Fixes: 53fa1f6e8a59 ("ACPI / video: Only default only_lcd to true ...") Signed-off-by: Hans de Goede hdegoede@redhat.com [ rjw: Drop redundant return statements ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpi_video.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index f0b52266b3ac..1ab1460c4a4e 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2124,21 +2124,28 @@ static int __init intel_opregion_present(void) return opregion; }
+/* Check if the chassis-type indicates there is no builtin LCD panel */ static bool dmi_is_desktop(void) { const char *chassis_type; + unsigned long type;
chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); if (!chassis_type) return false;
- if (!strcmp(chassis_type, "3") || /* 3: Desktop */ - !strcmp(chassis_type, "4") || /* 4: Low Profile Desktop */ - !strcmp(chassis_type, "5") || /* 5: Pizza Box */ - !strcmp(chassis_type, "6") || /* 6: Mini Tower */ - !strcmp(chassis_type, "7") || /* 7: Tower */ - !strcmp(chassis_type, "11")) /* 11: Main Server Chassis */ + if (kstrtoul(chassis_type, 10, &type) != 0) + return false; + + switch (type) { + case 0x03: /* Desktop */ + case 0x04: /* Low Profile Desktop */ + case 0x05: /* Pizza Box */ + case 0x06: /* Mini Tower */ + case 0x07: /* Tower */ + case 0x11: /* Main Server Chassis */ return true; + }
return false; }
From: Emil Velikov emil.velikov@collabora.com
[ Upstream commit 8059add0478e29cb641936011a8fcc9ce9fd80be ]
There are cases (in mesa and applications) where one would open the primary node without properly authenticating the client.
Sometimes we don't check if the authentication succeeds, but there's also cases we simply forget to do it.
The former was a case for Mesa where it did not not check the return value of drmGetMagic() [1]. That was fixed recently although, there's the question of older drivers or other apps that exbibit this behaviour.
While omitting the call results in issues as seen in [2] and [3].
In the libva case, libva itself doesn't authenticate the DRM client and the vaGetDisplayDRM documentation doesn't mention if the app should either.
As of today, the official vainfo utility doesn't authenticate.
To workaround issues like these, some users resort to running their apps under sudo. Which admittedly isn't always a good idea.
Since any DRIVER_RENDER driver has sufficient isolation between clients, we can use that, for unauthenticated [primary node] ioctls that require DRM_AUTH. But only if the respective ioctl is tagged as DRM_RENDER_ALLOW.
v2: - Rework/simplify if check (Daniel V) - Add examples to commit messages, elaborate. (Daniel V)
v3: - Use single unlikely (Daniel V)
[1] https://gitlab.freedesktop.org/mesa/mesa/blob/2bc1f5c2e70fe3b4d41f060af9859b... [2] https://lists.freedesktop.org/archives/libva/2016-July/004185.html [3] https://gitlab.freedesktop.org/mesa/kmscube/issues/1 Testcase: igt/core_unauth_vs_render Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Emil Velikov emil.velikov@collabora.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20190114085408.15933-2-emil.l.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_ioctl.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index ba129b64b61f..f8d333f658a4 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -502,6 +502,13 @@ int drm_version(struct drm_device *dev, void *data, return err; }
+static inline bool +drm_render_driver_and_ioctl(const struct drm_device *dev, u32 flags) +{ + return drm_core_check_feature(dev, DRIVER_RENDER) && + (flags & DRM_RENDER_ALLOW); +} + /** * drm_ioctl_permit - Check ioctl permissions against caller * @@ -516,14 +523,19 @@ int drm_version(struct drm_device *dev, void *data, */ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) { + const struct drm_device *dev = file_priv->minor->dev; + /* ROOT_ONLY is only for CAP_SYS_ADMIN */ if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN))) return -EACCES;
- /* AUTH is only for authenticated or render client */ - if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) && - !file_priv->authenticated)) - return -EACCES; + /* AUTH is only for master ... */ + if (unlikely((flags & DRM_AUTH) && drm_is_primary_client(file_priv))) { + /* authenticated ones, or render capable on DRM_RENDER_ALLOW. */ + if (!file_priv->authenticated && + !drm_render_driver_and_ioctl(dev, flags)) + return -EACCES; + }
/* MASTER is only for master or control clients */ if (unlikely((flags & DRM_MASTER) &&
From: Tycho Andersen tycho@tycho.ws
[ Upstream commit 3aa415dd2128e478ea3225b59308766de0e94d6b ]
The get_metadata() test requires real root, so let's skip it if we're not real root.
Note that I used XFAIL here because that's what the test does later if CONFIG_CHEKCKPOINT_RESTORE happens to not be enabled. After looking at the code, there doesn't seem to be a nice way to skip tests defined as TEST(), since there's no return code (I tried exit(KSFT_SKIP), but that didn't work either...). So let's do it this way to be consistent, and easier to fix when someone comes along and fixes it.
Signed-off-by: Tycho Andersen tycho@tycho.ws Acked-by: Kees Cook keescook@chromium.org Signed-off-by: Shuah Khan shuah@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/seccomp/seccomp_bpf.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 83057fa9d391..14cad657bc6a 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -2920,6 +2920,12 @@ TEST(get_metadata) struct seccomp_metadata md; long ret;
+ /* Only real root can get metadata. */ + if (geteuid()) { + XFAIL(return, "get_metadata requires real root"); + return; + } + ASSERT_EQ(0, pipe(pipefd));
pid = fork();
From: Andrea Righi righi.andrea@gmail.com
[ Upstream commit 02106f883cd745523f7766d90a739f983f19e650 ]
Since kprobe breakpoing handler is using bsearch(), probing on this routine can cause recursive breakpoint problem.
int3 ->do_int3() ->ftrace_int3_handler() ->ftrace_location() ->ftrace_location_range() ->bsearch() -> int3
Prohibit probing on bsearch().
Signed-off-by: Andrea Righi righi.andrea@gmail.com Acked-by: Masami Hiramatsu mhiramat@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jiri Olsa jolsa@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Peter Zijlstra peterz@infradead.org Cc: Steven Rostedt rostedt@goodmis.org Cc: Thomas Gleixner tglx@linutronix.de Link: http://lkml.kernel.org/r/154998813406.31052.8791425358974650922.stgit@devbox Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/bsearch.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/lib/bsearch.c b/lib/bsearch.c index 18b445b010c3..82512fe7b33c 100644 --- a/lib/bsearch.c +++ b/lib/bsearch.c @@ -11,6 +11,7 @@
#include <linux/export.h> #include <linux/bsearch.h> +#include <linux/kprobes.h>
/* * bsearch - binary search an array of elements @@ -53,3 +54,4 @@ void *bsearch(const void *key, const void *base, size_t num, size_t size, return NULL; } EXPORT_SYMBOL(bsearch); +NOKPROBE_SYMBOL(bsearch);
From: Masami Hiramatsu mhiramat@kernel.org
[ Upstream commit a39f15b9644fac3f950f522c39e667c3af25c588 ]
Since kprobe itself depends on RCU, probing on RCU debug routine can cause recursive breakpoint bugs.
Prohibit probing on RCU debug routines.
int3 ->do_int3() ->ist_enter() ->RCU_LOCKDEP_WARN() ->debug_lockdep_rcu_enabled() -> int3
Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andrea Righi righi.andrea@gmail.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jiri Olsa jolsa@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Peter Zijlstra peterz@infradead.org Cc: Steven Rostedt rostedt@goodmis.org Cc: Thomas Gleixner tglx@linutronix.de Link: http://lkml.kernel.org/r/154998807741.31052.11229157537816341591.stgit@devbo... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/update.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index 39cb23d22109..81688a133552 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -52,6 +52,7 @@ #include <linux/tick.h> #include <linux/rcupdate_wait.h> #include <linux/sched/isolation.h> +#include <linux/kprobes.h>
#define CREATE_TRACE_POINTS
@@ -253,6 +254,7 @@ int notrace debug_lockdep_rcu_enabled(void) current->lockdep_recursion == 0; } EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); +NOKPROBE_SYMBOL(debug_lockdep_rcu_enabled);
/** * rcu_read_lock_held() - might we be in RCU read-side critical section?
From: Chieh-Min Wang chiehminw@synology.com
[ Upstream commit 13f5251fd17088170c18844534682d9cab5ff5aa ]
For bridge(br_flood) or broadcast/multicast packets, they could clone skb with unconfirmed conntrack which break the rule that unconfirmed skb->_nfct is never shared. With nfqueue running on my system, the race can be easily reproduced with following warning calltrace:
[13257.707525] CPU: 0 PID: 12132 Comm: main Tainted: P W 4.4.60 #7744 [13257.707568] Hardware name: Qualcomm (Flattened Device Tree) [13257.714700] [<c021f6dc>] (unwind_backtrace) from [<c021bce8>] (show_stack+0x10/0x14) [13257.720253] [<c021bce8>] (show_stack) from [<c0449e10>] (dump_stack+0x94/0xa8) [13257.728240] [<c0449e10>] (dump_stack) from [<c022a7e0>] (warn_slowpath_common+0x94/0xb0) [13257.735268] [<c022a7e0>] (warn_slowpath_common) from [<c022a898>] (warn_slowpath_null+0x1c/0x24) [13257.743519] [<c022a898>] (warn_slowpath_null) from [<c06ee450>] (__nf_conntrack_confirm+0xa8/0x618) [13257.752284] [<c06ee450>] (__nf_conntrack_confirm) from [<c0772670>] (ipv4_confirm+0xb8/0xfc) [13257.761049] [<c0772670>] (ipv4_confirm) from [<c06e7a60>] (nf_iterate+0x48/0xa8) [13257.769725] [<c06e7a60>] (nf_iterate) from [<c06e7af0>] (nf_hook_slow+0x30/0xb0) [13257.777108] [<c06e7af0>] (nf_hook_slow) from [<c07f20b4>] (br_nf_post_routing+0x274/0x31c) [13257.784486] [<c07f20b4>] (br_nf_post_routing) from [<c06e7a60>] (nf_iterate+0x48/0xa8) [13257.792556] [<c06e7a60>] (nf_iterate) from [<c06e7af0>] (nf_hook_slow+0x30/0xb0) [13257.800458] [<c06e7af0>] (nf_hook_slow) from [<c07e5580>] (br_forward_finish+0x94/0xa4) [13257.808010] [<c07e5580>] (br_forward_finish) from [<c07f22ac>] (br_nf_forward_finish+0x150/0x1ac) [13257.815736] [<c07f22ac>] (br_nf_forward_finish) from [<c06e8df0>] (nf_reinject+0x108/0x170) [13257.824762] [<c06e8df0>] (nf_reinject) from [<c06ea854>] (nfqnl_recv_verdict+0x3d8/0x420) [13257.832924] [<c06ea854>] (nfqnl_recv_verdict) from [<c06e940c>] (nfnetlink_rcv_msg+0x158/0x248) [13257.841256] [<c06e940c>] (nfnetlink_rcv_msg) from [<c06e5564>] (netlink_rcv_skb+0x54/0xb0) [13257.849762] [<c06e5564>] (netlink_rcv_skb) from [<c06e4ec8>] (netlink_unicast+0x148/0x23c) [13257.858093] [<c06e4ec8>] (netlink_unicast) from [<c06e5364>] (netlink_sendmsg+0x2ec/0x368) [13257.866348] [<c06e5364>] (netlink_sendmsg) from [<c069fb8c>] (sock_sendmsg+0x34/0x44) [13257.874590] [<c069fb8c>] (sock_sendmsg) from [<c06a03dc>] (___sys_sendmsg+0x1ec/0x200) [13257.882489] [<c06a03dc>] (___sys_sendmsg) from [<c06a11c8>] (__sys_sendmsg+0x3c/0x64) [13257.890300] [<c06a11c8>] (__sys_sendmsg) from [<c0209b40>] (ret_fast_syscall+0x0/0x34)
The original code just triggered the warning but do nothing. It will caused the shared conntrack moves to the dying list and the packet be droppped (nf_ct_resolve_clash returns NF_DROP for dying conntrack).
- Reproduce steps:
+----------------------------+ | br0(bridge) | | | +-+---------+---------+------+ | eth0| | eth1| | eth2| | | | | | | +--+--+ +--+--+ +---+-+ | | | | | | +--+-+ +-+--+ +--+-+ | PC1| | PC2| | PC3| +----+ +----+ +----+
iptables -A FORWARD -m mark --mark 0x1000000/0x1000000 -j NFQUEUE --queue-num 100 --queue-bypass
ps: Our nfq userspace program will set mark on packets whose connection has already been processed.
PC1 sends broadcast packets simulated by hping3:
hping3 --rand-source --udp 192.168.1.255 -i u100
- Broadcast racing flow chart is as follow:
br_handle_frame BR_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, br_handle_frame_finish) // skb->_nfct (unconfirmed conntrack) is constructed at PRE_ROUTING stage br_handle_frame_finish // check if this packet is broadcast br_flood_forward br_flood list_for_each_entry_rcu(p, &br->port_list, list) // iterate through each port maybe_deliver deliver_clone skb = skb_clone(skb) __br_forward BR_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD,...) // queue in our nfq and received by our userspace program // goto __nf_conntrack_confirm with process context on CPU 1 br_pass_frame_up BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN,...) // goto __nf_conntrack_confirm with softirq context on CPU 0
Because conntrack confirm can happen at both INPUT and POSTROUTING stage. So with NFQUEUE running, skb->_nfct with the same unconfirmed conntrack could race on different core.
This patch fixes a repeating kernel splat, now it is only displayed once.
Signed-off-by: Chieh-Min Wang chiehminw@synology.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 895171a2e1f1..9a249478abf2 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -901,10 +901,18 @@ __nf_conntrack_confirm(struct sk_buff *skb) * REJECT will give spurious warnings here. */
- /* No external references means no one else could have - * confirmed us. + /* Another skb with the same unconfirmed conntrack may + * win the race. This may happen for bridge(br_flood) + * or broadcast/multicast packets do skb_clone with + * unconfirmed conntrack. */ - WARN_ON(nf_ct_is_confirmed(ct)); + if (unlikely(nf_ct_is_confirmed(ct))) { + WARN_ON_ONCE(1); + nf_conntrack_double_unlock(hash, reply_hash); + local_bh_enable(); + return NF_DROP; + } + pr_debug("Confirming conntrack %p\n", ct); /* We have to check the DYING flag after unlink to prevent * a race against nf_ct_get_next_corpse() possibly called from
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit de9c0d49d85dc563549972edc5589d195cd5e859 ]
While building arm32 allyesconfig, I ran into the following errors:
arch/arm/lib/xor-neon.c:17:2: error: You should compile this file with '-mfloat-abi=softfp -mfpu=neon'
In file included from lib/raid6/neon1.c:27: /home/nathan/cbl/prebuilt/lib/clang/8.0.0/include/arm_neon.h:28:2: error: "NEON support not enabled"
Building V=1 showed NEON_FLAGS getting passed along to Clang but __ARM_NEON__ was not getting defined. Ultimately, it boils down to Clang only defining __ARM_NEON__ when targeting armv7, rather than armv6k, which is the '-march' value for allyesconfig.
From lib/Basic/Targets/ARM.cpp in the Clang source:
// This only gets set when Neon instructions are actually available, unlike // the VFP define, hence the soft float and arch check. This is subtly // different from gcc, we follow the intent which was that it should be set // when Neon instructions are actually available. if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { Builder.defineMacro("__ARM_NEON", "1"); Builder.defineMacro("__ARM_NEON__"); // current AArch32 NEON implementations do not support double-precision // floating-point even when it is present in VFP. Builder.defineMacro("__ARM_NEON_FP", "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); }
Ard Biesheuvel recommended explicitly adding '-march=armv7-a' at the beginning of the NEON_FLAGS definitions so that __ARM_NEON__ always gets definined by Clang. This doesn't functionally change anything because that code will only run where NEON is supported, which is implicitly armv7.
Link: https://github.com/ClangBuiltLinux/linux/issues/287
Suggested-by: Ard Biesheuvel ard.biesheuvel@linaro.org Signed-off-by: Nathan Chancellor natechancellor@gmail.com Acked-by: Nicolas Pitre nico@linaro.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Stefan Agner stefan@agner.ch Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/arm/kernel_mode_neon.txt | 4 ++-- arch/arm/lib/Makefile | 2 +- arch/arm/lib/xor-neon.c | 2 +- lib/raid6/Makefile | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Documentation/arm/kernel_mode_neon.txt b/Documentation/arm/kernel_mode_neon.txt index 525452726d31..b9e060c5b61e 100644 --- a/Documentation/arm/kernel_mode_neon.txt +++ b/Documentation/arm/kernel_mode_neon.txt @@ -6,7 +6,7 @@ TL;DR summary * Use only NEON instructions, or VFP instructions that don't rely on support code * Isolate your NEON code in a separate compilation unit, and compile it with - '-mfpu=neon -mfloat-abi=softfp' + '-march=armv7-a -mfpu=neon -mfloat-abi=softfp' * Put kernel_neon_begin() and kernel_neon_end() calls around the calls into your NEON code * Don't sleep in your NEON code, and be aware that it will be executed with @@ -87,7 +87,7 @@ instructions appearing in unexpected places if no special care is taken. Therefore, the recommended and only supported way of using NEON/VFP in the kernel is by adhering to the following rules: * isolate the NEON code in a separate compilation unit and compile it with - '-mfpu=neon -mfloat-abi=softfp'; + '-march=armv7-a -mfpu=neon -mfloat-abi=softfp'; * issue the calls to kernel_neon_begin(), kernel_neon_end() as well as the calls into the unit containing the NEON code from a compilation unit which is *not* built with the GCC flag '-mfpu=neon' set. diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index ad25fd1872c7..0bff0176db2c 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,7 +39,7 @@ $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
ifeq ($(CONFIG_KERNEL_MODE_NEON),y) - NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon + NEON_FLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon CFLAGS_xor-neon.o += $(NEON_FLAGS) obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o endif diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c index 2c40aeab3eaa..c691b901092f 100644 --- a/arch/arm/lib/xor-neon.c +++ b/arch/arm/lib/xor-neon.c @@ -14,7 +14,7 @@ MODULE_LICENSE("GPL");
#ifndef __ARM_NEON__ -#error You should compile this file with '-mfloat-abi=softfp -mfpu=neon' +#error You should compile this file with '-march=armv7-a -mfloat-abi=softfp -mfpu=neon' #endif
/* diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index 7ed43eaa02ef..5e0d55c54100 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -40,7 +40,7 @@ endif ifeq ($(CONFIG_KERNEL_MODE_NEON),y) NEON_FLAGS := -ffreestanding ifeq ($(ARCH),arm) -NEON_FLAGS += -mfloat-abi=softfp -mfpu=neon +NEON_FLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon endif CFLAGS_recov_neon_inner.o += $(NEON_FLAGS) ifeq ($(ARCH),arm64)
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 29f0023d01f063feacfc404f0446905aee4f82ee ]
According to the Odroid-C1+ schematics the Ethernet TXD1 signal is routed to GPIOH_5 and the TXD0 signal is routed to GPIOH_6. The public S805 datasheet shows that TXD0 can be routed to DIF_2_P and TXD1 can be routed to DIF_2_N instead.
The pin groups eth_txd0_0 (GPIOH_6) and eth_txd0_1 (DIF_2_P) are both configured as Ethernet TXD0 and TXD1 data lines in meson8b.dtsi. At the same time eth_txd1_0 (GPIOH_5) and eth_txd1_1 (DIF_2_N) are configured as TXD0 and TXD1 data lines as well. This results in a bad Ethernet receive performance. Presumably this is due to the eth_txd0 and eth_txd1 signal being routed to the wrong pins. As a result of that data can only be transmitted on eth_txd2 and eth_txd3. However, I have no scope to fully confirm this assumption.
The vendor u-boot sources for Odroid-C1 use the following Ethernet pinmux configuration: SET_CBUS_REG_MASK(PERIPHS_PIN_MUX_6, 0x3f4f); SET_CBUS_REG_MASK(PERIPHS_PIN_MUX_7, 0xf00000); This translates to the following pin groups in the mainline kernel: - register 6 bit 0: eth_rxd1 (DIF_0_P) - register 6 bit 1: eth_rxd0 (DIF_0_N) - register 6 bit 2: eth_rx_dv (DIF_1_P) - register 6 bit 3: eth_rx_clk (DIF_1_N) - register 6 bit 6: eth_tx_en (DIF_3_P) - register 6 bit 8: eth_ref_clk (DIF_3_N) - register 6 bit 9: eth_mdc (DIF_4_P) - register 6 bit 10: eth_mdio_en (DIF_4_N) - register 6 bit 11: eth_tx_clk (GPIOH_9) - register 6 bit 12: eth_txd2 (GPIOH_8) - register 6 bit 13: eth_txd3 (GPIOH_7) - register 7 bit 20: eth_txd0_0 (GPIOH_6) - register 7 bit 21: eth_txd1_0 (GPIOH_5) - register 7 bit 22: eth_rxd3 (DIF_2_P) - register 7 bit 23: eth_rxd2 (DIF_2_N)
Drop the eth_txd0_1 and eth_txd1_1 groups from eth_rgmii_pins to fix the Ethernet transmit performance on Odroid-C1. Also add the eth_rxd2 and eth_rxd3 groups so we don't rely on the bootloader to set them up.
iperf3 statistics before this change: - transmitting from Odroid-C1: 741 Mbits/sec (0 retries) - receiving on Odroid-C1: 199 Mbits/sec (1713 retries)
iperf3 statistics after this change: - transmitting from Odroid-C1: 667 Mbits/sec (0 retries) - receiving on Odroid-C1: 750 Mbits/sec (0 retries)
Fixes: b96446541d8390 ("ARM: dts: meson8b: extend ethernet controller description") Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Cc: Emiliano Ingrassia ingrassia@epigenesys.com Cc: Linus Lüssing linus.luessing@c0d3.blue Tested-by: Emiliano Ingrassia ingrassia@epigenesys.com Reviewed-by: Emiliano Ingrassia ingrassia@epigenesys.com Signed-off-by: Kevin Hilman khilman@baylibre.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/meson8b.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 08f7f6be7254..5b3e5c50c72f 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -207,9 +207,7 @@ groups = "eth_tx_clk", "eth_tx_en", "eth_txd1_0", - "eth_txd1_1", "eth_txd0_0", - "eth_txd0_1", "eth_rx_clk", "eth_rx_dv", "eth_rxd1", @@ -218,7 +216,9 @@ "eth_mdc", "eth_ref_clk", "eth_txd2", - "eth_txd3"; + "eth_txd3", + "eth_rxd3", + "eth_rxd2"; function = "ethernet"; }; };
From: Ranjani Sridharan ranjani.sridharan@linux.intel.com
[ Upstream commit d9c0b2afe820fa3b3f8258a659daee2cc71ca3ef ]
BE dai links only have internal PCM's and their substream ops may not be set. Suspending these PCM's will result in their ops->trigger() being invoked and cause a kernel oops. So skip suspending PCM's if their ops are NULL.
[ NOTE: this change is required now for following the recent PCM core change to get rid of snd_pcm_suspend() call. Since DPCM BE takes the runtime carried from FE while keeping NULL ops, it can hit this bug. See details at: https://github.com/thesofproject/linux/pull/582 -- tiwai ]
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/pcm_native.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 818dff1de545..b6e158ce6650 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1506,6 +1506,14 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) /* FIXME: the open/close code should lock this as well */ if (substream->runtime == NULL) continue; + + /* + * Skip BE dai link PCM's that are internal and may + * not have their substream ops set. + */ + if (!substream->ops) + continue; + err = snd_pcm_suspend(substream); if (err < 0 && err != -EBUSY) return err;
From: Rakesh Pillai pillair@codeaurora.org
[ Upstream commit 1863008369ae0407508033b4b00f98b985adeb15 ]
WCN3990 supports shadow registers write operation support for copy engine for regular operation in powersave mode.
Since WCN3990 is a 64-bit target, the shadow register implementation needs to be done in the copy engine handlers for 64-bit target. Currently the shadow register implementation is present in the 32-bit target handlers of copy engine.
Fix the shadow register copy engine write operation implementation for 64-bit target(WCN3990).
Tested HW: WCN3990 Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1
Fixes: b7ba83f7c414 ("ath10k: add support for shadow register for WNC3990") Signed-off-by: Rakesh Pillai pillair@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/ce.c | 26 +++++++++++++------------- drivers/net/wireless/ath/ath10k/ce.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 18c709c484e7..f761d651c16e 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -500,14 +500,8 @@ static int _ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
/* WORKAROUND */ - if (!(flags & CE_SEND_FLAG_GATHER)) { - if (ar->hw_params.shadow_reg_support) - ath10k_ce_shadow_src_ring_write_index_set(ar, ce_state, - write_index); - else - ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, - write_index); - } + if (!(flags & CE_SEND_FLAG_GATHER)) + ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
src_ring->write_index = write_index; exit: @@ -581,8 +575,14 @@ static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state, /* Update Source Ring Write Index */ write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
- if (!(flags & CE_SEND_FLAG_GATHER)) - ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index); + if (!(flags & CE_SEND_FLAG_GATHER)) { + if (ar->hw_params.shadow_reg_support) + ath10k_ce_shadow_src_ring_write_index_set(ar, ce_state, + write_index); + else + ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, + write_index); + }
src_ring->write_index = write_index; exit: @@ -1394,12 +1394,12 @@ static int ath10k_ce_alloc_shadow_base(struct ath10k *ar, u32 nentries) { src_ring->shadow_base_unaligned = kcalloc(nentries, - sizeof(struct ce_desc), + sizeof(struct ce_desc_64), GFP_KERNEL); if (!src_ring->shadow_base_unaligned) return -ENOMEM;
- src_ring->shadow_base = (struct ce_desc *) + src_ring->shadow_base = (struct ce_desc_64 *) PTR_ALIGN(src_ring->shadow_base_unaligned, CE_DESC_RING_ALIGN); return 0; @@ -1453,7 +1453,7 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, ret = ath10k_ce_alloc_shadow_base(ar, src_ring, nentries); if (ret) { dma_free_coherent(ar->dev, - (nentries * sizeof(struct ce_desc) + + (nentries * sizeof(struct ce_desc_64) + CE_DESC_RING_ALIGN), src_ring->base_addr_owner_space_unaligned, base_addr); diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index b8fb5382dede..8088f7a66426 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -118,7 +118,7 @@ struct ath10k_ce_ring { u32 base_addr_ce_space;
char *shadow_base_unaligned; - struct ce_desc *shadow_base; + struct ce_desc_64 *shadow_base;
/* keep last */ void *per_transfer_context[0];
From: John Stultz john.stultz@linaro.org
[ Upstream commit 54f64d5c983f939901dacc8cfc0983727c5c742e ]
Since the 5.0 merge window opened, I've been seeing frequent crashes on suspend and reboot with the trace:
[ 36.911170] Unable to handle kernel paging request at virtual address ffffff801153d660 [ 36.912769] Unable to handle kernel paging request at virtual address ffffff800004b564 ... [ 36.950666] Call trace: [ 36.950670] queued_spin_lock_slowpath+0x1cc/0x2c8 [ 36.950681] _raw_spin_lock_irqsave+0x64/0x78 [ 36.950692] complete+0x28/0x70 [ 36.950703] ffs_epfile_io_complete+0x3c/0x50 [ 36.950713] usb_gadget_giveback_request+0x34/0x108 [ 36.950721] dwc3_gadget_giveback+0x50/0x68 [ 36.950723] dwc3_thread_interrupt+0x358/0x1488 [ 36.950731] irq_thread_fn+0x30/0x88 [ 36.950734] irq_thread+0x114/0x1b0 [ 36.950739] kthread+0x104/0x130 [ 36.950747] ret_from_fork+0x10/0x1c
I isolated this down to in ffs_epfile_io(): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv...
Where the completion done is setup on the stack: DECLARE_COMPLETION_ONSTACK(done);
Then later we setup a request and queue it, and wait for it: if (unlikely(wait_for_completion_interruptible(&done))) { /* * To avoid race condition with ffs_epfile_io_complete, * dequeue the request first then check * status. usb_ep_dequeue API should guarantee no race * condition with req->complete callback. */ usb_ep_dequeue(ep->ep, req); interrupted = ep->status < 0; }
The problem is, that we end up being interrupted, dequeue the request, and exit.
But then the irq triggers and we try calling complete() on the context pointer which points to now random stack space, which results in the panic.
Alan Stern pointed out there is a bug here, in that the snippet above "assumes that usb_ep_dequeue() waits until the request has been completed." And that:
wait_for_completion(&done);
Is needed right after the usb_ep_dequeue().
Thus this patch implements that change. With it I no longer see the crashes on suspend or reboot.
This issue seems to have been uncovered by behavioral changes in the dwc3 driver in commit fec9095bdef4e ("usb: dwc3: gadget: remove wait_end_transfer").
Cc: Alan Stern stern@rowland.harvard.edu Cc: Felipe Balbi balbi@kernel.org Cc: Zeng Tao prime.zeng@hisilicon.com Cc: Jack Pham jackp@codeaurora.org Cc: Thinh Nguyen thinh.nguyen@synopsys.com Cc: Chen Yu chenyu56@huawei.com Cc: Jerry Zhang zhangjerry@google.com Cc: Lars-Peter Clausen lars@metafoo.de Cc: Vincent Pelletier plr.vincent@gmail.com Cc: Andrzej Pietrasiewicz andrzej.p@samsung.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Linux USB List linux-usb@vger.kernel.org Suggested-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: John Stultz john.stultz@linaro.org Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_fs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 31e8bf3578c8..aa15593a3ac4 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1008,6 +1008,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) * condition with req->complete callback. */ usb_ep_dequeue(ep->ep, req); + wait_for_completion(&done); interrupted = ep->status < 0; }
From: Luc Van Oostenryck luc.vanoostenryck@gmail.com
[ Upstream commit 99687cdbb3f6c8e32bcc7f37496e811f30460e48 ]
The percpu members of struct sd_data and s_data are declared as:
struct ... ** __percpu member;
So their type is:
__percpu pointer to pointer to struct ...
But looking at how they're used, their type should be:
pointer to __percpu pointer to struct ...
and they should thus be declared as:
struct ... * __percpu *member;
So fix the placement of '__percpu' in the definition of these structures.
This addresses a bunch of Sparse's warnings like:
warning: incorrect type in initializer (different address spaces) expected void const [noderef] asn:3 *__vpp_verify got struct sched_domain **
Signed-off-by: Luc Van Oostenryck luc.vanoostenryck@gmail.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/20190118144936.79158-1-luc.vanoostenryck@gmail.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/topology.h | 8 ++++---- kernel/sched/topology.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 26347741ba50..15f3f61f7e3b 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -177,10 +177,10 @@ typedef int (*sched_domain_flags_f)(void); #define SDTL_OVERLAP 0x01
struct sd_data { - struct sched_domain **__percpu sd; - struct sched_domain_shared **__percpu sds; - struct sched_group **__percpu sg; - struct sched_group_capacity **__percpu sgc; + struct sched_domain *__percpu *sd; + struct sched_domain_shared *__percpu *sds; + struct sched_group *__percpu *sg; + struct sched_group_capacity *__percpu *sgc; };
struct sched_domain_topology_level { diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 505a41c42b96..c0a751464971 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -477,7 +477,7 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu) }
struct s_data { - struct sched_domain ** __percpu sd; + struct sched_domain * __percpu *sd; struct root_domain *rd; };
From: Coly Li colyli@suse.de
[ Upstream commit a91fbda49f746119828f7e8ad0f0aa2ab0578f65 ]
Cache set sysfs entry io_error_halflife is used to set c->error_decay. c->error_decay is in type unsigned int, and it is converted by strtoul_or_return(), therefore overflow to c->error_decay is possible for a large input value.
This patch fixes the overflow by using strtoul_safe_clamp() to convert input string to an unsigned long value in range [0, UINT_MAX], then divides by 88 and set it to c->error_decay.
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/sysfs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 26f035a0c5b9..59bf13faf752 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -766,8 +766,17 @@ STORE(__bch_cache_set) c->error_limit = strtoul_or_return(buf);
/* See count_io_errors() for why 88 */ - if (attr == &sysfs_io_error_halflife) - c->error_decay = strtoul_or_return(buf) / 88; + if (attr == &sysfs_io_error_halflife) { + unsigned long v = 0; + ssize_t ret; + + ret = strtoul_safe_clamp(buf, v, 0, UINT_MAX); + if (!ret) { + c->error_decay = v / 88; + return size; + } + return ret; + }
if (attr == &sysfs_io_disable) { v = strtoul_or_return(buf);
From: Coly Li colyli@suse.de
[ Upstream commit 8c27a3953e92eb0b22dbb03d599f543a05f9574e ]
People may set sequential_cutoff of a cached device via sysfs file, but current code does not check input value overflow. E.g. if value 4294967295 (UINT_MAX) is written to file sequential_cutoff, its value is 4GB, but if 4294967296 (UINT_MAX + 1) is written into, its value will be 0. This is an unexpected behavior.
This patch replaces d_strtoi_h() by sysfs_strtoul_clamp() to convert input string to unsigned integer value, and limit its range in [0, UINT_MAX]. Then the input overflow can be fixed.
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 59bf13faf752..01c7c4452a26 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -295,7 +295,9 @@ STORE(__cached_dev) dc->io_disable = v ? 1 : 0; }
- d_strtoi_h(sequential_cutoff); + sysfs_strtoul_clamp(sequential_cutoff, + dc->sequential_cutoff, + 0, UINT_MAX); d_strtoi_h(readahead);
if (attr == &sysfs_clear_stats)
From: Coly Li colyli@suse.de
[ Upstream commit c3b75a2199cdbfc1c335155fe143d842604b1baa ]
dc->writeback_rate_i_term_inverse can be set via sysfs interface. It is in type unsigned int, and convert from input string by d_strtoul(). The problem is d_strtoul() does not check valid range of the input, if 4294967296 is written into sysfs file writeback_rate_i_term_inverse, an overflow of unsigned integer will happen and value 0 is set to dc->writeback_rate_i_term_inverse.
In writeback.c:__update_writeback_rate(), there are following lines of code, integral_scaled = div_s64(dc->writeback_rate_integral, dc->writeback_rate_i_term_inverse); If dc->writeback_rate_i_term_inverse is set to 0 via sysfs interface, a div-zero error might be triggered in the above code.
Therefore we need to add a range limitation in the sysfs interface, this is what this patch does, use sysfs_stroul_clamp() to replace d_strtoul() and restrict the input range in [1, UINT_MAX].
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 01c7c4452a26..503ad954ccc0 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -283,7 +283,9 @@ STORE(__cached_dev) sysfs_strtoul_clamp(writeback_rate_update_seconds, dc->writeback_rate_update_seconds, 1, WRITEBACK_RATE_UPDATE_SECS_MAX); - d_strtoul(writeback_rate_i_term_inverse); + sysfs_strtoul_clamp(writeback_rate_i_term_inverse, + dc->writeback_rate_i_term_inverse, + 1, UINT_MAX); d_strtoul_nonzero(writeback_rate_p_term_inverse); d_strtoul_nonzero(writeback_rate_minimum);
From: Coly Li colyli@suse.de
[ Upstream commit 596b5a5dd1bc2fa019fdaaae522ef331deef927f ]
Currently sysfs_strtoul_clamp() is defined as, 82 #define sysfs_strtoul_clamp(file, var, min, max) \ 83 do { \ 84 if (attr == &sysfs_ ## file) \ 85 return strtoul_safe_clamp(buf, var, min, max) \ 86 ?: (ssize_t) size; \ 87 } while (0)
The problem is, if bit width of var is less then unsigned long, min and max may not protect var from integer overflow, because overflow happens in strtoul_safe_clamp() before checking min and max.
To fix such overflow in sysfs_strtoul_clamp(), to make min and max take effect, this patch adds an unsigned long variable, and uses it to macro strtoul_safe_clamp() to convert an unsigned long value in range defined by [min, max]. Then assign this value to var. By this method, if bit width of var is less than unsigned long, integer overflow won't happen before min and max are checking.
Now sysfs_strtoul_clamp() can properly handle smaller data type like unsigned int, of cause min and max should be defined in range of unsigned int too.
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/sysfs.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/md/bcache/sysfs.h b/drivers/md/bcache/sysfs.h index 3fe82425859c..0ad2715a884e 100644 --- a/drivers/md/bcache/sysfs.h +++ b/drivers/md/bcache/sysfs.h @@ -81,9 +81,16 @@ do { \
#define sysfs_strtoul_clamp(file, var, min, max) \ do { \ - if (attr == &sysfs_ ## file) \ - return strtoul_safe_clamp(buf, var, min, max) \ - ?: (ssize_t) size; \ + if (attr == &sysfs_ ## file) { \ + unsigned long v = 0; \ + ssize_t ret; \ + ret = strtoul_safe_clamp(buf, v, min, max); \ + if (!ret) { \ + var = v; \ + return size; \ + } \ + return ret; \ + } \ } while (0)
#define strtoul_or_return(cp) \
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 1136b0728969901a091f0471968b2b76ed14d9ad ]
Waiman reported that on large systems with a large amount of interrupts the readout of /proc/stat takes a long time to sum up the interrupt statistics. In principle this is not a problem. but for unknown reasons some enterprise quality software reads /proc/stat with a high frequency.
The reason for this is that interrupt statistics are accounted per cpu. So the /proc/stat logic has to sum up the interrupt stats for each interrupt.
This can be largely avoided for interrupts which are not marked as 'PER_CPU' interrupts by simply adding a per interrupt summation counter which is incremented along with the per interrupt per cpu counter.
The PER_CPU interrupts need to avoid that and use only per cpu accounting because they share the interrupt number and the interrupt descriptor and concurrent updates would conflict or require unwanted synchronization.
Reported-by: Waiman Long longman@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Waiman Long longman@redhat.com Reviewed-by: Marc Zyngier marc.zyngier@arm.com Reviewed-by: Davidlohr Bueso dbueso@suse.de Cc: Matthew Wilcox willy@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Kees Cook keescook@chromium.org Cc: linux-fsdevel@vger.kernel.org Cc: Davidlohr Bueso dave@stgolabs.net Cc: Miklos Szeredi miklos@szeredi.hu Cc: Daniel Colascione dancol@google.com Cc: Dave Chinner david@fromorbit.com Cc: Randy Dunlap rdunlap@infradead.org Link: https://lkml.kernel.org/r/20190208135020.925487496@linutronix.de
8<-------------
v2: Undo the unintentional layout change of struct irq_desc.
include/linux/irqdesc.h | 1 + kernel/irq/chip.c | 12 ++++++++++-- kernel/irq/internals.h | 8 +++++++- kernel/irq/irqdesc.c | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-)
Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/irqdesc.h | 1 + kernel/irq/chip.c | 12 ++++++++++-- kernel/irq/internals.h | 8 +++++++- kernel/irq/irqdesc.c | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index dd1e40ddac7d..875c41b23f20 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -65,6 +65,7 @@ struct irq_desc { unsigned int core_internal_state__do_not_mess_with_it; unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ + unsigned int tot_count; unsigned int irq_count; /* For detecting broken IRQs */ unsigned long last_unhandled; /* Aging timer for unhandled count */ unsigned int irqs_unhandled; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index a2b3d9de999c..811009ebacd4 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -855,7 +855,11 @@ void handle_percpu_irq(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc);
- kstat_incr_irqs_this_cpu(desc); + /* + * PER CPU interrupts are not serialized. Do not touch + * desc->tot_count. + */ + __kstat_incr_irqs_this_cpu(desc);
if (chip->irq_ack) chip->irq_ack(&desc->irq_data); @@ -884,7 +888,11 @@ void handle_percpu_devid_irq(struct irq_desc *desc) unsigned int irq = irq_desc_get_irq(desc); irqreturn_t res;
- kstat_incr_irqs_this_cpu(desc); + /* + * PER CPU interrupts are not serialized. Do not touch + * desc->tot_count. + */ + __kstat_incr_irqs_this_cpu(desc);
if (chip->irq_ack) chip->irq_ack(&desc->irq_data); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index ca6afa267070..e74e7eea76cf 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -242,12 +242,18 @@ static inline void irq_state_set_masked(struct irq_desc *desc)
#undef __irqd_to_state
-static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) +static inline void __kstat_incr_irqs_this_cpu(struct irq_desc *desc) { __this_cpu_inc(*desc->kstat_irqs); __this_cpu_inc(kstat.irqs_sum); }
+static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) +{ + __kstat_incr_irqs_this_cpu(desc); + desc->tot_count++; +} + static inline int irq_desc_get_node(struct irq_desc *desc) { return irq_common_data_get_node(&desc->irq_common_data); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 578d0e5f1b5b..ba454cba4069 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -119,6 +119,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, desc->depth = 1; desc->irq_count = 0; desc->irqs_unhandled = 0; + desc->tot_count = 0; desc->name = NULL; desc->owner = owner; for_each_possible_cpu(cpu) @@ -915,11 +916,15 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) unsigned int kstat_irqs(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); - int cpu; unsigned int sum = 0; + int cpu;
if (!desc || !desc->kstat_irqs) return 0; + if (!irq_settings_is_per_cpu_devid(desc) && + !irq_settings_is_per_cpu(desc)) + return desc->tot_count; + for_each_possible_cpu(cpu) sum += *per_cpu_ptr(desc->kstat_irqs, cpu); return sum;
From: Russell King rmk+kernel@armlinux.org.uk
[ Upstream commit 316734fdcf70900a83065360cff11a5826919067 ]
It appears that the mvpp22 can get stuck with SGMII negotiation. The symptoms are that in-band negotiation never completes and the partner (eg, PHY) never reports SGMII link up, or if it supports negotiation bypass, goes into negotiation bypass mode (which will happen when the PHY sees that the MAC is alive but gets no response.)
Triggering the PHY end of the link to re-negotiate results in the bypass bit clearing on the PHY, and then re-setting - indicating that the problem is at the mvpp22 GMAC end.
Asserting the GMAC reset and de-asserting it resolves the issue. Arrange to assert the GMAC reset at probe time, and deassert it only after we have configured the GMAC for the appropriate mode. This resolves the issue.
Tested-by: Sven Auhagen sven.auhagen@voleatech.de Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index f8e4808a8317..9988c89ed9fd 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1372,13 +1372,9 @@ static void mvpp2_port_reset(struct mvpp2_port *port) for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++) mvpp2_read_count(port, &mvpp2_ethtool_regs[i]);
- val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) & - ~MVPP2_GMAC_PORT_RESET_MASK; + val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) | + MVPP2_GMAC_PORT_RESET_MASK; writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); - - while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) & - MVPP2_GMAC_PORT_RESET_MASK) - continue; }
/* Change maximum receive size of the port */ @@ -4445,12 +4441,15 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode, const struct phylink_link_state *state) { u32 an, ctrl0, ctrl2, ctrl4; + u32 old_ctrl2;
an = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG); ctrl0 = readl(port->base + MVPP2_GMAC_CTRL_0_REG); ctrl2 = readl(port->base + MVPP2_GMAC_CTRL_2_REG); ctrl4 = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
+ old_ctrl2 = ctrl2; + /* Force link down */ an &= ~MVPP2_GMAC_FORCE_LINK_PASS; an |= MVPP2_GMAC_FORCE_LINK_DOWN; @@ -4523,6 +4522,12 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode, writel(ctrl2, port->base + MVPP2_GMAC_CTRL_2_REG); writel(ctrl4, port->base + MVPP22_GMAC_CTRL_4_REG); writel(an, port->base + MVPP2_GMAC_AUTONEG_CONFIG); + + if (old_ctrl2 & MVPP2_GMAC_PORT_RESET_MASK) { + while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) & + MVPP2_GMAC_PORT_RESET_MASK) + continue; + } }
static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
From: Raju Rangoju rajur@chelsio.com
[ Upstream commit f368ff188ae4b3ef6f740a15999ea0373261b619 ]
When an application aborts the connection by moving QP from RTS to ERROR, then iw_cxgb4's modify_rc_qp() RTS->ERROR logic sets the *srqidxp to 0 via t4_set_wq_in_error(&qhp->wq, 0), and aborts the connection by calling c4iw_ep_disconnect().
c4iw_ep_disconnect() does the following: 1. sends up a close_complete_upcall(ep, -ECONNRESET) to libcxgb4. 2. sends abort request CPL to hw.
But, since the close_complete_upcall() is sent before sending the ABORT_REQ to hw, libcxgb4 would fail to release the srqidx if the connection holds one. Because, the srqidx is passed up to libcxgb4 only after corresponding ABORT_RPL is processed by kernel in abort_rpl().
This patch handle the corner-case by moving the call to close_complete_upcall() from c4iw_ep_disconnect() to abort_rpl(). So that libcxgb4 is notified about the -ECONNRESET only after abort_rpl(), and libcxgb4 can relinquish the srqidx properly.
Signed-off-by: Raju Rangoju rajur@chelsio.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/cxgb4/cm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 0f83cbec33f3..a68569ec86bf 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1904,8 +1904,10 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) } mutex_unlock(&ep->com.mutex);
- if (release) + if (release) { + close_complete_upcall(ep, -ECONNRESET); release_ep_resources(ep); + } c4iw_put_ep(&ep->com); return 0; } @@ -3608,7 +3610,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) if (close) { if (abrupt) { set_bit(EP_DISC_ABORT, &ep->com.history); - close_complete_upcall(ep, -ECONNRESET); ret = send_abort(ep); } else { set_bit(EP_DISC_CLOSE, &ep->com.history);
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit 93c0970493c71f264e6c3c7caf1ff24a9e1de786 ]
The link status value latches link-down events. To get the current status we read the register twice in genphy_update_link(). There's a potential risk that we miss a link-down event in polling mode. This may cause issues if the user e.g. connects his machine to a different network.
On the other hand reading the latched value may cause issues in interrupt mode. Following scenario:
- After boot link goes up - phy_start() is called triggering an aneg restart, hence link goes down and link-down info is latched. - After aneg has finished link goes up and triggers an interrupt. Interrupt handler reads link status, means it reads the latched "link is down" info. But there won't be another interrupt as long as link stays up, therefore phylib will never recognize that link is up.
Deal with both scenarios by reading the register twice in interrupt mode only.
Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phy-c45.c | 10 ++++++++-- drivers/net/phy/phy_device.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index e1225545362d..0ba3607585bd 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -147,9 +147,15 @@ int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask) mmd_mask &= ~BIT(devad);
/* The link state is latched low so that momentary link - * drops can be detected. Do not double-read the status - * register if the link is down. + * drops can be detected. Do not double-read the status + * in polling mode to detect such short link drops. */ + if (!phy_polling_mode(phydev)) { + val = phy_read_mmd(phydev, devad, MDIO_STAT1); + if (val < 0) + return val; + } + val = phy_read_mmd(phydev, devad, MDIO_STAT1); if (val < 0) return val; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2c32c795f5dd..8a96d985a52f 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1503,10 +1503,15 @@ int genphy_update_link(struct phy_device *phydev) { int status;
- /* Do a fake read */ - status = phy_read(phydev, MII_BMSR); - if (status < 0) - return status; + /* The link state is latched low so that momentary link + * drops can be detected. Do not double-read the status + * in polling mode to detect such short link drops. + */ + if (!phy_polling_mode(phydev)) { + status = phy_read(phydev, MII_BMSR); + if (status < 0) + return status; + }
/* Read link and autonegotiation status */ status = phy_read(phydev, MII_BMSR);
From: Manfred Schlaegl manfred.schlaegl@ginzinger.com
[ Upstream commit a5399db139cb3ad9b8502d8b1bd02da9ce0b9df0 ]
There is no clipping on the x or y axis for logos larger that the framebuffer size. Therefore: a logo bigger than screen size leads to invalid memory access:
[ 1.254664] Backtrace: [ 1.254728] [<c02714e0>] (cfb_imageblit) from [<c026184c>] (fb_show_logo+0x620/0x684) [ 1.254763] r10:00000003 r9:00027fd8 r8:c6a40000 r7:c6a36e50 r6:00000000 r5:c06b81e4 [ 1.254774] r4:c6a3e800 [ 1.254810] [<c026122c>] (fb_show_logo) from [<c026c1e4>] (fbcon_switch+0x3fc/0x46c) [ 1.254842] r10:c6a3e824 r9:c6a3e800 r8:00000000 r7:c6a0c000 r6:c070b014 r5:c6a3e800 [ 1.254852] r4:c6808c00 [ 1.254889] [<c026bde8>] (fbcon_switch) from [<c029c8f8>] (redraw_screen+0xf0/0x1e8) [ 1.254918] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:c070d5a0 r5:00000080 [ 1.254928] r4:c6808c00 [ 1.254961] [<c029c808>] (redraw_screen) from [<c029d264>] (do_bind_con_driver+0x194/0x2e4) [ 1.254991] r9:00000000 r8:00000000 r7:00000014 r6:c070d5a0 r5:c070d5a0 r4:c070d5a0
So prevent displaying a logo bigger than screen size and avoid invalid memory access.
Signed-off-by: Manfred Schlaegl manfred.schlaegl@ginzinger.com Signed-off-by: Martin Kepplinger martin.kepplinger@ginzinger.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/core/fbmem.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 77cee99fc36c..c48f083d522a 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -427,6 +427,9 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, { unsigned int x;
+ if (image->width > info->var.xres || image->height > info->var.yres) + return; + if (rotate == FB_ROTATE_UR) { for (x = 0; x < num && image->dx + image->width <= info->var.xres;
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit f25191bb322dec8fa2979ecb8235643aa42470e1 ]
The following traceback is sometimes seen when booting an image in qemu:
[ 54.608293] cdrom: Uniform CD-ROM driver Revision: 3.20 [ 54.611085] Fusion MPT base driver 3.04.20 [ 54.611877] Copyright (c) 1999-2008 LSI Corporation [ 54.616234] Fusion MPT SAS Host driver 3.04.20 [ 54.635139] sysctl duplicate entry: /dev/cdrom//info [ 54.639578] CPU: 0 PID: 266 Comm: kworker/u4:5 Not tainted 5.0.0-rc5 #1 [ 54.639578] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 [ 54.641273] Workqueue: events_unbound async_run_entry_fn [ 54.641273] Call Trace: [ 54.641273] dump_stack+0x67/0x90 [ 54.641273] __register_sysctl_table+0x50b/0x570 [ 54.641273] ? rcu_read_lock_sched_held+0x6f/0x80 [ 54.641273] ? kmem_cache_alloc_trace+0x1c7/0x1f0 [ 54.646814] __register_sysctl_paths+0x1c8/0x1f0 [ 54.646814] cdrom_sysctl_register.part.7+0xc/0x5f [ 54.646814] register_cdrom.cold.24+0x2a/0x33 [ 54.646814] sr_probe+0x4bd/0x580 [ 54.646814] ? __driver_attach+0xd0/0xd0 [ 54.646814] really_probe+0xd6/0x260 [ 54.646814] ? __driver_attach+0xd0/0xd0 [ 54.646814] driver_probe_device+0x4a/0xb0 [ 54.646814] ? __driver_attach+0xd0/0xd0 [ 54.646814] bus_for_each_drv+0x73/0xc0 [ 54.646814] __device_attach+0xd6/0x130 [ 54.646814] bus_probe_device+0x9a/0xb0 [ 54.646814] device_add+0x40c/0x670 [ 54.646814] ? __pm_runtime_resume+0x4f/0x80 [ 54.646814] scsi_sysfs_add_sdev+0x81/0x290 [ 54.646814] scsi_probe_and_add_lun+0x888/0xc00 [ 54.646814] ? scsi_autopm_get_host+0x21/0x40 [ 54.646814] __scsi_add_device+0x116/0x130 [ 54.646814] ata_scsi_scan_host+0x93/0x1c0 [ 54.646814] async_run_entry_fn+0x34/0x100 [ 54.646814] process_one_work+0x237/0x5e0 [ 54.646814] worker_thread+0x37/0x380 [ 54.646814] ? rescuer_thread+0x360/0x360 [ 54.646814] kthread+0x118/0x130 [ 54.646814] ? kthread_create_on_node+0x60/0x60 [ 54.646814] ret_from_fork+0x3a/0x50
The only sensible explanation is that cdrom_sysctl_register() is called twice, once from the module init function and once from register_cdrom(). cdrom_sysctl_register() is not mutex protected and may happily execute twice if the second call is made before the first call is complete.
Use a static atomic to ensure that the function is executed exactly once.
Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cdrom/cdrom.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 10802d1fc554..27a82a559ab9 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -265,6 +265,7 @@ /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */ /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
+#include <linux/atomic.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> @@ -3693,9 +3694,9 @@ static struct ctl_table_header *cdrom_sysctl_header;
static void cdrom_sysctl_register(void) { - static int initialized; + static atomic_t initialized = ATOMIC_INIT(0);
- if (initialized == 1) + if (!atomic_add_unless(&initialized, 1, 1)) return;
cdrom_sysctl_header = register_sysctl_table(cdrom_root_table); @@ -3706,8 +3707,6 @@ static void cdrom_sysctl_register(void) cdrom_sysctl_settings.debug = debug; cdrom_sysctl_settings.lock = lockdoor; cdrom_sysctl_settings.check = check_media_type; - - initialized = 1; }
static void cdrom_sysctl_unregister(void)
From: Julia Lawall julia.lawall@lip6.fr
[ Upstream commit 4c6d8fc20b09f9684743afd72e4dbc3f15524479 ]
Add an of_node_put when the result of of_graph_get_remote_port_parent is not available.
Add a second of_node_put if no encoder is selected (encoder remains NULL).
The semantic match that finds the first problem is as follows (http://coccinelle.lip6.fr):
// <smpl> @r exists@ local idexpression e; expression x; @@ e = of_graph_get_remote_port_parent(...); ... when != x = e when != true e == NULL when != of_node_put(e) when != of_fwnode_handle(e) ( return e; | *return ...; ) // </smpl>
Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr Reviewed-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index fb46df56f0c4..0386b454e221 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -300,6 +300,7 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, dev_dbg(rcdu->dev, "connected entity %pOF is disabled, skipping\n", entity); + of_node_put(entity); return -ENODEV; }
@@ -335,6 +336,7 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, dev_warn(rcdu->dev, "no encoder found for endpoint %pOF, skipping\n", ep->local_node); + of_node_put(entity); return -ENODEV; }
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 5062b797db4103218fa00ee254417b8ecaab7401 ]
[Why] There are opt1c lock warnings and CRTC read timeouts when running the "igt@kms_plane@plane-position-hole-dpms-pipe-*" tests. These are caused by trying to reprogram planes that are not in the current context.
DPMS off removes the stream from the context. In this case:
new_crtc_state->active_changed = true new_crtc_state->mode_changed = false
The planes are reprogrammed before the stream is removed from the context because stream_state->mode_changed = false.
For DPMS adds the stream and planes back to the context:
new_crtc_state->active_changed = true new_crtc_state->mode_changed = false
The planes are also reprogrammed here before the stream is added to the context because stream_state->mode_changed = true. They were not previously in the current context so warnings occur here.
[How] Set stream_state->mode_changed = true when new_crtc_state->active_changed = true too.
This prevents reprogramming before the context is applied in DC. The programming will be done after the context is applied.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Sun peng Li Sunpeng.Li@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Acked-by: Tony Cheng Tony.Cheng@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c5ba9128b736..c57e85f08e23 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4368,7 +4368,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_state, struct dc_stream_state *stream_state) { - stream_state->mode_changed = crtc_state->mode_changed; + stream_state->mode_changed = + crtc_state->mode_changed || crtc_state->active_changed; }
static int amdgpu_dm_atomic_commit(struct drm_device *dev,
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 77476360f173c127c191bfe8ca8113130ef283b8 ]
[Why] This fixes an mpc programming error for the following sequence of atomic commits when pipe split is enabled:
Commit 1: CRTC0 (plane 4, plane 3)
Pipe 0: old_plane_state = A0, new_plane_state = A1, new_tg = T0 Pipe 1: old_plane_state = B0, new_plane_state = B1, new_tg = T0 Pipe 2: old_plane_state = A0, new_plane_state = A1, new_tg = T0 Pipe 3: old_plane_state = B0, new_plane_state = B1, new_tg = T0
Commit 2: CRTC0 (plane 3), CRTC1 (plane 2)
Pipe 0: old_plane_state = A1, new_plane_state = A2, new_tg = T0 Pipe 1: old_plane_state = B1, new_plane_state = B2, new_tg = T1 Pipe 2: old_plane_state = A1, new_plane_state = NULL, new_tg = NULL Pipe 3: old_plane_state = B1, new_plane_state = NULL, new_tg = NULL
In the second commit the assertion for mpcc in use is hit because mpcc disconnect never occurs for pipe 1. This is because the stream changes for pipe 1 and the opp_list is empty.
This sequence occurs when running the "igt@kms_plane_multiple@atomic-pipe-A-tiling-none" test with two displays connected.
[How] Expand the reset condition to include:
"old_pipe_ctx->stream_res.tg != new_pipe_ctx->stream_res.tg"
...but only when the plane state is non-NULL for both old and new.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Reviewed-by: Tony Cheng Tony.Cheng@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 4058b59d9bea..a0355709abd1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2336,9 +2336,10 @@ static void dcn10_apply_ctx_for_surface( } }
- if (!pipe_ctx->plane_state && - old_pipe_ctx->plane_state && - old_pipe_ctx->stream_res.tg == tg) { + if ((!pipe_ctx->plane_state || + pipe_ctx->stream_res.tg != old_pipe_ctx->stream_res.tg) && + old_pipe_ctx->plane_state && + old_pipe_ctx->stream_res.tg == tg) {
dc->hwss.plane_atomic_disconnect(dc, old_pipe_ctx); removed_pipe[i] = true;
From: Mathieu Poirier mathieu.poirier@linaro.org
[ Upstream commit 840018668ce2d96783356204ff282d6c9b0e5f66 ]
When pmu::setup_aux() is called the coresight PMU needs to know which sink to use for the session by looking up the information in the event's attr::config2 field.
As such simply replace the cpu information by the complete perf_event structure and change all affected customers.
Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Reviewed-by: Suzuki Poulouse suzuki.poulose@arm.com Acked-by: Peter Zijlstra peterz@infradead.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexei Starovoitov ast@kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: H. Peter Anvin hpa@zytor.com Cc: Heiko Carstens heiko.carstens@de.ibm.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Martin Schwidefsky schwidefsky@de.ibm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-s390@vger.kernel.org Link: http://lkml.kernel.org/r/20190131184714.20388-2-mathieu.poirier@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/perf_cpum_sf.c | 6 +++--- arch/x86/events/intel/bts.c | 4 +++- arch/x86/events/intel/pt.c | 5 +++-- drivers/hwtracing/coresight/coresight-etm-perf.c | 6 +++--- drivers/perf/arm_spe_pmu.c | 6 +++--- include/linux/perf_event.h | 2 +- kernel/events/ring_buffer.c | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 5c53e977be62..44404836e9d1 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1600,7 +1600,7 @@ static void aux_sdb_init(unsigned long sdb)
/* * aux_buffer_setup() - Setup AUX buffer for diagnostic mode sampling - * @cpu: On which to allocate, -1 means current + * @event: Event the buffer is setup for, event->cpu == -1 means current * @pages: Array of pointers to buffer pages passed from perf core * @nr_pages: Total pages * @snapshot: Flag for snapshot mode @@ -1612,8 +1612,8 @@ static void aux_sdb_init(unsigned long sdb) * * Return the private AUX buffer structure if success or NULL if fails. */ -static void *aux_buffer_setup(int cpu, void **pages, int nr_pages, - bool snapshot) +static void *aux_buffer_setup(struct perf_event *event, void **pages, + int nr_pages, bool snapshot) { struct sf_buffer *sfb; struct aux_buffer *aux; diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 24ffa1e88cf9..7139f6bf27ad 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c @@ -77,10 +77,12 @@ static size_t buf_size(struct page *page) }
static void * -bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite) +bts_buffer_setup_aux(struct perf_event *event, void **pages, + int nr_pages, bool overwrite) { struct bts_buffer *buf; struct page *page; + int cpu = event->cpu; int node = (cpu == -1) ? cpu : cpu_to_node(cpu); unsigned long offset; size_t size = nr_pages << PAGE_SHIFT; diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 8d016ce5b80d..8f4c98fdd03c 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -1104,10 +1104,11 @@ static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages, * Return: Our private PT buffer structure. */ static void * -pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot) +pt_buffer_setup_aux(struct perf_event *event, void **pages, + int nr_pages, bool snapshot) { struct pt_buffer *buf; - int node, ret; + int node, ret, cpu = event->cpu;
if (!nr_pages) return NULL; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 677695635211..0f5e03e4df22 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -181,15 +181,15 @@ static void etm_free_aux(void *data) schedule_work(&event_data->work); }
-static void *etm_setup_aux(int event_cpu, void **pages, +static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { - int cpu; + int cpu = event->cpu; cpumask_t *mask; struct coresight_device *sink; struct etm_event_data *event_data = NULL;
- event_data = alloc_event_data(event_cpu); + event_data = alloc_event_data(cpu); if (!event_data) return NULL; INIT_WORK(&event_data->work, free_event_data); diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index e1a77b2de78a..3623f6489f49 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -824,10 +824,10 @@ static void arm_spe_pmu_read(struct perf_event *event) { }
-static void *arm_spe_pmu_setup_aux(int cpu, void **pages, int nr_pages, - bool snapshot) +static void *arm_spe_pmu_setup_aux(struct perf_event *event, void **pages, + int nr_pages, bool snapshot) { - int i; + int i, cpu = event->cpu; struct page **pglist; struct arm_spe_pmu_buf *buf;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index c2876e740514..42fc852bf512 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -409,7 +409,7 @@ struct pmu { /* * Set up pmu-private data structures for an AUX area */ - void *(*setup_aux) (int cpu, void **pages, + void *(*setup_aux) (struct perf_event *event, void **pages, int nr_pages, bool overwrite); /* optional */
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 5631af940316..474b2ccdbe69 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -648,7 +648,7 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, goto out; }
- rb->aux_priv = event->pmu->setup_aux(event->cpu, rb->aux_pages, nr_pages, + rb->aux_priv = event->pmu->setup_aux(event, rb->aux_pages, nr_pages, overwrite); if (!rb->aux_priv) goto out;
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit 0f9e980bf5ee1a97e2e401c846b2af989eb21c61 ]
I'm seeing series of e1000e resets (sometimes endless) at system boot if something generates tx traffic at this time. In my case this is netconsole who sends message "e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames" from e1000e itself. As result e1000_watchdog_task sees used tx buffer while carrier is off and start this reset cycle again.
[ 17.794359] e1000e: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None [ 17.794714] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready [ 22.936455] e1000e 0000:02:00.0 eth1: changing MTU from 1500 to 9000 [ 23.033336] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 26.102364] e1000e: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None [ 27.174495] 8021q: 802.1Q VLAN Support v1.8 [ 27.174513] 8021q: adding VLAN 0 to HW filter on device eth1 [ 30.671724] cgroup: cgroup: disabling cgroup2 socket matching due to net_prio or net_cls activation [ 30.898564] netpoll: netconsole: local port 6666 [ 30.898566] netpoll: netconsole: local IPv6 address 2a02:6b8:0:80b:beae:c5ff:fe28:23f8 [ 30.898567] netpoll: netconsole: interface 'eth1' [ 30.898568] netpoll: netconsole: remote port 6666 [ 30.898568] netpoll: netconsole: remote IPv6 address 2a02:6b8:b000:605c:e61d:2dff:fe03:3790 [ 30.898569] netpoll: netconsole: remote ethernet address b0:a8:6e:f4:ff:c0 [ 30.917747] console [netcon0] enabled [ 30.917749] netconsole: network logging started [ 31.453353] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.185730] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.321840] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.465822] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.597423] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.745417] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 34.877356] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 35.005441] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 35.157376] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 35.289362] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 35.417441] e1000e 0000:02:00.0: Some CPU C-states have been disabled in order to enable jumbo frames [ 37.790342] e1000e: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
This patch flushes tx buffers only once when carrier is off rather than at each watchdog iteration.
Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e1000e/netdev.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index e3945469b5c8..23edc1364487 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5286,8 +5286,13 @@ static void e1000_watchdog_task(struct work_struct *work) /* 8000ES2LAN requires a Rx packet buffer work-around * on link down event; reset the controller to flush * the Rx packet buffer. + * + * If the link is lost the controller stops DMA, but + * if there is queued Tx work it cannot be done. So + * reset the controller to flush the Tx packet buffers. */ - if (adapter->flags & FLAG_RX_NEEDS_RESTART) + if ((adapter->flags & FLAG_RX_NEEDS_RESTART) || + e1000_desc_unused(tx_ring) + 1 < tx_ring->count) adapter->flags |= FLAG_RESTART_NOW; else pm_schedule_suspend(netdev->dev.parent, @@ -5310,14 +5315,6 @@ static void e1000_watchdog_task(struct work_struct *work) adapter->gotc_old = adapter->stats.gotc; spin_unlock(&adapter->stats64_lock);
- /* If the link is lost the controller stops DMA, but - * if there is queued Tx work it cannot be done. So - * reset the controller to flush the Tx packet buffers. - */ - if (!netif_carrier_ok(netdev) && - (e1000_desc_unused(tx_ring) + 1 < tx_ring->count)) - adapter->flags |= FLAG_RESTART_NOW; - /* If reset is necessary, do it outside of interrupt context. */ if (adapter->flags & FLAG_RESTART_NOW) { schedule_work(&adapter->reset_task);
From: Kai-Heng Feng kai.heng.feng@canonical.com
[ Upstream commit 59f58708c5047289589cbf6ee95146b76cf57d1e ]
e1000e sets different WoL settings in system suspend callback and runtime suspend callback.
The suspend direct complete optimization leaves e1000e in runtime suspended state with wrong WoL setting during system suspend.
To fix this, we need to disable suspend direct complete optimization to let e1000e always use suspend callback to set correct WoL during system suspend.
Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Jeff Kirsher jeffrey.t.kirsher@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e1000e/netdev.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 23edc1364487..8b11682ebba2 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -7327,6 +7327,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
e1000_print_device_info(adapter);
+ dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); + if (pci_dev_run_wake(pdev)) pm_runtime_put_noidle(&pdev->dev);
From: Rajneesh Bhardwaj rajneesh.bhardwaj@linux.intel.com
[ Upstream commit 0e68eeea9894feeba2edf7ec63e4551b87f39621 ]
A previous commit "platform/x86: intel_pmc_core: Make the driver PCH family agnostic <c977b98bbef5898ed3d30b08ea67622e9e82082a>" provided better abstraction to this driver but has some fundamental issues.
e.g. the following condition
for (index = 0; index < pmcdev->map->ppfear_buckets && index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++)
is wrong because for CNL, PPFEAR_MAX_NUM_ENTRIES is hardcoded as 5 which is _wrong_ and even though ppfear_buckets is 8, the loop fails to read all eight registers needed for CNL PCH i.e. PPFEAR0 and PPFEAR1. This patch refactors the pfear show logic to correctly read PCH IP power gating status for Cannonlake and beyond.
Cc: "David E. Box" david.e.box@intel.com Cc: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Fixes: c977b98bbef5 ("platform/x86: intel_pmc_core: Make the driver PCH family agnostic") Signed-off-by: Rajneesh Bhardwaj rajneesh.bhardwaj@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel_pmc_core.c | 3 ++- drivers/platform/x86/intel_pmc_core.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index 2d272a3e0176..e0dcdb3cc070 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -333,7 +333,8 @@ static int pmc_core_ppfear_sts_show(struct seq_file *s, void *unused) index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++) pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
- for (index = 0; map[index].name; index++) + for (index = 0; map[index].name && + index < pmcdev->map->ppfear_buckets * 8; index++) pmc_core_display_map(s, index, pf_regs[index / 8], map);
return 0; diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h index 93a7e99e1f8b..3f9711b03cb4 100644 --- a/drivers/platform/x86/intel_pmc_core.h +++ b/drivers/platform/x86/intel_pmc_core.h @@ -39,7 +39,7 @@ #define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64 #define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1) #define MTPMC_MASK 0xffff0000 -#define PPFEAR_MAX_NUM_ENTRIES 5 +#define PPFEAR_MAX_NUM_ENTRIES 12 #define SPT_PPFEAR_NUM_ENTRIES 5 #define SPT_PMC_READ_DISABLE_BIT 0x16 #define SPT_PMC_MSG_FULL_STS_BIT 0x18
From: Thierry Reding treding@nvidia.com
[ Upstream commit e814e688413aabd7b0d75e2a8ed1caa472951dec ]
If an I2C adapter doesn't match the provided device tree node, also try matching the parent's device tree node. This allows finding an adapter based on the device node of the parent device that was used to register it.
This fixes a regression on Tegra124-based Chromebooks (Nyan) where the eDP controller registers an I2C adapter that is used to read to EDID. After commit 993a815dcbb2 ("dt-bindings: panel: Add missing .txt suffix") this stopped working because the I2C adapter could no longer be found. The approach in this patch fixes the regression without introducing the issues that the above commit solved.
Fixes: 17ab7806de0c ("drm: don't link DP aux i2c adapter to the hardware device node") Signed-off-by: Thierry Reding treding@nvidia.com Tested-by: Tristan Bastian tristan-c.bastian@gmx.de Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/i2c-core-of.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 6cb7ad608bcd..0f01cdba9d2c 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -121,6 +121,17 @@ static int of_dev_node_match(struct device *dev, void *data) return dev->of_node == data; }
+static int of_dev_or_parent_node_match(struct device *dev, void *data) +{ + if (dev->of_node == data) + return 1; + + if (dev->parent) + return dev->parent->of_node == data; + + return 0; +} + /* must call put_device() when done with returned i2c_client device */ struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) { @@ -145,7 +156,8 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) struct device *dev; struct i2c_adapter *adapter;
- dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match); + dev = bus_find_device(&i2c_bus_type, NULL, node, + of_dev_or_parent_node_match); if (!dev) return NULL;
From: Stefan Roese sr@denx.de
[ Upstream commit 46c337872f34bc6387b0c29a4964f562c70139e3 ]
This patch adds a return code check on device_reset() and removes the compile warning.
Signed-off-by: Stefan Roese sr@denx.de Cc: Mark Brown broonie@kernel.org Cc: Sankalp Negi sankalpnegi2310@gmail.com Cc: Chuanhong Guo gch981213@gmail.com Cc: John Crispin john@phrozen.org Reviewed-by: NeilBrown neil@brown.name Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/mt7621-spi/spi-mt7621.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c index d045b5568e0f..578aa6824ad3 100644 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ b/drivers/staging/mt7621-spi/spi-mt7621.c @@ -429,6 +429,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) int status = 0; struct clk *clk; struct mt7621_spi_ops *ops; + int ret;
match = of_match_device(mt7621_spi_match, &pdev->dev); if (!match) @@ -476,7 +477,11 @@ static int mt7621_spi_probe(struct platform_device *pdev) rs->pending_write = 0; dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
- device_reset(&pdev->dev); + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "SPI reset failed!\n"); + return ret; + }
mt7621_spi_reset(rs, 0);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit dbf592f3d14fb7d532cb7c820b1065cf33e02aaa ]
If we have >=10 (logical) CPUs, our command size exceeds the internal buffer size and the command fails; fix that by using IWL_HCMD_DFL_NOCOPY for the command that's allocated anyway.
While at it, also fix the leak of cmd, and use struct_size() to calculate its size.
Signed-off-by: Johannes Berg johannes.berg@intel.com Fixes: 8edbfaa19835 ("iwlwifi: mvm: configure multi RX queue") Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 16c6c7f921a8..8b7d70e3a379 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -132,13 +132,17 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
static int iwl_configure_rxq(struct iwl_mvm *mvm) { - int i, num_queues, size; + int i, num_queues, size, ret; struct iwl_rfh_queue_config *cmd; + struct iwl_host_cmd hcmd = { + .id = WIDE_ID(DATA_PATH_GROUP, RFH_QUEUE_CONFIG_CMD), + .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + };
/* Do not configure default queue, it is configured via context info */ num_queues = mvm->trans->num_rx_queues - 1;
- size = sizeof(*cmd) + num_queues * sizeof(struct iwl_rfh_queue_data); + size = struct_size(cmd, data, num_queues);
cmd = kzalloc(size, GFP_KERNEL); if (!cmd) @@ -159,10 +163,14 @@ static int iwl_configure_rxq(struct iwl_mvm *mvm) cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid); }
- return iwl_mvm_send_cmd_pdu(mvm, - WIDE_ID(DATA_PATH_GROUP, - RFH_QUEUE_CONFIG_CMD), - 0, size, cmd); + hcmd.data[0] = cmd; + hcmd.len[0] = size; + + ret = iwl_mvm_send_cmd(mvm, &hcmd); + + kfree(cmd); + + return ret; }
static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm)
From: wen yang yellowriver2010@hotmail.com
[ Upstream commit 11907e9d3533648615db08140e3045b829d2c141 ]
The of_find_device_by_node() takes a reference to the underlying device structure, we should release that reference.
Signed-off-by: Wen Yang yellowriver2010@hotmil.com Cc: Timur Tabi timur@kernel.org Cc: Nicolin Chen nicoleotsuka@gmail.com Cc: Xiubo Li Xiubo.Lee@gmail.com Cc: Fabio Estevam festevam@gmail.com Cc: Liam Girdwood lgirdwood@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 44433b20435c..600d9be9706e 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -689,6 +689,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) asrc_fail: of_node_put(asrc_np); of_node_put(codec_np); + put_device(&cpu_pdev->dev); fail: of_node_put(cpu_np);
From: Hidetoshi Seto seto.hidetoshi@jp.fujitsu.com
[ Upstream commit 1ca4fa3ab604734e38e2a3000c9abf788512ffa7 ]
register_sched_domain_sysctl() copies the cpu_possible_mask into sd_sysctl_cpus, but only if sd_sysctl_cpus hasn't already been allocated (ie, CONFIG_CPUMASK_OFFSTACK is set). However, when CONFIG_CPUMASK_OFFSTACK is not set, sd_sysctl_cpus is left uninitialized (all zeroes) and the kernel may fail to initialize sched_domain sysctl entries for all possible CPUs.
This is visible to the user if the kernel is booted with maxcpus=n, or if ACPI tables have been modified to leave CPUs offline, and then checking for missing /proc/sys/kernel/sched_domain/cpu* entries.
Fix this by separating the allocation and initialization, and adding a flag to initialize the possible CPU entries while system booting only.
Tested-by: Syuuichirou Ishii ishii.shuuichir@jp.fujitsu.com Tested-by: Tarumizu, Kohei tarumizu.kohei@jp.fujitsu.com Signed-off-by: Hidetoshi Seto seto.hidetoshi@jp.fujitsu.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Masayoshi Mizuma m.mizuma@jp.fujitsu.com Acked-by: Joe Lawrence joe.lawrence@redhat.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Masayoshi Mizuma msys.mizuma@gmail.com Cc: Mike Galbraith efault@gmx.de Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/20190129151245.5073-1-msys.mizuma@gmail.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/debug.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 6383aa6a60ca..141ea9ff210e 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -315,6 +315,7 @@ void register_sched_domain_sysctl(void) { static struct ctl_table *cpu_entries; static struct ctl_table **cpu_idx; + static bool init_done = false; char buf[32]; int i;
@@ -344,7 +345,10 @@ void register_sched_domain_sysctl(void) if (!cpumask_available(sd_sysctl_cpus)) { if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL)) return; + }
+ if (!init_done) { + init_done = true; /* init to possible to not have holes in @cpu_entries */ cpumask_copy(sd_sysctl_cpus, cpu_possible_mask); }
From: Waiman Long longman@redhat.com
[ Upstream commit 71492580571467fb7177aade19c18ce7486267f5 ]
Tetsuo Handa had reported he saw an incorrect "downgrading a read lock" warning right after a previous lockdep warning. It is likely that the previous warning turned off lock debugging causing the lockdep to have inconsistency states leading to the lock downgrade warning.
Fix that by add a check for debug_locks at the beginning of __lock_downgrade().
Debugged-by: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Reported-by: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Reported-by: syzbot+53383ae265fb161ef488@syzkaller.appspotmail.com Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Link: https://lkml.kernel.org/r/1547093005-26085-1-git-send-email-longman@redhat.c... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 26b57e24476f..0cbdbbb0729f 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -3567,6 +3567,9 @@ __lock_set_class(struct lockdep_map *lock, const char *name, unsigned int depth; int i;
+ if (unlikely(!debug_locks)) + return 0; + depth = curr->lockdep_depth; /* * This function is about (re)setting the class of a held lock,
From: Ard Biesheuvel ard.biesheuvel@linaro.org
[ Upstream commit 5de0fef0230f3c8d75cff450a71740a7bf2db866 ]
The EFI memory attributes code cross-references the EFI memory map with the more granular EFI memory attributes table to ensure that they are in sync before applying the strict permissions to the regions it describes.
Since we always install virtual mappings for the EFI runtime regions to which these strict permissions apply, we currently perform a sanity check on the EFI memory descriptor, and ensure that the EFI_MEMORY_RUNTIME bit is set, and that the virtual address has been assigned.
However, in cases where a runtime region exists at physical address 0x0, and the virtual mapping equals the physical mapping, e.g., when running in mixed mode on x86, we encounter a memory descriptor with the runtime attribute and virtual address 0x0, and incorrectly draw the conclusion that a runtime region exists for which no virtual mapping was installed, and give up altogether. The consequence of this is that firmware mappings retain their read-write-execute permissions, making the system more vulnerable to attacks.
So let's only bail if the virtual address of 0x0 has been assigned to a physical region that does not reside at address 0x0.
Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org Acked-by: Sai Praneeth Prakhya sai.praneeth.prakhya@intel.com Cc: AKASHI Takahiro takahiro.akashi@linaro.org Cc: Alexander Graf agraf@suse.de Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Borislav Petkov bp@alien8.de Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Jeffrey Hugo jhugo@codeaurora.org Cc: Lee Jones lee.jones@linaro.org Cc: Leif Lindholm leif.lindholm@linaro.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Matt Fleming matt@codeblueprint.co.uk Cc: Peter Jones pjones@redhat.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-efi@vger.kernel.org Fixes: 10f0d2f577053 ("efi: Implement generic support for the Memory ...") Link: http://lkml.kernel.org/r/20190202094119.13230-4-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/memattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c index 8986757eafaf..aac972b056d9 100644 --- a/drivers/firmware/efi/memattr.c +++ b/drivers/firmware/efi/memattr.c @@ -94,7 +94,7 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out)
if (!(md->attribute & EFI_MEMORY_RUNTIME)) continue; - if (md->virt_addr == 0) { + if (md->virt_addr == 0 && md->phys_addr != 0) { /* no virtual mapping has been installed by the stub */ break; }
From: Andrea Parri andrea.parri@amarulasolutions.com
[ Upstream commit c546951d9c9300065bad253ecdf1ac59ce9d06c8 ]
move_queued_task() synchronizes with task_rq_lock() as follows:
move_queued_task() task_rq_lock()
[S] ->on_rq = MIGRATING [L] rq = task_rq() WMB (__set_task_cpu()) ACQUIRE (rq->lock); [S] ->cpu = new_cpu [L] ->on_rq
where "[L] rq = task_rq()" is ordered before "ACQUIRE (rq->lock)" by an address dependency and, in turn, "ACQUIRE (rq->lock)" is ordered before "[L] ->on_rq" by the ACQUIRE itself.
Use READ_ONCE() to load ->cpu in task_rq() (c.f., task_cpu()) to honor this address dependency. Also, mark the accesses to ->cpu and ->on_rq with READ_ONCE()/WRITE_ONCE() to comply with the LKMM.
Signed-off-by: Andrea Parri andrea.parri@amarulasolutions.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Alan Stern stern@rowland.harvard.edu Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Mike Galbraith efault@gmx.de Cc: Paul E. McKenney paulmck@linux.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Link: https://lkml.kernel.org/r/20190121155240.27173-1-andrea.parri@amarulasolutio... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched.h | 4 ++-- kernel/sched/core.c | 9 +++++---- kernel/sched/sched.h | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h index 4abb5bd74b04..5dc024e28397 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1737,9 +1737,9 @@ static __always_inline bool need_resched(void) static inline unsigned int task_cpu(const struct task_struct *p) { #ifdef CONFIG_THREAD_INFO_IN_TASK - return p->cpu; + return READ_ONCE(p->cpu); #else - return task_thread_info(p)->cpu; + return READ_ONCE(task_thread_info(p)->cpu); #endif }
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 152a0b0c91bb..9a4f57d7e931 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -107,11 +107,12 @@ struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf) * [L] ->on_rq * RELEASE (rq->lock) * - * If we observe the old CPU in task_rq_lock, the acquire of + * If we observe the old CPU in task_rq_lock(), the acquire of * the old rq->lock will fully serialize against the stores. * - * If we observe the new CPU in task_rq_lock, the acquire will - * pair with the WMB to ensure we must then also see migrating. + * If we observe the new CPU in task_rq_lock(), the address + * dependency headed by '[L] rq = task_rq()' and the acquire + * will pair with the WMB to ensure we then also see migrating. */ if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) { rq_pin_lock(rq, rf); @@ -910,7 +911,7 @@ static struct rq *move_queued_task(struct rq *rq, struct rq_flags *rf, { lockdep_assert_held(&rq->lock);
- p->on_rq = TASK_ON_RQ_MIGRATING; + WRITE_ONCE(p->on_rq, TASK_ON_RQ_MIGRATING); dequeue_task(rq, p, DEQUEUE_NOCLOCK); set_task_cpu(p, new_cpu); rq_unlock(rq, rf); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index b63172288f7b..4c7a837d7c14 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1331,9 +1331,9 @@ static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) */ smp_wmb(); #ifdef CONFIG_THREAD_INFO_IN_TASK - p->cpu = cpu; + WRITE_ONCE(p->cpu, cpu); #else - task_thread_info(p)->cpu = cpu; + WRITE_ONCE(task_thread_info(p)->cpu, cpu); #endif p->wake_cpu = cpu; #endif @@ -1434,7 +1434,7 @@ static inline int task_on_rq_queued(struct task_struct *p)
static inline int task_on_rq_migrating(struct task_struct *p) { - return p->on_rq == TASK_ON_RQ_MIGRATING; + return READ_ONCE(p->on_rq) == TASK_ON_RQ_MIGRATING; }
/*
From: Shayenne Moura shayenneluzmoura@gmail.com
[ Upstream commit def35e7c592616bc09be328de8795e5e624a3cf8 ]
kms_flip tests are breaking on vkms when simulate vblank because vblank event sequence count returns one extra frame after arm vblank event to make a page flip.
When vblank interrupt happens, userspace processes the vblank event and issues the next page flip command. Kernel calls queue_work to call commit_planes and arm the new page flip. The next vblank picks up the newly armed vblank event and vblank interrupt happens again.
The arm and vblank event are asynchronous, then, on the next vblank, we receive x+2 from `get_vblank_timestamp`, instead x+1, although timestamp and vblank seqno matches.
Function `get_vblank_timestamp` is reached by 2 ways:
- from `drm_mode_page_flip_ioctl`: driver is doing one atomic operation to synchronize planes in the same output. There is no vblank simulation, the `drm_crtc_arm_vblank_event` function adds 1 on vblank count, and the variable in_vblank_irq is false - from `vkms_vblank_simulate`: since the driver is doing a vblank simulation, the variable in_vblank_irq is true.
Fix this problem subtracting one vblank period from vblank_time when `get_vblank_timestamp` is called from trace `drm_mode_page_flip_ioctl`, i.e., is not a real vblank interrupt, and getting the timestamp and vblank seqno when it is a real vblank interrupt.
The reason for all this is that get_vblank_timestamp always supplies the timestamp for the next vblank event. The hrtimer is the vblank simulator, and it needs the correct previous value to present the next vblank. Since this is how hw timestamp registers work and what the vblank core expects.
Signed-off-by: Shayenne Moura shayenneluzmoura@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Reviewed-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Signed-off-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/171e6e1c239cbca0c3df7183ed8acd... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_crtc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 1ea2dd35bca9..0a271f762a0a 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -55,6 +55,9 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
*vblank_time = output->vblank_hrtimer.node.expires;
+ if (!in_vblank_irq) + *vblank_time -= output->period_ns; + return true; }
From: Mathieu Malaterre malat@debian.org
[ Upstream commit 3e3380d0675d5e20b0af067d60cb947a4348bf9b ]
Improve the DTS files by removing all the leading "0x" and zeros to fix the following dtc warnings:
Warning (unit_address_format): Node /XXX unit name should not have leading "0x"
and
Warning (unit_address_format): Node /XXX unit name should not have leading 0s
Converted using the following command:
find . -type f ( -iname *.dts -o -iname *.dtsi ) -exec sed -i -e "s/@([0-9a-fA-FxX.;:#]+)\s*{/@\L\1 {/g" -e "s/@0x(.*) {/@\1 {/g" -e "s/@0+(.*) {/@\1 {/g" {} +
For simplicity, two sed expressions were used to solve each warnings separately.
To make the regex expression more robust a few other issues were resolved, namely setting unit-address to lower case, and adding a whitespace before the opening curly brace:
https://elinux.org/Device_Tree_Linux#Linux_conventions
This will solve as a side effect warning:
Warning (simple_bus_reg): Node /XXX@<UPPER> simple-bus unit address format error, expected "<lower>"
This is a follow up to commit 4c9847b7375a ("dt-bindings: Remove leading 0x from bindings notation")
Reported-by: David Daney ddaney@caviumnetworks.com Suggested-by: Rob Herring robh@kernel.org Signed-off-by: Mathieu Malaterre malat@debian.org [vzapolskiy: fixed commit message to pass checkpatch.pl test] Signed-off-by: Vladimir Zapolskiy vz@mleia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/lpc32xx.dtsi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index abff7ef7c9cd..4981741377f3 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -230,7 +230,7 @@ status = "disabled"; };
- i2s1: i2s@2009C000 { + i2s1: i2s@2009c000 { compatible = "nxp,lpc3220-i2s"; reg = <0x2009C000 0x1000>; }; @@ -273,7 +273,7 @@ status = "disabled"; };
- i2c1: i2c@400A0000 { + i2c1: i2c@400a0000 { compatible = "nxp,pnx-i2c"; reg = <0x400A0000 0x100>; interrupt-parent = <&sic1>; @@ -284,7 +284,7 @@ clocks = <&clk LPC32XX_CLK_I2C1>; };
- i2c2: i2c@400A8000 { + i2c2: i2c@400a8000 { compatible = "nxp,pnx-i2c"; reg = <0x400A8000 0x100>; interrupt-parent = <&sic1>; @@ -295,7 +295,7 @@ clocks = <&clk LPC32XX_CLK_I2C2>; };
- mpwm: mpwm@400E8000 { + mpwm: mpwm@400e8000 { compatible = "nxp,lpc3220-motor-pwm"; reg = <0x400E8000 0x78>; status = "disabled"; @@ -394,7 +394,7 @@ #gpio-cells = <3>; /* bank, pin, flags */ };
- timer4: timer@4002C000 { + timer4: timer@4002c000 { compatible = "nxp,lpc3220-timer"; reg = <0x4002C000 0x1000>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; @@ -412,7 +412,7 @@ status = "disabled"; };
- watchdog: watchdog@4003C000 { + watchdog: watchdog@4003c000 { compatible = "nxp,pnx4008-wdt"; reg = <0x4003C000 0x1000>; clocks = <&clk LPC32XX_CLK_WDOG>; @@ -451,7 +451,7 @@ status = "disabled"; };
- timer1: timer@4004C000 { + timer1: timer@4004c000 { compatible = "nxp,lpc3220-timer"; reg = <0x4004C000 0x1000>; interrupts = <17 IRQ_TYPE_LEVEL_LOW>; @@ -475,7 +475,7 @@ status = "disabled"; };
- pwm1: pwm@4005C000 { + pwm1: pwm@4005c000 { compatible = "nxp,lpc3220-pwm"; reg = <0x4005C000 0x4>; clocks = <&clk LPC32XX_CLK_PWM1>; @@ -484,7 +484,7 @@ status = "disabled"; };
- pwm2: pwm@4005C004 { + pwm2: pwm@4005c004 { compatible = "nxp,lpc3220-pwm"; reg = <0x4005C004 0x4>; clocks = <&clk LPC32XX_CLK_PWM2>;
From: Ard Biesheuvel ard.biesheuvel@linaro.org
[ Upstream commit 4e46c2a956215482418d7b315749fb1b6c6bc224 ]
The UEFI spec revision 2.7 errata A section 8.4 has the following to say about the virtual memory runtime services:
"This section contains function definitions for the virtual memory support that may be optionally used by an operating system at runtime. If an operating system chooses to make EFI runtime service calls in a virtual addressing mode instead of the flat physical mode, then the operating system must use the services in this section to switch the EFI runtime services from flat physical addressing to virtual addressing."
So it is pretty clear that calling SetVirtualAddressMap() is entirely optional, and so there is no point in doing so unless it achieves anything useful for us.
This is not the case for 64-bit ARM. The identity mapping used by the firmware is arbitrarily converted into another permutation of userland addresses (i.e., bits [63:48] cleared), and the runtime code could easily deal with the original layout in exactly the same way as it deals with the converted layout. However, due to constraints related to page size differences if the OS is not running with 4k pages, and related to systems that may expose the individual sections of PE/COFF runtime modules as different memory regions, creating the virtual layout is a bit fiddly, and requires us to sort the memory map and reason about adjacent regions with identical memory types etc etc.
So the obvious fix is to stop calling SetVirtualAddressMap() altogether on arm64 systems. However, to avoid surprises, which are notoriously hard to diagnose when it comes to OS<->firmware interactions, let's start by making it an opt-out feature, and implement support for the 'efi=novamap' kernel command line parameter on ARM and arm64 systems.
( Note that 32-bit ARM generally does require SetVirtualAddressMap() to be used, given that the physical memory map and the kernel virtual address map are not guaranteed to be non-overlapping like on arm64. However, having support for efi=novamap,noruntime on 32-bit ARM, combined with the recently proposed support for earlycon=efifb, is likely to be useful to diagnose boot issues on such systems if they have no accessible serial port. )
Tested-by: Jeffrey Hugo jhugo@codeaurora.org Tested-by: Bjorn Andersson bjorn.andersson@linaro.org Tested-by: Lee Jones lee.jones@linaro.org Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: AKASHI Takahiro takahiro.akashi@linaro.org Cc: Alexander Graf agraf@suse.de Cc: Borislav Petkov bp@alien8.de Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Leif Lindholm leif.lindholm@linaro.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Matt Fleming matt@codeblueprint.co.uk Cc: Peter Jones pjones@redhat.com Cc: Peter Zijlstra peterz@infradead.org Cc: Sai Praneeth Prakhya sai.praneeth.prakhya@intel.com Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20190202094119.13230-8-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/libstub/arm-stub.c | 5 +++++ drivers/firmware/efi/libstub/efi-stub-helper.c | 10 ++++++++++ drivers/firmware/efi/libstub/efistub.h | 1 + drivers/firmware/efi/libstub/fdt.c | 3 +++ 4 files changed, 19 insertions(+)
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 6920033de6d4..6c09644d620e 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -340,6 +340,11 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, paddr = in->phys_addr; size = in->num_pages * EFI_PAGE_SIZE;
+ if (novamap()) { + in->virt_addr = in->phys_addr; + continue; + } + /* * Make the mapping compatible with 64k pages: this allows * a 4k page size kernel to kexec a 64k page size kernel and diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index e94975f4655b..442f51c2a53d 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -34,6 +34,7 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
static int __section(.data) __nokaslr; static int __section(.data) __quiet; +static int __section(.data) __novamap;
int __pure nokaslr(void) { @@ -43,6 +44,10 @@ int __pure is_quiet(void) { return __quiet; } +int __pure novamap(void) +{ + return __novamap; +}
#define EFI_MMAP_NR_SLACK_SLOTS 8
@@ -482,6 +487,11 @@ efi_status_t efi_parse_options(char const *cmdline) __chunk_size = -1UL; }
+ if (!strncmp(str, "novamap", 7)) { + str += strlen("novamap"); + __novamap = 1; + } + /* Group words together, delimited by "," */ while (*str && *str != ' ' && *str != ',') str++; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 32799cf039ef..337b52c4702c 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -27,6 +27,7 @@
extern int __pure nokaslr(void); extern int __pure is_quiet(void); +extern int __pure novamap(void);
#define pr_efi(sys_table, msg) do { \ if (!is_quiet()) efi_printk(sys_table, "EFI stub: "msg); \ diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 0c0d2312f4a8..dba296a44f4e 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -327,6 +327,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, if (status == EFI_SUCCESS) { efi_set_virtual_address_map_t *svam;
+ if (novamap()) + return EFI_SUCCESS; + /* Install the new virtual address map */ svam = sys_table->runtime->set_virtual_address_map; status = svam(runtime_entry_count * desc_size, desc_size,
From: Alexey Khoroshilov khoroshilov@ispras.ru
[ Upstream commit 8cd09a3dd3e176c62da67efcd477a44a8d87185e ]
If of_platform_populate() fails in gsbi_probe(), gsbi->hclk is left undisabled.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Andy Gross andy.gross@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/qcom_gsbi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index 09c669e70d63..038abc377fdb 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -138,7 +138,7 @@ static int gsbi_probe(struct platform_device *pdev) struct resource *res; void __iomem *base; struct gsbi_info *gsbi; - int i; + int i, ret; u32 mask, gsbi_num; const struct crci_config *config = NULL;
@@ -221,7 +221,10 @@ static int gsbi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gsbi);
- return of_platform_populate(node, NULL, NULL, &pdev->dev); + ret = of_platform_populate(node, NULL, NULL, &pdev->dev); + if (ret) + clk_disable_unprepare(gsbi->hclk); + return ret; }
static int gsbi_remove(struct platform_device *pdev)
From: Stanislaw Gruszka sgruszka@redhat.com
[ Upstream commit 3bd1505fed71d834f45e87b32ff07157fdda47e0 ]
As reported by Michael eeprom 0d is supported and work with the driver.
Dump of /sys/kernel/debug/ieee80211/phy1/mt7601u/eeprom_param with 0d EEPORM looks like this:
RSSI offset: 0 0 Reference temp: f9 LNA gain: 8 Reg channels: 1-14 Per rate power: raw:05 bw20:05 bw40:05 raw:05 bw20:05 bw40:05 raw:03 bw20:03 bw40:03 raw:03 bw20:03 bw40:03 raw:04 bw20:04 bw40:04 raw:00 bw20:00 bw40:00 raw:00 bw20:00 bw40:00 raw:00 bw20:00 bw40:00 raw:02 bw20:02 bw40:02 raw:00 bw20:00 bw40:00 Per channel power: tx_power ch1:09 ch2:09 tx_power ch3:0a ch4:0a tx_power ch5:0a ch6:0a tx_power ch7:0b ch8:0b tx_power ch9:0b ch10:0b tx_power ch11:0b ch12:0b tx_power ch13:0b ch14:0b
Reported-and-tested-by: Michael ZeroBeat@gmx.de Signed-off-by: Stanislaw Gruszka sgruszka@redhat.com Acked-by: Jakub Kicinski kubakici@wp.pl Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt7601u/eeprom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt7601u/eeprom.h b/drivers/net/wireless/mediatek/mt7601u/eeprom.h index 662d12703b69..57b503ae63f1 100644 --- a/drivers/net/wireless/mediatek/mt7601u/eeprom.h +++ b/drivers/net/wireless/mediatek/mt7601u/eeprom.h @@ -17,7 +17,7 @@
struct mt7601u_dev;
-#define MT7601U_EE_MAX_VER 0x0c +#define MT7601U_EE_MAX_VER 0x0d #define MT7601U_EEPROM_SIZE 256
#define MT7601U_DEFAULT_TX_POWER 6
From: Vladimir Murzin vladimir.murzin@arm.com
[ Upstream commit 72cd4064fccaae15ab84d40d4be23667402df4ed ]
ARMv8M introduces support for Security extension to M class, among other things it affects exception handling, especially, encoding of EXC_RETURN.
The new bits have been added:
Bit [6] Secure or Non-secure stack Bit [5] Default callee register stacking Bit [0] Exception Secure
which conflicts with hard-coded value of EXC_RETURN:
In fact, we only care of few bits:
Bit [3] Mode (0 - Handler, 1 - Thread) Bit [2] Stack pointer selection (0 - Main, 1 - Process)
We can toggle only those bits and left other bits as they were on exception entry.
It is basically, what patch does - saves EXC_RETURN when we do transition form Thread to Handler mode (it is first svc), so later saved value is used instead of EXC_RET_THREADMODE_PROCESSSTACK.
Signed-off-by: Vladimir Murzin vladimir.murzin@arm.com Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/v7m.h | 2 +- arch/arm/kernel/entry-header.S | 3 ++- arch/arm/kernel/entry-v7m.S | 4 ++++ arch/arm/mm/proc-v7m.S | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h index 187ccf6496ad..2cb00d15831b 100644 --- a/arch/arm/include/asm/v7m.h +++ b/arch/arm/include/asm/v7m.h @@ -49,7 +49,7 @@ * (0 -> msp; 1 -> psp). Bits [1:0] are fixed to 0b01. */ #define EXC_RET_STACK_MASK 0x00000004 -#define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd +#define EXC_RET_THREADMODE_PROCESSSTACK (3 << 2)
/* Cache related definitions */
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 773424843d6e..62db1c9746cb 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -127,7 +127,8 @@ */ .macro v7m_exception_slow_exit ret_r0 cpsid i - ldr lr, =EXC_RET_THREADMODE_PROCESSSTACK + ldr lr, =exc_ret + ldr lr, [lr]
@ read original r12, sp, lr, pc and xPSR add r12, sp, #S_IP diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S index abcf47848525..19d2dcd6530d 100644 --- a/arch/arm/kernel/entry-v7m.S +++ b/arch/arm/kernel/entry-v7m.S @@ -146,3 +146,7 @@ ENTRY(vector_table) .rept CONFIG_CPU_V7M_NUM_IRQ .long __irq_entry @ External Interrupts .endr + .align 2 + .globl exc_ret +exc_ret: + .space 4 diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index 47a5acc64433..92e84181933a 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S @@ -139,6 +139,9 @@ __v7m_setup_cont: cpsie i svc #0 1: cpsid i + ldr r0, =exc_ret + orr lr, lr, #EXC_RET_THREADMODE_PROCESSSTACK + str lr, [r0] ldmia sp, {r0-r3, r12} str r5, [r12, #11 * 4] @ restore the original SVC vector entry mov lr, r6 @ restore LR
From: Russell King rmk+kernel@armlinux.org.uk
[ Upstream commit 5388a5b82199facacd3d7ac0d05aca6e8f902fed ]
machine_crash_nonpanic_core() does this:
while (1) cpu_relax();
because the kernel has crashed, and we have no known safe way to deal with the CPU. So, we place the CPU into an infinite loop which we expect it to never exit - at least not until the system as a whole is reset by some method.
In the absence of erratum 754327, this code assembles to:
b .
In other words, an infinite loop. When erratum 754327 is enabled, this becomes:
1: dmb b 1b
It has been observed that on some systems (eg, OMAP4) where, if a crash is triggered, the system tries to kexec into the panic kernel, but fails after taking the secondary CPU down - placing it into one of these loops. This causes the system to livelock, and the most noticable effect is the system stops after issuing:
Loading crashdump kernel...
to the system console.
The tested as working solution I came up with was to add wfe() to these infinite loops thusly:
while (1) { cpu_relax(); wfe(); }
which, without 754327 builds to:
1: wfe b 1b
or with 754327 is enabled:
1: dmb wfe b 1b
Adding "wfe" does two things depending on the environment we're running under: - where we're running on bare metal, and the processor implements "wfe", it stops us spinning endlessly in a loop where we're never going to do any useful work. - if we're running in a VM, it allows the CPU to be given back to the hypervisor and rescheduled for other purposes (maybe a different VM) rather than wasting CPU cycles inside a crashed VM.
However, in light of erratum 794072, Will Deacon wanted to see 10 nops as well - which is reasonable to cover the case where we have erratum 754327 enabled _and_ we have a processor that doesn't implement the wfe hint.
So, we now end up with:
1: wfe b 1b
when erratum 754327 is disabled, or:
1: dmb nop nop nop nop nop nop nop nop nop nop wfe b 1b
when erratum 754327 is enabled. We also get the dmb + 10 nop sequence elsewhere in the kernel, in terminating loops.
This is reasonable - it means we get the workaround for erratum 794072 when erratum 754327 is enabled, but still relinquish the dead processor - either by placing it in a lower power mode when wfe is implemented as such or by returning it to the hypervisior, or in the case where wfe is a no-op, we use the workaround specified in erratum 794072 to avoid the problem.
These as two entirely orthogonal problems - the 10 nops addresses erratum 794072, and the wfe is an optimisation that makes the system more efficient when crashed either in terms of power consumption or by allowing the host/other VMs to make use of the CPU.
I don't see any reason not to use kexec() inside a VM - it has the potential to provide automated recovery from a failure of the VMs kernel with the opportunity for saving a crashdump of the failure. A panic() with a reboot timeout won't do that, and reading the libvirt documentation, setting on_reboot to "preserve" won't either (the documentation states "The preserve action for an on_reboot event is treated as a destroy".) Surely it has to be a good thing to avoiding having CPUs spinning inside a VM that is doing no useful work.
Acked-by: Will Deacon will.deacon@arm.com Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/barrier.h | 2 ++ arch/arm/include/asm/processor.h | 6 +++++- arch/arm/kernel/machine_kexec.c | 5 ++++- arch/arm/kernel/smp.c | 4 +++- arch/arm/mach-omap2/prm_common.c | 4 +++- 5 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h index 69772e742a0a..83ae97c049d9 100644 --- a/arch/arm/include/asm/barrier.h +++ b/arch/arm/include/asm/barrier.h @@ -11,6 +11,8 @@ #define sev() __asm__ __volatile__ ("sev" : : : "memory") #define wfe() __asm__ __volatile__ ("wfe" : : : "memory") #define wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#else +#define wfe() do { } while (0) #endif
#if __LINUX_ARM_ARCH__ >= 7 diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 1bf65b47808a..cb2a3423b714 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -95,7 +95,11 @@ extern void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p);
#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327) -#define cpu_relax() smp_mb() +#define cpu_relax() \ + do { \ + smp_mb(); \ + __asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \ + } while (0) #else #define cpu_relax() barrier() #endif diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index dd2eb5f76b9f..76300f3813e8 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -91,8 +91,11 @@ void machine_crash_nonpanic_core(void *unused)
set_cpu_online(smp_processor_id(), false); atomic_dec(&waiting_for_crash_ipi); - while (1) + + while (1) { cpu_relax(); + wfe(); + } }
void crash_smp_send_stop(void) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 1d6f5ea522f4..a3ce7c5365fa 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -604,8 +604,10 @@ static void ipi_cpu_stop(unsigned int cpu) local_fiq_disable(); local_irq_disable();
- while (1) + while (1) { cpu_relax(); + wfe(); + } }
static DEFINE_PER_CPU(struct completion *, cpu_completion); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 058a37e6d11c..fd6e0671f957 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -523,8 +523,10 @@ void omap_prm_reset_system(void)
prm_ll_data->reset_system();
- while (1) + while (1) { cpu_relax(); + wfe(); + } }
/**
From: Paolo Valente paolo.valente@linaro.org
[ Upstream commit 058fdecc6de7cdecbf4c59b851e80eb2d6c5295f ]
When a new I/O request arrives for a bfq_queue, say Q, bfq checks whether that request is close to (a) the head request of some other queue waiting to be served, or (b) the last request dispatched for the in-service queue (in case Q itself is not the in-service queue)
If a queue, say Q2, is found for which the above condition holds, then bfq merges Q and Q2, to hopefully get a more sequential I/O in the resulting merged queue, and thus a possibly higher throughput.
Case (b) is checked by comparing the new request for Q with the last request dispatched, assuming that the latter necessarily belonged to the in-service queue. Unfortunately, this assumption is no longer always correct, since commit d0edc2473be9 ("block, bfq: inject other-queue I/O into seeky idle queues on NCQ flash").
When the assumption does not hold, queues that must not be merged may be merged, causing unexpected loss of control on per-queue service guarantees.
This commit solves this problem by adding an extra field, which stores the actual last request dispatched for the in-service queue, and by using this new field to correctly check case (b).
Signed-off-by: Paolo Valente paolo.valente@linaro.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-iosched.c | 5 ++++- block/bfq-iosched.h | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 653100fb719e..c5e2c5a01182 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2215,7 +2215,8 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
if (in_service_bfqq && in_service_bfqq != bfqq && likely(in_service_bfqq != &bfqd->oom_bfqq) && - bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && + bfq_rq_close_to_sector(io_struct, request, + bfqd->in_serv_last_pos) && bfqq->entity.parent == in_service_bfqq->entity.parent && bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) { new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); @@ -2755,6 +2756,8 @@ static void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq) bfq_update_rate_reset(bfqd, rq); update_last_values: bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); + if (RQ_BFQQ(rq) == bfqd->in_service_queue) + bfqd->in_serv_last_pos = bfqd->last_position; bfqd->last_dispatch = now_ns; }
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h index a8a2e5aca4d4..d5e9e60cb1a5 100644 --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -469,6 +469,9 @@ struct bfq_data { /* on-disk position of the last served request */ sector_t last_position;
+ /* position of the last served request for the in-service queue */ + sector_t in_serv_last_pos; + /* time of last request completion (ns) */ u64 last_completion;
From: Valdis Kletnieks valdis.kletnieks@vt.edu
[ Upstream commit 116bfa96a255123ed209da6544f74a4f2eaca5da ]
Compiling with W=1 generates warnings:
CC kernel/bpf/core.o kernel/bpf/core.c:721:12: warning: no previous prototype for ?bpf_jit_alloc_exec_limit? [-Wmissing-prototypes] 721 | u64 __weak bpf_jit_alloc_exec_limit(void) | ^~~~~~~~~~~~~~~~~~~~~~~~ kernel/bpf/core.c:757:14: warning: no previous prototype for ?bpf_jit_alloc_exec? [-Wmissing-prototypes] 757 | void *__weak bpf_jit_alloc_exec(unsigned long size) | ^~~~~~~~~~~~~~~~~~ kernel/bpf/core.c:762:13: warning: no previous prototype for ?bpf_jit_free_exec? [-Wmissing-prototypes] 762 | void __weak bpf_jit_free_exec(void *addr) | ^~~~~~~~~~~~~~~~~
All three are weak functions that archs can override, provide proper prototypes for when a new arch provides their own.
Signed-off-by: Valdis Kletnieks valdis.kletnieks@vt.edu Acked-by: Song Liu songliubraving@fb.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/filter.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h index 1a39d57eb88f..037610845892 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -844,7 +844,9 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, unsigned int alignment, bpf_jit_fill_hole_t bpf_fill_ill_insns); void bpf_jit_binary_free(struct bpf_binary_header *hdr); - +u64 bpf_jit_alloc_exec_limit(void); +void *bpf_jit_alloc_exec(unsigned long size); +void bpf_jit_free_exec(void *addr); void bpf_jit_free(struct bpf_prog *fp);
struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *fp);
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 8184d44c9a577a2f1842ed6cc844bfd4a9981d8e ]
Use recently introduced bpf_probe_prog_type() to skip tests in the test_verifier() if bpf_verify_program() fails. The skipped test is indicated in the output.
Example:
... 679/p bpf_get_stack return R0 within range SKIP (unsupported program type 5) 680/p ld_abs: invalid op 1 OK ... Summary: 863 PASSED, 165 SKIPPED, 3 FAILED
Signed-off-by: Stanislav Fomichev sdf@google.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_verifier.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 9db5a7378f40..294fc18aba2a 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -32,6 +32,7 @@ #include <linux/if_ether.h>
#include <bpf/bpf.h> +#include <bpf/libbpf.h>
#ifdef HAVE_GENHDR # include "autoconf.h" @@ -56,6 +57,7 @@
#define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled" static bool unpriv_disabled = false; +static int skips;
struct bpf_test { const char *descr; @@ -12770,6 +12772,11 @@ static void do_test_single(struct bpf_test *test, bool unpriv, fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT, "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1); + if (fd_prog < 0 && !bpf_probe_prog_type(prog_type, 0)) { + printf("SKIP (unsupported program type %d)\n", prog_type); + skips++; + goto close_fds; + }
expected_ret = unpriv && test->result_unpriv != UNDEF ? test->result_unpriv : test->result; @@ -12905,7 +12912,7 @@ static void get_unpriv_disabled()
static int do_test(bool unpriv, unsigned int from, unsigned int to) { - int i, passes = 0, errors = 0, skips = 0; + int i, passes = 0, errors = 0;
for (i = from; i < to; i++) { struct bpf_test *test = &tests[i];
From: Nicolai Stange nstange@suse.de
[ Upstream commit eddd0b332304d554ad6243942f87c2fcea98c56b ]
The ppc64 specific implementation of the reliable stacktracer, save_stack_trace_tsk_reliable(), bails out and reports an "unreliable trace" whenever it finds an exception frame on the stack. Stack frames are classified as exception frames if the STACK_FRAME_REGS_MARKER magic, as written by exception prologues, is found at a particular location.
However, as observed by Joe Lawrence, it is possible in practice that non-exception stack frames can alias with prior exception frames and thus, that the reliable stacktracer can find a stale STACK_FRAME_REGS_MARKER on the stack. It in turn falsely reports an unreliable stacktrace and blocks any live patching transition to finish. Said condition lasts until the stack frame is overwritten/initialized by function call or other means.
In principle, we could mitigate this by making the exception frame classification condition in save_stack_trace_tsk_reliable() stronger: in addition to testing for STACK_FRAME_REGS_MARKER, we could also take into account that for all exceptions executing on the kernel stack - their stack frames's backlink pointers always match what is saved in their pt_regs instance's ->gpr[1] slot and that - their exception frame size equals STACK_INT_FRAME_SIZE, a value uncommonly large for non-exception frames.
However, while these are currently true, relying on them would make the reliable stacktrace implementation more sensitive towards future changes in the exception entry code. Note that false negatives, i.e. not detecting exception frames, would silently break the live patching consistency model.
Furthermore, certain other places (diagnostic stacktraces, perf, xmon) rely on STACK_FRAME_REGS_MARKER as well.
Make the exception exit code clear the on-stack STACK_FRAME_REGS_MARKER for those exceptions running on the "normal" kernel stack and returning to kernelspace: because the topmost frame is ignored by the reliable stack tracer anyway, returns to userspace don't need to take care of clearing the marker.
Furthermore, as I don't have the ability to test this on Book 3E or 32 bits, limit the change to Book 3S and 64 bits.
Fixes: df78d3f61480 ("powerpc/livepatch: Implement reliable stack tracing for the consistency model") Reported-by: Joe Lawrence joe.lawrence@redhat.com Signed-off-by: Nicolai Stange nstange@suse.de Signed-off-by: Joe Lawrence joe.lawrence@redhat.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/entry_64.S | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2206912ea4f0..1f39ce40ae11 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -989,6 +989,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ld r2,_NIP(r1) mtspr SPRN_SRR0,r2
+ /* + * Leaving a stale exception_marker on the stack can confuse + * the reliable stack unwinder later on. Clear it. + */ + li r2,0 + std r2,STACK_FRAME_OVERHEAD-16(r1) + ld r0,GPR0(r1) ld r2,GPR2(r1) ld r3,GPR3(r1)
From: Oleg Nesterov oleg@redhat.com
[ Upstream commit 51bee5abeab2058ea5813c5615d6197a23dbf041 ]
The only user of cgroup_subsys->free() callback is pids_cgrp_subsys which needs pids_free() to uncharge the pid.
However, ->free() is called from __put_task_struct()->cgroup_free() and this is too late. Even the trivial program which does
for (;;) { int pid = fork(); assert(pid >= 0); if (pid) wait(NULL); else exit(0); }
can run out of limits because release_task()->call_rcu(delayed_put_task_struct) implies an RCU gp after the task/pid goes away and before the final put().
Test-case:
mkdir -p /tmp/CG mount -t cgroup2 none /tmp/CG echo '+pids' > /tmp/CG/cgroup.subtree_control
mkdir /tmp/CG/PID echo 2 > /tmp/CG/PID/pids.max
perl -e 'while ($p = fork) { wait; } $p // die "fork failed: $!\n"' & echo $! > /tmp/CG/PID/cgroup.procs
Without this patch the forking process fails soon after migration.
Rename cgroup_subsys->free() to cgroup_subsys->release() and move the callsite into the new helper, cgroup_release(), called by release_task() which actually frees the pid(s).
Reported-by: Herton R. Krzesinski hkrzesin@redhat.com Reported-by: Jan Stancek jstancek@redhat.com Signed-off-by: Oleg Nesterov oleg@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/cgroup-defs.h | 2 +- include/linux/cgroup.h | 2 ++ kernel/cgroup/cgroup.c | 15 +++++++++------ kernel/cgroup/pids.c | 4 ++-- kernel/exit.c | 1 + 5 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 22254c1fe1c5..6002275937f5 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -597,7 +597,7 @@ struct cgroup_subsys { void (*cancel_fork)(struct task_struct *task); void (*fork)(struct task_struct *task); void (*exit)(struct task_struct *task); - void (*free)(struct task_struct *task); + void (*release)(struct task_struct *task); void (*bind)(struct cgroup_subsys_state *root_css);
bool early_init:1; diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 32c553556bbd..ca51b2c15bcc 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -119,6 +119,7 @@ extern int cgroup_can_fork(struct task_struct *p); extern void cgroup_cancel_fork(struct task_struct *p); extern void cgroup_post_fork(struct task_struct *p); void cgroup_exit(struct task_struct *p); +void cgroup_release(struct task_struct *p); void cgroup_free(struct task_struct *p);
int cgroup_init_early(void); @@ -699,6 +700,7 @@ static inline int cgroup_can_fork(struct task_struct *p) { return 0; } static inline void cgroup_cancel_fork(struct task_struct *p) {} static inline void cgroup_post_fork(struct task_struct *p) {} static inline void cgroup_exit(struct task_struct *p) {} +static inline void cgroup_release(struct task_struct *p) {} static inline void cgroup_free(struct task_struct *p) {}
static inline int cgroup_init_early(void) { return 0; } diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index e710ac7fbbbf..63dae7e0ccae 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -195,7 +195,7 @@ static u64 css_serial_nr_next = 1; */ static u16 have_fork_callback __read_mostly; static u16 have_exit_callback __read_mostly; -static u16 have_free_callback __read_mostly; +static u16 have_release_callback __read_mostly; static u16 have_canfork_callback __read_mostly;
/* cgroup namespace for init task */ @@ -5240,7 +5240,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
have_fork_callback |= (bool)ss->fork << ss->id; have_exit_callback |= (bool)ss->exit << ss->id; - have_free_callback |= (bool)ss->free << ss->id; + have_release_callback |= (bool)ss->release << ss->id; have_canfork_callback |= (bool)ss->can_fork << ss->id;
/* At system boot, before all subsystems have been @@ -5676,16 +5676,19 @@ void cgroup_exit(struct task_struct *tsk) } while_each_subsys_mask(); }
-void cgroup_free(struct task_struct *task) +void cgroup_release(struct task_struct *task) { - struct css_set *cset = task_css_set(task); struct cgroup_subsys *ss; int ssid;
- do_each_subsys_mask(ss, ssid, have_free_callback) { - ss->free(task); + do_each_subsys_mask(ss, ssid, have_release_callback) { + ss->release(task); } while_each_subsys_mask(); +}
+void cgroup_free(struct task_struct *task) +{ + struct css_set *cset = task_css_set(task); put_css_set(cset); }
diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c index 9829c67ebc0a..c9960baaa14f 100644 --- a/kernel/cgroup/pids.c +++ b/kernel/cgroup/pids.c @@ -247,7 +247,7 @@ static void pids_cancel_fork(struct task_struct *task) pids_uncharge(pids, 1); }
-static void pids_free(struct task_struct *task) +static void pids_release(struct task_struct *task) { struct pids_cgroup *pids = css_pids(task_css(task, pids_cgrp_id));
@@ -342,7 +342,7 @@ struct cgroup_subsys pids_cgrp_subsys = { .cancel_attach = pids_cancel_attach, .can_fork = pids_can_fork, .cancel_fork = pids_cancel_fork, - .free = pids_free, + .release = pids_release, .legacy_cftypes = pids_files, .dfl_cftypes = pids_files, .threaded = true, diff --git a/kernel/exit.c b/kernel/exit.c index d607e23fd0c3..5c0964dc805a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -219,6 +219,7 @@ void release_task(struct task_struct *p) }
write_unlock_irq(&tasklist_lock); + cgroup_release(p); release_thread(p); call_rcu(&p->rcu, delayed_put_task_struct);
From: Chen-Yu Tsai wens@csie.org
[ Upstream commit cec2b18832e26bc866bef2be22eff4e25bbc4034 ]
gpiod_get_value() gives out a warning if access to the underlying gpiochip requires sleeping, which is common for I2C based chips:
WARNING: CPU: 0 PID: 77 at drivers/gpio/gpiolib.c:2500 gpiod_get_value+0xd0/0x100 Modules linked in: CPU: 0 PID: 77 Comm: kworker/0:2 Not tainted 4.14.0-rc3-00589-gf32897915d48-dirty #90 Hardware name: Allwinner sun4i/sun5i Families Workqueue: events deferred_probe_work_func [<c010ec50>] (unwind_backtrace) from [<c010b784>] (show_stack+0x10/0x14) [<c010b784>] (show_stack) from [<c0797224>] (dump_stack+0x88/0x9c) [<c0797224>] (dump_stack) from [<c0125b08>] (__warn+0xe8/0x100) [<c0125b08>] (__warn) from [<c0125bd0>] (warn_slowpath_null+0x20/0x28) [<c0125bd0>] (warn_slowpath_null) from [<c037069c>] (gpiod_get_value+0xd0/0x100) [<c037069c>] (gpiod_get_value) from [<c03778d0>] (pwm_backlight_probe+0x238/0x508) [<c03778d0>] (pwm_backlight_probe) from [<c0411a2c>] (platform_drv_probe+0x50/0xac) [<c0411a2c>] (platform_drv_probe) from [<c0410224>] (driver_probe_device+0x238/0x2e8) [<c0410224>] (driver_probe_device) from [<c040e820>] (bus_for_each_drv+0x44/0x94) [<c040e820>] (bus_for_each_drv) from [<c040ff0c>] (__device_attach+0xb0/0x114) [<c040ff0c>] (__device_attach) from [<c040f4f8>] (bus_probe_device+0x84/0x8c) [<c040f4f8>] (bus_probe_device) from [<c040f944>] (deferred_probe_work_func+0x50/0x14c) [<c040f944>] (deferred_probe_work_func) from [<c013be84>] (process_one_work+0x1ec/0x414) [<c013be84>] (process_one_work) from [<c013ce5c>] (worker_thread+0x2b0/0x5a0) [<c013ce5c>] (worker_thread) from [<c0141908>] (kthread+0x14c/0x154) [<c0141908>] (kthread) from [<c0107ab0>] (ret_from_fork+0x14/0x24)
This was missed in commit 0c9501f823a4 ("backlight: pwm_bl: Handle gpio that can sleep"). The code was then moved to a separate function in commit 7613c922315e ("backlight: pwm_bl: Move the checks for initial power state to a separate function").
The only usage of gpiod_get_value() is during the probe stage, which is safe to sleep in. Switch to gpiod_get_value_cansleep().
Fixes: 0c9501f823a4 ("backlight: pwm_bl: Handle gpio that can sleep") Signed-off-by: Chen-Yu Tsai wens@csie.org Acked-by: Maxime Ripard maxime.ripard@bootlin.com Acked-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/backlight/pwm_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 6bde543452f2..7ddc0930e98c 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -425,7 +425,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) */
/* if the enable GPIO is disabled, do not enable the backlight */ - if (pb->enable_gpio && gpiod_get_value(pb->enable_gpio) == 0) + if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0) return FB_BLANK_POWERDOWN;
/* The regulator is disabled, do not enable the backlight */
From: Manfred Schlaegl manfred.schlaegl@ginzinger.com
[ Upstream commit 7ab57b76ebf632bf2231ccabe26bea33868118c6 ]
We increase the default limit for buffer memory allocation by a factor of 10 to 640K to prevent data loss when using fast serial interfaces.
For example when using RS485 without flow-control at speeds of 1Mbit/s an upwards we've run into problems such as applications being too slow to read out this buffer (on embedded devices based on imx53 or imx6).
If you want to write transmitted data to a slow SD card and thus have realtime requirements, this limit can become a problem.
That shouldn't be the case and 640K buffers fix such problems for us.
This value is a maximum limit for allocation only. It has no effect on systems that currently run fine. When transmission is slow enough applications and hardware can keep up and increasing this limit doesn't change anything.
It only _allows_ to allocate more than 2*64K in cases we currently fail to allocate memory despite having some.
Signed-off-by: Manfred Schlaegl manfred.schlaegl@ginzinger.com Signed-off-by: Martin Kepplinger martin.kepplinger@ginzinger.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index ae3ce330200e..ee3aa57bc0e7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -26,7 +26,7 @@ * Byte threshold to limit memory consumption for flip buffers. * The actual memory limit is > 2x this amount. */ -#define TTYB_DEFAULT_MEM_LIMIT 65536 +#define TTYB_DEFAULT_MEM_LIMIT (640 * 1024UL)
/* * We default to dicing tty buffer allocations to this many characters
From: Nathan Fontenot nfont@linux.vnet.ibm.com
[ Upstream commit 81b61324922c67f73813d8a9c175f3c153f6a1c6 ]
On pseries systems, performing a partition migration can result in altering the nodes a CPU is assigned to on the destination system. For exampl, pre-migration on the source system CPUs are in node 1 and 3, post-migration on the destination system CPUs are in nodes 2 and 3.
Handling the node change for a CPU can cause corruption in the slab cache if we hit a timing where a CPUs node is changed while cache_reap() is invoked. The corruption occurs because the slab cache code appears to rely on the CPU and slab cache pages being on the same node.
The current dynamic updating of a CPUs node done in arch/powerpc/mm/numa.c does not prevent us from hitting this scenario.
Changing the device tree property update notification handler that recognizes an affinity change for a CPU to do a full DLPAR remove and add of the CPU instead of dynamically changing its node resolves this issue.
Signed-off-by: Nathan Fontenot nfont@linux.vnet.ibm.com Signed-off-by: Michael W. Bringmann mwb@linux.vnet.ibm.com Tested-by: Michael W. Bringmann mwb@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/topology.h | 2 ++ arch/powerpc/mm/numa.c | 9 +-------- arch/powerpc/platforms/pseries/hotplug-cpu.c | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index a4a718dbfec6..f85e2b01c3df 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -132,6 +132,8 @@ static inline void shared_proc_topology_init(void) {} #define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_core_id(cpu) (cpu_to_core_id(cpu)) + +int dlpar_cpu_readd(int cpu); #endif #endif
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 5500e4edabc6..10fb43efef50 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1461,13 +1461,6 @@ static void reset_topology_timer(void)
#ifdef CONFIG_SMP
-static void stage_topology_update(int core_id) -{ - cpumask_or(&cpu_associativity_changes_mask, - &cpu_associativity_changes_mask, cpu_sibling_mask(core_id)); - reset_topology_timer(); -} - static int dt_update_callback(struct notifier_block *nb, unsigned long action, void *data) { @@ -1480,7 +1473,7 @@ static int dt_update_callback(struct notifier_block *nb, !of_prop_cmp(update->prop->name, "ibm,associativity")) { u32 core_id; of_property_read_u32(update->dn, "reg", &core_id); - stage_topology_update(core_id); + rc = dlpar_cpu_readd(core_id); rc = NOTIFY_OK; } break; diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6ef77caf7bcf..1d3f9313c02f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -802,6 +802,25 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add) return rc; }
+int dlpar_cpu_readd(int cpu) +{ + struct device_node *dn; + struct device *dev; + u32 drc_index; + int rc; + + dev = get_cpu_device(cpu); + dn = dev->of_node; + + rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index); + + rc = dlpar_cpu_remove_by_index(drc_index); + if (!rc) + rc = dlpar_cpu_add(drc_index); + + return rc; +} + int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) { u32 count, drc_index;
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 428da2bdb05d76c48d0bd8fbfa2e4c102685be08 ]
[Why] In order to read CRC events when CRC capture is enabled the vblank interrput handler needs to be running for the CRTC. The handler is enabled while there is an active vblank reference.
When running IGT tests there will often be no active vblank reference but the test expects to read a CRC value. This is valid usage (and works on i915 since they have a CRC interrupt handler) so the reference to the vblank should be grabbed while capture is active.
This issue was found running:
igt@kms_plane_multiple@atomic-pipe-b-tiling-none
The pipe-b is the only one in the initial commit and was not previously active so no vblank reference is grabbed. The vblank interrupt is not enabled and the test times out.
[How] Keep a reference to the vblank as long as CRC capture is enabled. If userspace never explicitly disables it then the reference is also dropped when removing the CRTC from the context (stream = NULL).
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Harry Wentland Harry.Wentland@amd.com Reviewed-by: Sun peng Li Sunpeng.Li@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++- .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 42 +++++++++---------- 2 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c57e85f08e23..2b8b892eb846 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4390,10 +4390,22 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
- if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream) + if (drm_atomic_crtc_needs_modeset(new_crtc_state) + && dm_old_crtc_state->stream) { + /* + * CRC capture was enabled but not disabled. + * Release the vblank reference. + */ + if (dm_new_crtc_state->crc_enabled) { + drm_crtc_vblank_put(crtc); + dm_new_crtc_state->crc_enabled = false; + } + manage_dm_interrupts(adev, acrtc, false); + } } /* Add check here for SoC's that support hardware cursor plane, to * unset legacy_cursor_update */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index 6a6d977ddd7a..36a0bed9af07 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -51,6 +51,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name, { struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state); struct dc_stream_state *stream_state = crtc_state->stream; + bool enable;
enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
@@ -65,28 +66,27 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name, return -EINVAL; }
+ enable = (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO); + + if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state, + enable, enable)) + return -EINVAL; + /* When enabling CRC, we should also disable dithering. */ - if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) { - if (dc_stream_configure_crc(stream_state->ctx->dc, - stream_state, - true, true)) { - crtc_state->crc_enabled = true; - dc_stream_set_dither_option(stream_state, - DITHER_OPTION_TRUN8); - } - else - return -EINVAL; - } else { - if (dc_stream_configure_crc(stream_state->ctx->dc, - stream_state, - false, false)) { - crtc_state->crc_enabled = false; - dc_stream_set_dither_option(stream_state, - DITHER_OPTION_DEFAULT); - } - else - return -EINVAL; - } + dc_stream_set_dither_option(stream_state, + enable ? DITHER_OPTION_TRUN8 + : DITHER_OPTION_DEFAULT); + + /* + * Reading the CRC requires the vblank interrupt handler to be + * enabled. Keep a reference until CRC capture stops. + */ + if (!crtc_state->crc_enabled && enable) + drm_crtc_vblank_get(crtc); + else if (crtc_state->crc_enabled && !enable) + drm_crtc_vblank_put(crtc); + + crtc_state->crc_enabled = enable;
*values_cnt = 3; /* Reset crc_skipped on dm state */
From: Takashi Sakamoto o-takashi@sakamocchi.jp
[ Upstream commit b2e9e1c8810ee05c95f4d55800b8afae70ab01b4 ]
Duende Classic was produced by Solid State Logic in 2006, as a first model of Duende DSP series. The following model, Duende Mini was produced in 2008. They are designed to receive isochronous packets for PCM frames via IEEE 1394 bus, perform signal processing by downloaded program, then transfer isochronous packets for converted PCM frames.
These two models includes the same embedded board, consists of several ICs below: - Texus Instruments Inc, TSB41AB3 for physical layer of IEEE 1394 bus - WaveFront semiconductor, DICE II STD ASIC for link/protocol layer - Altera MAX 3000A CPLD for programs - Analog devices, SHARC ADSP-21363 for signal processing (4 chips)
This commit adds support for the two models to ALSA dice driver. Like support for the other devices, packet streaming is just available. Userspace applications should be developed if full features became available; e.g. program uploader and parameter controller.
$ ./hinawa-config-rom-printer /dev/fw1 { 'bus-info': { 'adj': False, 'bmc': False, 'chip_ID': 349771402425, 'cmc': True, 'cyc_clk_acc': 255, 'generation': 1, 'imc': True, 'isc': True, 'link_spd': 2, 'max_ROM': 1, 'max_rec': 512, 'name': '1394', 'node_vendor_ID': 20674, 'pmc': False}, 'root-directory': [ ['VENDOR', 20674], ['DESCRIPTOR', 'Solid State Logic'], ['MODEL', 112], ['DESCRIPTOR', 'Duende board'], [ 'NODE_CAPABILITIES', { 'addressing': {'64': True, 'fix': True, 'prv': True}, 'misc': {'int': False, 'ms': False, 'spt': True}, 'state': { 'atn': False, 'ded': False, 'drq': True, 'elo': False, 'init': False, 'lst': True, 'off': False}, 'testing': {'bas': False, 'ext': False}}], [ 'UNIT', [ ['SPECIFIER_ID', 20674], ['VERSION', 1], ['MODEL', 112], ['DESCRIPTOR', 'Duende board']]]]}
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/firewire/dice/dice.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 774eb2205668..3d600f498914 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c @@ -18,6 +18,7 @@ MODULE_LICENSE("GPL v2"); #define OUI_ALESIS 0x000595 #define OUI_MAUDIO 0x000d6c #define OUI_MYTEK 0x001ee8 +#define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE.
#define DICE_CATEGORY_ID 0x04 #define WEISS_CATEGORY_ID 0x00 @@ -216,7 +217,7 @@ static int dice_probe(struct fw_unit *unit, struct snd_dice *dice; int err;
- if (!entry->driver_data) { + if (!entry->driver_data && entry->vendor_id != OUI_SSL) { err = check_dice_category(unit); if (err < 0) return -ENODEV; @@ -382,6 +383,15 @@ static const struct ieee1394_device_id dice_id_table[] = { .model_id = 0x000002, .driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats, }, + // Solid State Logic, Duende Classic and Mini. + // NOTE: each field of GUID in config ROM is not compliant to standard + // DICE scheme. + { + .match_flags = IEEE1394_MATCH_VENDOR_ID | + IEEE1394_MATCH_MODEL_ID, + .vendor_id = OUI_SSL, + .model_id = 0x000070, + }, { .match_flags = IEEE1394_MATCH_VERSION, .version = DICE_INTERFACE,
From: Roger Quadros rogerq@ti.com
[ Upstream commit 169e3b68cadb5775daca009ced4faf01ffd97dcf ]
On v3.10a in dual-role mode, if port is in device mode and gadget driver isn't loaded, the OTG event interrupts don't come through.
It seems that if the core is configured to be OTG2.0 only, then we can't leave the DCFG.DEVSPD at Super-speed (default) if we expect OTG to work properly. It must be set to High-speed.
Fix this issue by configuring DCFG.DEVSPD to the supported maximum speed at gadget init. Device tree still needs to provide correct supported maximum speed for this to work.
This issue wasn't present on v2.40a but is seen on v3.10a. It doesn't cause any side effects on v2.40a.
Signed-off-by: Roger Quadros rogerq@ti.com Signed-off-by: Sekhar Nori nsekhar@ti.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 700fb626ad03..524104eed8a7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3233,6 +3233,8 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err4; }
+ dwc3_gadget_set_speed(&dwc->gadget, dwc->maximum_speed); + return 0;
err4:
From: Jérôme de Bretagne jerome.debretagne@gmail.com
[ Upstream commit e97a34563d18606ee5db93e495382a967f999cd4 ]
Power button suspend for some Dell models was added in:
commit 821b85366284 ("platform/x86: intel-hid: Power button suspend on Dell Latitude 7275")
by checking against the power button press notification (0xCE) to report the power button press event. The corresponding power button release notification (0xCF) was caught and ignored to stop it from being reported as an "unknown event" in the logs.
The missing button release event is creating issues on Android-x86, as reported on the project mailing list for a Dell Latitude 5175 model, since the events are expected in down/up pairs.
Report the power button release event to fix this issue.
Link: https://groups.google.com/forum/#%21topic/android-x86/aSwZK9Nf9Ro Tested-by: Tristian Celestin tristian.celestin@outlook.com Tested-by: Jérôme de Bretagne jerome.debretagne@gmail.com Signed-off-by: Jérôme de Bretagne jerome.debretagne@gmail.com Reviewed-by: Mario Limonciello mario.limonciello@dell.com [dvhart: corrected commit reference format per checkpatch] Signed-off-by: Darren Hart (VMware) dvhart@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel-hid.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c index 6cf9b7fa5bf0..3201a83073b5 100644 --- a/drivers/platform/x86/intel-hid.c +++ b/drivers/platform/x86/intel-hid.c @@ -373,7 +373,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) * the 5-button array, but still send notifies with power button * event code to this device object on power button actions. * - * Report the power button press; catch and ignore the button release. + * Report the power button press and release. */ if (!priv->array) { if (event == 0xce) { @@ -382,8 +382,11 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) return; }
- if (event == 0xcf) + if (event == 0xcf) { + input_report_key(priv->input_dev, KEY_POWER, 0); + input_sync(priv->input_dev); return; + } }
/* 0xC0 is for HID events, other values are for 5 button array */
From: Tony Jones tonyj@suse.de
[ Upstream commit 72e0b15cb24a497d7d0d4707cf51ff40c185ae8c ]
With Python3. PyUnicode_FromStringAndSize is unsafe to call on attr and will return NULL. Use _PyBytes_FromStringAndSize (as with raw_buf).
Below is the observed behavior without the fix. Note it is first necessary to apply the prior fix (Add trace_context extension module to sys,modules):
# ldd /usr/bin/perf | grep -i python libpython3.6m.so.1.0 => /usr/lib64/libpython3.6m.so.1.0 (0x00007f8e1dfb2000)
# perf record -e raw_syscalls:sys_enter /bin/false [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.018 MB perf.data (21 samples) ]
# perf script -g python | cat generated Python script: perf-script.py
# perf script -s ./perf-script.py in trace_begin Segmentation fault (core dumped)
Signed-off-by: Tony Jones tonyj@suse.de Acked-by: Jiri Olsa jolsa@kernel.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jaroslav Škarvada jskarvad@redhat.com Cc: Jonathan Corbet corbet@lwn.net Cc: Ravi Bangoria ravi.bangoria@linux.ibm.com Cc: Seeteena Thoufeek s1seetee@linux.vnet.ibm.com Fixes: 66dfdff03d19 ("perf tools: Add Python 3 support") Link: http://lkml.kernel.org/r/20190124005229.16146-3-tonyj@suse.de Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/scripting-engines/trace-event-python.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 05d95de14e20..fb11396ec861 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -733,8 +733,7 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, Py_FatalError("couldn't create Python dictionary");
pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel))); - pydict_set_item_string_decref(dict, "attr", _PyUnicode_FromStringAndSize( - (const char *)&evsel->attr, sizeof(evsel->attr))); + pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->attr, sizeof(evsel->attr)));
pydict_set_item_string_decref(dict_sample, "pid", _PyLong_FromLong(sample->pid));
From: Tony Jones tonyj@suse.de
[ Upstream commit cc437642255224e4140fed1f3e3156fc8ad91903 ]
In Python3, the result of PyModule_Create (called from scripts/python/Perf-Trace-Util/Context.c) is not automatically added to sys.modules. See: https://bugs.python.org/issue4592
Below is the observed behavior without the fix:
# ldd /usr/bin/perf | grep -i python libpython3.6m.so.1.0 => /usr/lib64/libpython3.6m.so.1.0 (0x00007f8e1dfb2000)
# perf record /bin/false [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.015 MB perf.data (17 samples) ]
# perf script -g python | cat generated Python script: perf-script.py
# perf script -s ./perf-script.py Traceback (most recent call last): File "./perf-script.py", line 18, in <module> from perf_trace_context import * ModuleNotFoundError: No module named 'perf_trace_context' Error running python script ./perf-script.py #
Committer notes:
To build with python3 use:
$ make -C tools/perf PYTHON=python3
Use a non-const variable to pass the 'name' arg to PyImport_AppendInittab(), as python2.6 has that as 'char *', which ends up trowing this in some environments:
CC /tmp/build/perf/util/parse-branch-options.o util/scripting-engines/trace-event-python.c: In function 'python_start_script': util/scripting-engines/trace-event-python.c:1520:2: error: passing argument 1 of 'PyImport_AppendInittab' discards 'const' qualifier from pointer target type [-Werror] PyImport_AppendInittab("perf_trace_context", initfunc); ^ In file included from /usr/include/python2.6/Python.h:130:0, from util/scripting-engines/trace-event-python.c:22: /usr/include/python2.6/import.h:54:17: note: expected 'char *' but argument is of type 'const char *' PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void)); ^ cc1: all warnings being treated as errors
Signed-off-by: Tony Jones tonyj@suse.de Acked-by: Jiri Olsa jolsa@kernel.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jaroslav Škarvada jskarvad@redhat.com Cc: Jonathan Corbet corbet@lwn.net Cc: Ravi Bangoria ravi.bangoria@linux.ibm.com Cc: Seeteena Thoufeek s1seetee@linux.vnet.ibm.com Fixes: 66dfdff03d19 ("perf tools: Add Python 3 support") Link: http://lkml.kernel.org/r/20190124005229.16146-2-tonyj@suse.de Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../perf/util/scripting-engines/trace-event-python.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index fb11396ec861..9569cc06e0a7 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1493,34 +1493,40 @@ static void _free_command_line(wchar_t **command_line, int num) static int python_start_script(const char *script, int argc, const char **argv) { struct tables *tables = &tables_global; + PyMODINIT_FUNC (*initfunc)(void); #if PY_MAJOR_VERSION < 3 const char **command_line; #else wchar_t **command_line; #endif - char buf[PATH_MAX]; + /* + * Use a non-const name variable to cope with python 2.6's + * PyImport_AppendInittab prototype + */ + char buf[PATH_MAX], name[19] = "perf_trace_context"; int i, err = 0; FILE *fp;
#if PY_MAJOR_VERSION < 3 + initfunc = initperf_trace_context; command_line = malloc((argc + 1) * sizeof(const char *)); command_line[0] = script; for (i = 1; i < argc + 1; i++) command_line[i] = argv[i - 1]; #else + initfunc = PyInit_perf_trace_context; command_line = malloc((argc + 1) * sizeof(wchar_t *)); command_line[0] = Py_DecodeLocale(script, NULL); for (i = 1; i < argc + 1; i++) command_line[i] = Py_DecodeLocale(argv[i - 1], NULL); #endif
+ PyImport_AppendInittab(name, initfunc); Py_Initialize();
#if PY_MAJOR_VERSION < 3 - initperf_trace_context(); PySys_SetArgv(argc + 1, (char **)command_line); #else - PyInit_perf_trace_context(); PySys_SetArgv(argc + 1, command_line); #endif
From: Akinobu Mita akinobu.mita@gmail.com
[ Upstream commit 29856308137de1c21eda89411695f4fc6e9780ff ]
This driver sets initial frame width and height to 0x0, which is invalid. So set it to selection rectangle bounds instead.
This is detected by v4l2-compliance detected.
Cc: Enrico Scholz enrico.scholz@sigma-chemnitz.de Cc: Michael Grzeschik m.grzeschik@pengutronix.de Cc: Marco Felsch m.felsch@pengutronix.de Signed-off-by: Akinobu Mita akinobu.mita@gmail.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/mt9m111.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index efda1aa95ca0..7a7d3969af20 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -1014,6 +1014,8 @@ static int mt9m111_probe(struct i2c_client *client, mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; mt9m111->rect.width = MT9M111_MAX_WIDTH; mt9m111->rect.height = MT9M111_MAX_HEIGHT; + mt9m111->width = mt9m111->rect.width; + mt9m111->height = mt9m111->rect.height; mt9m111->fmt = &mt9m111_colour_fmts[0]; mt9m111->lastpage = -1; mutex_init(&mt9m111->power_lock);
From: David Tolnay dtolnay@gmail.com
[ Upstream commit aef027db48da56b6f25d0e54c07c8401ada6ce21 ]
The virtio-rng driver uses a completion called have_data to wait for a virtio read to be fulfilled by the hypervisor. The completion is reset before placing a buffer on the virtio queue and completed by the virtio callback once data has been written into the buffer.
Prior to this commit, the driver called init_completion on this completion both during probe as well as when registering virtio buffers as part of a hwrng read operation. The second of these init_completion calls should instead be reinit_completion because the have_data completion has already been inited by probe. As described in Documentation/scheduler/completion.txt, "Calling init_completion() twice on the same completion object is most likely a bug".
This bug was present in the initial implementation of virtio-rng in f7f510ec1957 ("virtio: An entropy device, as suggested by hpa"). Back then the have_data completion was a single static completion rather than a member of one of potentially multiple virtrng_info structs as implemented later by 08e53fbdb85c ("virtio-rng: support multiple virtio-rng devices"). The original driver incorrectly used init_completion rather than INIT_COMPLETION to reset have_data during read.
Tested by running `head -c48 /dev/random | hexdump` within crosvm, the Chrome OS virtual machine monitor, and confirming that the virtio-rng driver successfully produces random bytes from the host.
Signed-off-by: David Tolnay dtolnay@gmail.com Tested-by: David Tolnay dtolnay@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index b89df66ea1ae..7abd604e938c 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -73,7 +73,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
if (!vi->busy) { vi->busy = true; - init_completion(&vi->have_data); + reinit_completion(&vi->have_data); register_buffer(vi, buf, size); }
From: Timo Alho talho@nvidia.com
[ Upstream commit 51294bf6b9e897d595466dcda5a3f2751906a200 ]
On cases where device tree entries for fuse and clock provider are in different order, fuse driver needs to defer probing. This leads to freeing incorrect IO base address as the fuse->base variable gets overwritten once during first probe invocation. This leads to the following spew during boot:
[ 3.082285] Trying to vfree() nonexistent vm area (00000000cfe8fd94) [ 3.082308] WARNING: CPU: 5 PID: 126 at /hdd/l4t/kernel/stable/mm/vmalloc.c:1511 __vunmap+0xcc/0xd8 [ 3.082318] Modules linked in: [ 3.082330] CPU: 5 PID: 126 Comm: kworker/5:1 Tainted: G S 4.19.7-tegra-gce119d3 #1 [ 3.082340] Hardware name: quill (DT) [ 3.082353] Workqueue: events deferred_probe_work_func [ 3.082364] pstate: 40000005 (nZcv daif -PAN -UAO) [ 3.082372] pc : __vunmap+0xcc/0xd8 [ 3.082379] lr : __vunmap+0xcc/0xd8 [ 3.082385] sp : ffff00000a1d3b60 [ 3.082391] x29: ffff00000a1d3b60 x28: 0000000000000000 [ 3.082402] x27: 0000000000000000 x26: ffff000008e8b610 [ 3.082413] x25: 0000000000000000 x24: 0000000000000009 [ 3.082423] x23: ffff000009221a90 x22: ffff000009f6d000 [ 3.082432] x21: 0000000000000000 x20: 0000000000000000 [ 3.082442] x19: ffff000009f6d000 x18: ffffffffffffffff [ 3.082452] x17: 0000000000000000 x16: 0000000000000000 [ 3.082462] x15: ffff0000091396c8 x14: 0720072007200720 [ 3.082471] x13: 0720072007200720 x12: 0720072907340739 [ 3.082481] x11: 0764076607380765 x10: 0766076307300730 [ 3.082491] x9 : 0730073007300730 x8 : 0730073007280720 [ 3.082501] x7 : 0761076507720761 x6 : 0000000000000102 [ 3.082510] x5 : 0000000000000000 x4 : 0000000000000000 [ 3.082519] x3 : ffffffffffffffff x2 : ffff000009150ff8 [ 3.082528] x1 : 3d95b1429fff5200 x0 : 0000000000000000 [ 3.082538] Call trace: [ 3.082545] __vunmap+0xcc/0xd8 [ 3.082552] vunmap+0x24/0x30 [ 3.082561] __iounmap+0x2c/0x38 [ 3.082569] tegra_fuse_probe+0xc8/0x118 [ 3.082577] platform_drv_probe+0x50/0xa0 [ 3.082585] really_probe+0x1b0/0x288 [ 3.082593] driver_probe_device+0x58/0x100 [ 3.082601] __device_attach_driver+0x98/0xf0 [ 3.082609] bus_for_each_drv+0x64/0xc8 [ 3.082616] __device_attach+0xd8/0x130 [ 3.082624] device_initial_probe+0x10/0x18 [ 3.082631] bus_probe_device+0x90/0x98 [ 3.082638] deferred_probe_work_func+0x74/0xb0 [ 3.082649] process_one_work+0x1e0/0x318 [ 3.082656] worker_thread+0x228/0x450 [ 3.082664] kthread+0x128/0x130 [ 3.082672] ret_from_fork+0x10/0x18 [ 3.082678] ---[ end trace 0810fe6ba772c1c7 ]---
Fix this by retaining the value of fuse->base until driver has successfully probed.
Signed-off-by: Timo Alho talho@nvidia.com Acked-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/tegra/fuse/fuse-tegra.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index a33ee8ef8b6b..51625703399e 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -137,13 +137,17 @@ static int tegra_fuse_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); fuse->phys = res->start; fuse->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(fuse->base)) - return PTR_ERR(fuse->base); + if (IS_ERR(fuse->base)) { + err = PTR_ERR(fuse->base); + fuse->base = base; + return err; + }
fuse->clk = devm_clk_get(&pdev->dev, "fuse"); if (IS_ERR(fuse->clk)) { dev_err(&pdev->dev, "failed to get FUSE clock: %ld", PTR_ERR(fuse->clk)); + fuse->base = base; return PTR_ERR(fuse->clk); }
@@ -152,8 +156,10 @@ static int tegra_fuse_probe(struct platform_device *pdev)
if (fuse->soc->probe) { err = fuse->soc->probe(fuse); - if (err < 0) + if (err < 0) { + fuse->base = base; return err; + } }
if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
From: Song Hongyan hongyan.song@intel.com
[ Upstream commit 2edefc056e4f0e6ec9508dd1aca2c18fa320efef ]
Host driver should handle interrupt mask register earlier than wake up ish FW else there will be conditions when FW interrupt comes, host PIMR register still not set ready, so move the interrupt mask setting before ish_wakeup.
Clear PISR busy_clear bit in ish_irq_handler. If not clear, there will be conditions host driver received a busy_clear interrupt (before the busy_clear mask bit is ready), it will return IRQ_NONE after check_generated_interrupt, the interrupt will never be cleared, causing the DEVICE not sending following IRQ.
Since PISR clear should not be called for the CHV device we do this change. After the change, both ISH2HOST interrupt and busy_clear interrupt will be considered as interrupt from ISH, busy_clear interrupt will return IRQ_HANDLED from IPC_IS_BUSY check.
Signed-off-by: Song Hongyan hongyan.song@intel.com Acked-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/intel-ish-hid/ipc/ipc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index bfbca7ec54ce..e00b9dbe220f 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -91,7 +91,10 @@ static bool check_generated_interrupt(struct ishtp_device *dev) IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val); } else { pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT); - interrupt_generated = IPC_INT_FROM_ISH_TO_HOST_BXT(pisr_val); + interrupt_generated = !!pisr_val; + /* only busy-clear bit is RW, others are RO */ + if (pisr_val) + ish_reg_write(dev, IPC_REG_PISR_BXT, pisr_val); }
return interrupt_generated; @@ -843,11 +846,11 @@ int ish_hw_start(struct ishtp_device *dev) { ish_set_host_rdy(dev);
+ set_host_ready(dev); + /* After that we can enable ISH DMA operation and wakeup ISHFW */ ish_wakeup(dev);
- set_host_ready(dev); - /* wait for FW-initiated reset flow */ if (!dev->recvd_hw_ready) wait_event_interruptible_timeout(dev->wait_hw_ready,
From: Marcel Holtmann marcel@holtmann.org
[ Upstream commit 7c9cbd0b5e38a1672fcd137894ace3b042dfbf69 ]
The function l2cap_get_conf_opt will return L2CAP_CONF_OPT_SIZE + opt->len as length value. The opt->len however is in control over the remote user and can be used by an attacker to gain access beyond the bounds of the actual packet.
To prevent any potential leak of heap memory, it is enough to check that the resulting len calculation after calling l2cap_get_conf_opt is not below zero. A well formed packet will always return >= 0 here and will end with the length value being zero after the last option has been parsed. In case of malformed packets messing with the opt->len field the length value will become negative. If that is the case, then just abort and ignore the option.
In case an attacker uses a too short opt->len value, then garbage will be parsed, but that is protected by the unknown option handling and also the option parameter size checks.
Signed-off-by: Marcel Holtmann marcel@holtmann.org Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Johan Hedberg johan.hedberg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/l2cap_core.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d17a4736e47c..6c873dc549b0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3336,6 +3336,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); + if (len < 0) + break;
hint = type & L2CAP_CONF_HINT; type &= L2CAP_CONF_MASK; @@ -3547,6 +3549,8 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); + if (len < 0) + break;
switch (type) { case L2CAP_CONF_MTU: @@ -3727,6 +3731,8 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); + if (len < 0) + break;
switch (type) { case L2CAP_CONF_RFC:
From: Sheng Yong shengyong1@huawei.com
[ Upstream commit ac92985864e187a1735502f6a02f54eaa655b2aa ]
When setting /sys/fs/f2fs/<DEV>/iostat_enable with non-bool value, UBSAN reports the following warning.
[ 7562.295484] ================================================================================ [ 7562.296531] UBSAN: Undefined behaviour in fs/f2fs/f2fs.h:2776:10 [ 7562.297651] load of value 64 is not a valid value for type '_Bool' [ 7562.298642] CPU: 1 PID: 7487 Comm: dd Not tainted 4.20.0-rc4+ #79 [ 7562.298653] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 7562.298662] Call Trace: [ 7562.298760] dump_stack+0x46/0x5b [ 7562.298811] ubsan_epilogue+0x9/0x40 [ 7562.298830] __ubsan_handle_load_invalid_value+0x72/0x90 [ 7562.298863] f2fs_file_write_iter+0x29f/0x3f0 [ 7562.298905] __vfs_write+0x115/0x160 [ 7562.298922] vfs_write+0xa7/0x190 [ 7562.298934] ksys_write+0x50/0xc0 [ 7562.298973] do_syscall_64+0x4a/0xe0 [ 7562.298992] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 7562.299001] RIP: 0033:0x7fa45ec19c00 [ 7562.299004] Code: 73 01 c3 48 8b 0d 88 92 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d dd eb 2c 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 ce 8f 01 00 48 89 04 24 [ 7562.299044] RSP: 002b:00007ffca52b49e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 7562.299052] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa45ec19c00 [ 7562.299059] RDX: 0000000000000400 RSI: 000000000093f000 RDI: 0000000000000001 [ 7562.299065] RBP: 000000000093f000 R08: 0000000000000004 R09: 0000000000000000 [ 7562.299071] R10: 00007ffca52b47b0 R11: 0000000000000246 R12: 0000000000000400 [ 7562.299077] R13: 000000000093f000 R14: 000000000093f400 R15: 0000000000000000 [ 7562.299091] ================================================================================
So, if iostat_enable is enabled, set its value as true.
Signed-off-by: Sheng Yong shengyong1@huawei.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/sysfs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 81c0e5337443..98887187af4c 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -273,10 +273,16 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return count; }
- *ui = t;
- if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0) - f2fs_reset_iostat(sbi); + if (!strcmp(a->attr.name, "iostat_enable")) { + sbi->iostat_enable = !!t; + if (!sbi->iostat_enable) + f2fs_reset_iostat(sbi); + return count; + } + + *ui = (unsigned int)t; + return count; }
From: Buland Singh bsingh@redhat.com
[ Upstream commit 24d48a61f2666630da130cc2ec2e526eacf229e3 ]
Commit '3d035f580699 ("drivers/char/hpet.c: allow user controlled mmap for user processes")' introduced a new kernel command line parameter hpet_mmap, that is required to expose the memory map of the HPET registers to user-space. Unfortunately the kernel command line parameter 'hpet_mmap' is broken and never takes effect due to missing '=' character in the __setup() code of hpet_mmap_enable.
Before this patch:
dmesg output with the kernel command line parameter hpet_mmap=1
[ 0.204152] HPET mmap disabled
dmesg output with the kernel command line parameter hpet_mmap=0
[ 0.204192] HPET mmap disabled
After this patch:
dmesg output with the kernel command line parameter hpet_mmap=1
[ 0.203945] HPET mmap enabled
dmesg output with the kernel command line parameter hpet_mmap=0
[ 0.204652] HPET mmap disabled
Fixes: 3d035f580699 ("drivers/char/hpet.c: allow user controlled mmap for user processes") Signed-off-by: Buland Singh bsingh@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hpet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 4a22b4b41aef..9bffcd37cc7b 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -377,7 +377,7 @@ static __init int hpet_mmap_enable(char *str) pr_info("HPET mmap %s\n", hpet_mmap_enabled ? "enabled" : "disabled"); return 1; } -__setup("hpet_mmap", hpet_mmap_enable); +__setup("hpet_mmap=", hpet_mmap_enable);
static int hpet_mmap(struct file *file, struct vm_area_struct *vma) {
From: Myungho Jung mhjungk@gmail.com
[ Upstream commit 1dc2d785156cbdc80806c32e8d2c7c735d0b4721 ]
h4_recv_buf() callers store the return value to socket buffer and recursively pass the buffer to h4_recv_buf() without protection. So, ERR_PTR returned from h4_recv_buf() can be dereferenced, if called again before setting the socket buffer to NULL from previous error. Check if skb is ERR_PTR in h4_recv_buf().
Reported-by: syzbot+017a32f149406df32703@syzkaller.appspotmail.com Signed-off-by: Myungho Jung mhjungk@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/h4_recv.h | 4 ++++ drivers/bluetooth/hci_h4.c | 4 ++++ 2 files changed, 8 insertions(+)
diff --git a/drivers/bluetooth/h4_recv.h b/drivers/bluetooth/h4_recv.h index b432651f8236..307d82166f48 100644 --- a/drivers/bluetooth/h4_recv.h +++ b/drivers/bluetooth/h4_recv.h @@ -60,6 +60,10 @@ static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev, const struct h4_recv_pkt *pkts, int pkts_count) { + /* Check for error from previous call */ + if (IS_ERR(skb)) + skb = NULL; + while (count) { int i, len;
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index fb97a3bf069b..5d97d77627c1 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -174,6 +174,10 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, struct hci_uart *hu = hci_get_drvdata(hdev); u8 alignment = hu->alignment ? hu->alignment : 1;
+ /* Check for error from previous call */ + if (IS_ERR(skb)) + skb = NULL; + while (count) { int i, len;
From: Valentin Schneider valentin.schneider@arm.com
[ Upstream commit ce48c457b95316b9a01b5aa9d4456ce820df94b4 ]
Since we've had:
commit cb538267ea1e ("jump_label/lockdep: Assert we hold the hotplug lock for _cpuslocked() operations")
we've been getting some lockdep warnings during init, such as on HiKey960:
[ 0.820495] WARNING: CPU: 4 PID: 0 at kernel/cpu.c:316 lockdep_assert_cpus_held+0x3c/0x48 [ 0.820498] Modules linked in: [ 0.820509] CPU: 4 PID: 0 Comm: swapper/4 Tainted: G S 4.20.0-rc5-00051-g4cae42a #34 [ 0.820511] Hardware name: HiKey960 (DT) [ 0.820516] pstate: 600001c5 (nZCv dAIF -PAN -UAO) [ 0.820520] pc : lockdep_assert_cpus_held+0x3c/0x48 [ 0.820523] lr : lockdep_assert_cpus_held+0x38/0x48 [ 0.820526] sp : ffff00000a9cbe50 [ 0.820528] x29: ffff00000a9cbe50 x28: 0000000000000000 [ 0.820533] x27: 00008000b69e5000 x26: ffff8000bff4cfe0 [ 0.820537] x25: ffff000008ba69e0 x24: 0000000000000001 [ 0.820541] x23: ffff000008fce000 x22: ffff000008ba70c8 [ 0.820545] x21: 0000000000000001 x20: 0000000000000003 [ 0.820548] x19: ffff00000a35d628 x18: ffffffffffffffff [ 0.820552] x17: 0000000000000000 x16: 0000000000000000 [ 0.820556] x15: ffff00000958f848 x14: 455f3052464d4d34 [ 0.820559] x13: 00000000769dde98 x12: ffff8000bf3f65a8 [ 0.820564] x11: 0000000000000000 x10: ffff00000958f848 [ 0.820567] x9 : ffff000009592000 x8 : ffff00000958f848 [ 0.820571] x7 : ffff00000818ffa0 x6 : 0000000000000000 [ 0.820574] x5 : 0000000000000000 x4 : 0000000000000001 [ 0.820578] x3 : 0000000000000000 x2 : 0000000000000001 [ 0.820582] x1 : 00000000ffffffff x0 : 0000000000000000 [ 0.820587] Call trace: [ 0.820591] lockdep_assert_cpus_held+0x3c/0x48 [ 0.820598] static_key_enable_cpuslocked+0x28/0xd0 [ 0.820606] arch_timer_check_ool_workaround+0xe8/0x228 [ 0.820610] arch_timer_starting_cpu+0xe4/0x2d8 [ 0.820615] cpuhp_invoke_callback+0xe8/0xd08 [ 0.820619] notify_cpu_starting+0x80/0xb8 [ 0.820625] secondary_start_kernel+0x118/0x1d0
We've also had a similar warning in sched_init_smp() for every asymmetric system that would enable the sched_asym_cpucapacity static key, although that was singled out in:
commit 40fa3780bac2 ("sched/core: Take the hotplug lock in sched_init_smp()")
Those warnings are actually harmless, since we cannot have hotplug operations at the time they appear. Instead of starting to sprinkle useless hotplug lock operations in the init codepaths, mute the warnings until they start warning about real problems.
Suggested-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Valentin Schneider valentin.schneider@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Cc: cai@gmx.us Cc: daniel.lezcano@linaro.org Cc: dietmar.eggemann@arm.com Cc: linux-arm-kernel@lists.infradead.org Cc: longman@redhat.com Cc: marc.zyngier@arm.com Cc: mark.rutland@arm.com Link: https://lkml.kernel.org/r/1545243796-23224-2-git-send-email-valentin.schneid... Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cpu.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/kernel/cpu.c b/kernel/cpu.c index 56f657adcf03..2e20de761c6c 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -313,6 +313,15 @@ void cpus_write_unlock(void)
void lockdep_assert_cpus_held(void) { + /* + * We can't have hotplug operations before userspace starts running, + * and some init codepaths will knowingly not take the hotplug lock. + * This is all valid, so mute lockdep until it makes sense to report + * unheld locks. + */ + if (system_state < SYSTEM_RUNNING) + return; + percpu_rwsem_assert_held(&cpu_hotplug_lock); }
From: Anders Roxell anders.roxell@linaro.org
[ Upstream commit 9227ab5643cb8350449502dd9e3168a873ab0e3b ]
The warning got introduced by commit 930507c18304 ("arm64: add basic Kconfig symbols for i.MX8"). Since it got enabled for arm64. The warning haven't been seen before since size_t was 'unsigned int' when built on arm32.
../drivers/dma/imx-dma.c: In function ‘imxdma_sg_next’: ../include/linux/kernel.h:846:29: warning: comparison of distinct pointer types lacks a cast (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) ^~ ../include/linux/kernel.h:860:4: note: in expansion of macro ‘__typecheck’ (__typecheck(x, y) && __no_side_effects(x, y)) ^~~~~~~~~~~ ../include/linux/kernel.h:870:24: note: in expansion of macro ‘__safe_cmp’ __builtin_choose_expr(__safe_cmp(x, y), \ ^~~~~~~~~~ ../include/linux/kernel.h:879:19: note: in expansion of macro ‘__careful_cmp’ #define min(x, y) __careful_cmp(x, y, <) ^~~~~~~~~~~~~ ../drivers/dma/imx-dma.c:288:8: note: in expansion of macro ‘min’ now = min(d->len, sg_dma_len(sg)); ^~~
Rework so that we use min_t and pass in the size_t that returns the minimum of two values, using the specified type.
Signed-off-by: Anders Roxell anders.roxell@linaro.org Acked-by: Olof Johansson olof@lixom.net Reviewed-by: Fabio Estevam festevam@gmail.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/imx-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 118d371a2a4a..dfee0d895ce3 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -284,7 +284,7 @@ static inline int imxdma_sg_next(struct imxdma_desc *d) struct scatterlist *sg = d->sg; unsigned long now;
- now = min(d->len, sg_dma_len(sg)); + now = min_t(size_t, d->len, sg_dma_len(sg)); if (d->len != IMX_DMA_LENGTH_LOOP) d->len -= now;
From: Shunyong Yang shunyong.yang@hxt-semitech.com
[ Upstream commit 546c0547555efca8ba8c120716c325435e29df1b ]
When dma_cookie_complete() is called in hidma_process_completed(), dma_cookie_status() will return DMA_COMPLETE in hidma_tx_status(). Then, hidma_txn_is_success() will be called to use channel cookie mchan->last_success to do additional DMA status check. Current code assigns mchan->last_success after dma_cookie_complete(). This causes a race condition of dma_cookie_status() returns DMA_COMPLETE before mchan->last_success is assigned correctly. The race will cause hidma_tx_status() return DMA_ERROR but the transaction is actually a success. Moreover, in async_tx case, it will cause a timeout panic in async_tx_quiesce().
Kernel panic - not syncing: async_tx_quiesce: DMA error waiting for transaction ... Call trace: [<ffff000008089994>] dump_backtrace+0x0/0x1f4 [<ffff000008089bac>] show_stack+0x24/0x2c [<ffff00000891e198>] dump_stack+0x84/0xa8 [<ffff0000080da544>] panic+0x12c/0x29c [<ffff0000045d0334>] async_tx_quiesce+0xa4/0xc8 [async_tx] [<ffff0000045d03c8>] async_trigger_callback+0x70/0x1c0 [async_tx] [<ffff0000048b7d74>] raid_run_ops+0x86c/0x1540 [raid456] [<ffff0000048bd084>] handle_stripe+0x5e8/0x1c7c [raid456] [<ffff0000048be9ec>] handle_active_stripes.isra.45+0x2d4/0x550 [raid456] [<ffff0000048beff4>] raid5d+0x38c/0x5d0 [raid456] [<ffff000008736538>] md_thread+0x108/0x168 [<ffff0000080fb1cc>] kthread+0x10c/0x138 [<ffff000008084d34>] ret_from_fork+0x10/0x18
Cc: Joey Zheng yu.zheng@hxt-semitech.com Reviewed-by: Sinan Kaya okaya@kernel.org Signed-off-by: Shunyong Yang shunyong.yang@hxt-semitech.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/qcom/hidma.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index 43d4b00b8138..ea219bca116d 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -138,24 +138,25 @@ static void hidma_process_completed(struct hidma_chan *mchan) desc = &mdesc->desc; last_cookie = desc->cookie;
+ llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch); + spin_lock_irqsave(&mchan->lock, irqflags); + if (llstat == DMA_COMPLETE) { + mchan->last_success = last_cookie; + result.result = DMA_TRANS_NOERROR; + } else { + result.result = DMA_TRANS_ABORTED; + } + dma_cookie_complete(desc); spin_unlock_irqrestore(&mchan->lock, irqflags);
- llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch); dmaengine_desc_get_callback(desc, &cb);
dma_run_dependencies(desc);
spin_lock_irqsave(&mchan->lock, irqflags); list_move(&mdesc->node, &mchan->free); - - if (llstat == DMA_COMPLETE) { - mchan->last_success = last_cookie; - result.result = DMA_TRANS_NOERROR; - } else - result.result = DMA_TRANS_ABORTED; - spin_unlock_irqrestore(&mchan->lock, irqflags);
dmaengine_desc_callback_invoke(&cb, &result);
From: Shunyong Yang shunyong.yang@hxt-semitech.com
[ Upstream commit 875aac8a46424e5b73a9ff7f40b83311b609e407 ]
In async_tx_test_ack(), it uses flags in struct dma_async_tx_descriptor to check the ACK status. As hidma reuses the descriptor in a free list when hidma_prep_dma_*(memcpy/memset) is called, the flag will keep ACKed if the descriptor has been used before. This will cause a BUG_ON in async_tx_quiesce().
kernel BUG at crypto/async_tx/async_tx.c:282! Internal error: Oops - BUG: 0 1 SMP ... task: ffff8017dd3ec000 task.stack: ffff8017dd3e8000 PC is at async_tx_quiesce+0x54/0x78 [async_tx] LR is at async_trigger_callback+0x98/0x110 [async_tx]
This patch initializes flags in dma_async_tx_descriptor by the flags passed from the caller when hidma_prep_dma_*(memcpy/memset) is called.
Cc: Joey Zheng yu.zheng@hxt-semitech.com Reviewed-by: Sinan Kaya okaya@kernel.org Signed-off-by: Shunyong Yang shunyong.yang@hxt-semitech.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/qcom/hidma.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index ea219bca116d..411f91fde734 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -416,6 +416,7 @@ hidma_prep_dma_memcpy(struct dma_chan *dmach, dma_addr_t dest, dma_addr_t src, if (!mdesc) return NULL;
+ mdesc->desc.flags = flags; hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch, src, dest, len, flags, HIDMA_TRE_MEMCPY); @@ -448,6 +449,7 @@ hidma_prep_dma_memset(struct dma_chan *dmach, dma_addr_t dest, int value, if (!mdesc) return NULL;
+ mdesc->desc.flags = flags; hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch, value, dest, len, flags, HIDMA_TRE_MEMSET);
From: Florian Westphal fw@strlen.de
[ Upstream commit 8e2f311a68494a6677c1724bdcb10bada21af37c ]
Following command: iptables -D FORWARD -m physdev ... causes connectivity loss in some setups.
Reason is that iptables userspace will probe kernel for the module revision of the physdev patch, and physdev has an artificial dependency on br_netfilter (xt_physdev use makes no sense unless a br_netfilter module is loaded).
This causes the "phydev" module to be loaded, which in turn enables the "call-iptables" infrastructure.
bridged packets might then get dropped by the iptables ruleset.
The better fix would be to change the "call-iptables" defaults to 0 and enforce explicit setting to 1, but that breaks backwards compatibility.
This does the next best thing: add a request_module call to checkentry. This was a stray '-D ... -m physdev' won't activate br_netfilter anymore.
Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/netfilter/br_netfilter.h | 1 - net/bridge/br_netfilter_hooks.c | 5 ----- net/netfilter/xt_physdev.c | 9 +++++++-- 3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h index 74af19c3a8f7..a4ba601b5d04 100644 --- a/include/net/netfilter/br_netfilter.h +++ b/include/net/netfilter/br_netfilter.h @@ -49,7 +49,6 @@ static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) }
struct net_device *setup_pre_routing(struct sk_buff *skb); -void br_netfilter_enable(void);
#if IS_ENABLED(CONFIG_IPV6) int br_validate_ipv6(struct net *net, struct sk_buff *skb); diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index e07a7e62c705..3b0a03b92080 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -884,11 +884,6 @@ static const struct nf_br_ops br_ops = { .br_dev_xmit_hook = br_nf_dev_xmit, };
-void br_netfilter_enable(void) -{ -} -EXPORT_SYMBOL_GPL(br_netfilter_enable); - /* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because * br_dev_queue_push_xmit is called afterwards */ static const struct nf_hook_ops br_nf_ops[] = { diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index 9d6d67b953ac..05f00fb20b04 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c @@ -96,8 +96,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) static int physdev_mt_check(const struct xt_mtchk_param *par) { const struct xt_physdev_info *info = par->matchinfo; - - br_netfilter_enable(); + static bool brnf_probed __read_mostly;
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || info->bitmask & ~XT_PHYSDEV_OP_MASK) @@ -111,6 +110,12 @@ static int physdev_mt_check(const struct xt_mtchk_param *par) if (par->hook_mask & (1 << NF_INET_LOCAL_OUT)) return -EINVAL; } + + if (!brnf_probed) { + brnf_probed = true; + request_module("br_netfilter"); + } + return 0; }
From: Steve Longerbeam slongerbeam@gmail.com
[ Upstream commit c5ff0edb8e2270a75935c73217fb0de1abd2d910 ]
There is a block of code in rvin_group_link_notify() that prevents enabling a link to a VIN node if any entity in the media graph is in use. This prevents enabling a VIN link even if there is an in-use entity somewhere in the graph that is independent of the link's pipeline.
For example, the code block will prevent enabling a link from the first rcar-csi2 receiver to a VIN node even if there is an enabled link somewhere far upstream on the second independent rcar-csi2 receiver pipeline.
If this code block is meant to prevent modifying a link if any entity in the graph is actively involved in streaming (because modifying the CHSEL register fields can disrupt any/all running streams), then the entities stream counts should be checked rather than the use counts.
(There is already such a check in __media_entity_setup_link() that verifies the stream_count of the link's source and sink entities are both zero, but that is insufficient, since there should be no running streams in the entire graph).
Modify the code block to check the entity stream_count instead of the use_count (and elaborate on the comment). VIN node links can now be enabled even if there are other independent in-use entities that are not streaming.
Fixes: c0cc5aef31 ("media: rcar-vin: add link notify for Gen3")
Signed-off-by: Steve Longerbeam slongerbeam@gmail.com Reviewed-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar-vin/rcar-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index ce09799976ef..e1085e3ab3cc 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -131,9 +131,13 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags, !is_media_entity_v4l2_video_device(link->sink->entity)) return 0;
- /* If any entity is in use don't allow link changes. */ + /* + * Don't allow link changes if any entity in the graph is + * streaming, modifying the CHSEL register fields can disrupt + * running streams. + */ media_device_for_each_entity(entity, &group->mdev) - if (entity->use_count) + if (entity->stream_count) return -EBUSY;
mutex_lock(&group->lock);
From: Pawe? Chmiel pawel.mikolaj.chmiel@gmail.com
[ Upstream commit 49710c32cd9d6626a77c9f5f978a5f58cb536b35 ]
Previously when doing format enumeration, it was returning all formats supported by driver, even if they're not supported by hw. Add missing check for fmt_ver_flag, so it'll be fixed and only those supported by hw will be returned. Similar thing is already done in s5p_jpeg_find_format.
It was found by using v4l2-compliance tool and checking result of VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS test and using v4l2-ctl to get list of all supported formats.
Tested on s5pv210-galaxys (Samsung i9000 phone).
Fixes: bb677f3ac434 ("[media] Exynos4 JPEG codec v4l2 driver")
Signed-off-by: Pawe? Chmiel pawel.mikolaj.chmiel@gmail.com Reviewed-by: Jacek Anaszewski jacek.anaszewski@gmail.com [hverkuil-cisco@xs4all.nl: fix a few alignment issues] Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 29daecf8de7d..350afaa29a62 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1293,13 +1293,16 @@ static int s5p_jpeg_querycap(struct file *file, void *priv, return 0; }
-static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n, +static int enum_fmt(struct s5p_jpeg_ctx *ctx, + struct s5p_jpeg_fmt *sjpeg_formats, int n, struct v4l2_fmtdesc *f, u32 type) { int i, num = 0; + unsigned int fmt_ver_flag = ctx->jpeg->variant->fmt_ver_flag;
for (i = 0; i < n; ++i) { - if (sjpeg_formats[i].flags & type) { + if (sjpeg_formats[i].flags & type && + sjpeg_formats[i].flags & fmt_ver_flag) { /* index-th format of type type found ? */ if (num == f->index) break; @@ -1326,11 +1329,11 @@ static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
if (ctx->mode == S5P_JPEG_ENCODE) - return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f, + return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, SJPEG_FMT_FLAG_ENC_CAPTURE);
- return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_DEC_CAPTURE); + return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, + SJPEG_FMT_FLAG_DEC_CAPTURE); }
static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, @@ -1339,11 +1342,11 @@ static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
if (ctx->mode == S5P_JPEG_ENCODE) - return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f, + return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, SJPEG_FMT_FLAG_ENC_OUTPUT);
- return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f, - SJPEG_FMT_FLAG_DEC_OUTPUT); + return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f, + SJPEG_FMT_FLAG_DEC_OUTPUT); }
static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
From: Axel Lin axel.lin@ingics.com
[ Upstream commit f01a7beb6791f1c419424c1a6958b7d0a289c974 ]
The act8600_sudcdc_voltage_ranges setting does not match the datasheet.
The problems in below entry: REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000),
1. The off-by-one min_sel causes wrong volatage calculation. The min_sel should be 192. 2. According to the datasheet[1] Table 7. (on page 43): The selector 248 (0b11111000) ~ 255 (0b11111111) are 41.400V.
Also fix off-by-one for ACT8600_SUDCDC_VOLTAGE_NUM.
[1] https://active-semi.com/wp-content/uploads/ACT8600_Datasheet.pdf
Fixes: df3a950e4e73 ("regulator: act8865: Add act8600 support") Signed-off-by: Axel Lin axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/act8865-regulator.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 21e20483bd91..e0239cf3f56d 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -131,7 +131,7 @@ * ACT8865 voltage number */ #define ACT8865_VOLTAGE_NUM 64 -#define ACT8600_SUDCDC_VOLTAGE_NUM 255 +#define ACT8600_SUDCDC_VOLTAGE_NUM 256
struct act8865 { struct regmap *regmap; @@ -222,7 +222,8 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0), REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000), REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000), - REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000), + REGULATOR_LINEAR_RANGE(19000000, 192, 247, 400000), + REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0), };
static struct regulator_ops act8865_ops = {
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 6daae00243e622dd3feec7965bfe421ad6dd317e ]
Gigabit Ethernet requires the Ethernet TXD0..3 and RXD0..3 data lines. Add the missing eth_rxd2 and eth_rxd3 definitions so we don't have to rely on the bootloader to set them up correctly.
The vendor u-boot sources for Odroid-C1 use the following Ethernet pinmux configuration: SET_CBUS_REG_MASK(PERIPHS_PIN_MUX_6, 0x3f4f); SET_CBUS_REG_MASK(PERIPHS_PIN_MUX_7, 0xf00000); This translates to the following pin groups in the mainline kernel: - register 6 bit 0: eth_rxd1 (DIF_0_P) - register 6 bit 1: eth_rxd0 (DIF_0_N) - register 6 bit 2: eth_rx_dv (DIF_1_P) - register 6 bit 3: eth_rx_clk (DIF_1_N) - register 6 bit 6: eth_tx_en (DIF_3_P) - register 6 bit 8: eth_ref_clk (DIF_3_N) - register 6 bit 9: eth_mdc (DIF_4_P) - register 6 bit 10: eth_mdio_en (DIF_4_N) - register 6 bit 11: eth_tx_clk (GPIOH_9) - register 6 bit 12: eth_txd2 (GPIOH_8) - register 6 bit 13: eth_txd3 (GPIOH_7) - register 7 bit 20: eth_txd0_0 (GPIOH_6) - register 7 bit 21: eth_txd1_0 (GPIOH_5) - register 7 bit 22: eth_rxd3 (DIF_2_P) - register 7 bit 23: eth_rxd2 (DIF_2_N)
All functions except eth_rxd2 and eth_rxd3 are already supported by the pinctrl-meson8b driver.
Suggested-by: Jianxin Pan jianxin.pan@amlogic.com Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Kevin Hilman khilman@baylibre.com Tested-by: Emiliano Ingrassia ingrassia@epigenesys.com Reviewed-by: Emiliano Ingrassia ingrassia@epigenesys.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/meson/pinctrl-meson8b.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c index ead4beb5f55f..036124fd363c 100644 --- a/drivers/pinctrl/meson/pinctrl-meson8b.c +++ b/drivers/pinctrl/meson/pinctrl-meson8b.c @@ -346,6 +346,8 @@ static const unsigned int eth_rx_dv_pins[] = { DIF_1_P }; static const unsigned int eth_rx_clk_pins[] = { DIF_1_N }; static const unsigned int eth_txd0_1_pins[] = { DIF_2_P }; static const unsigned int eth_txd1_1_pins[] = { DIF_2_N }; +static const unsigned int eth_rxd3_pins[] = { DIF_2_P }; +static const unsigned int eth_rxd2_pins[] = { DIF_2_N }; static const unsigned int eth_tx_en_pins[] = { DIF_3_P }; static const unsigned int eth_ref_clk_pins[] = { DIF_3_N }; static const unsigned int eth_mdc_pins[] = { DIF_4_P }; @@ -571,6 +573,8 @@ static struct meson_pmx_group meson8b_cbus_groups[] = { GROUP(eth_ref_clk, 6, 8), GROUP(eth_mdc, 6, 9), GROUP(eth_mdio_en, 6, 10), + GROUP(eth_rxd3, 7, 22), + GROUP(eth_rxd2, 7, 23), };
static struct meson_pmx_group meson8b_aobus_groups[] = { @@ -720,7 +724,7 @@ static const char * const ethernet_groups[] = { "eth_tx_clk", "eth_tx_en", "eth_txd1_0", "eth_txd1_1", "eth_txd0_0", "eth_txd0_1", "eth_rx_clk", "eth_rx_dv", "eth_rxd1", "eth_rxd0", "eth_mdio_en", "eth_mdc", "eth_ref_clk", - "eth_txd2", "eth_txd3" + "eth_txd2", "eth_txd3", "eth_rxd3", "eth_rxd2" };
static const char * const i2c_a_groups[] = {
From: Paul Kocialkowski paul.kocialkowski@bootlin.com
[ Upstream commit 890880ddfdbe256083170866e49c87618b706ac7 ]
When drivers pass non-empty lists of modifiers for initializing their planes, we can infer that they allow framebuffer modifiers and set the driver's allow_fb_modifiers mode config element.
In case the allow_fb_modifiers element was not set (some drivers tend to set them after registering planes), the modifiers will still be registered but won't be available to userspace unless the flag is set later. However in that case, the IN_FORMATS blob won't be created.
In order to avoid this case and generally reduce the trouble associated with the flag, always set allow_fb_modifiers when a non-empty list of format modifiers is passed at plane init.
Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Paul Kocialkowski paul.kocialkowski@bootlin.com Signed-off-by: Maxime Ripard maxime.ripard@bootlin.com Link: https://patchwork.freedesktop.org/patch/msgid/20190104085610.5829-1-paul.koc... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_plane.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 6153cbda239f..d36b1be632d9 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -211,6 +211,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, format_modifier_count++; }
+ if (format_modifier_count) + config->allow_fb_modifiers = true; + plane->modifier_count = format_modifier_count; plane->modifiers = kmalloc_array(format_modifier_count, sizeof(format_modifiers[0]),
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 934c5b32a5e43d8de2ab4f1566f91d7c3bf8cb64 ]
The correct way for legacy drivers to update properties that need to do a full modeset, is to do a full modeset.
Note that we don't need to call the drm_mode_config_internal helper because we're not changing any of the refcounted paramters.
v2: Fixup error handling (Ville). Since the old code didn't bother I decided to just delete it instead of adding even more code for just error handling.
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Alex Deucher alexander.deucher@amd.com (v1) Cc: Sean Paul seanpaul@chromium.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20181217194303.14397-2-daniel.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/dispnv04/tvnv17.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 6a4ca139cf5d..8fd8124d72ba 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -750,7 +750,9 @@ static int nv17_tv_set_property(struct drm_encoder *encoder, /* Disable the crtc to ensure a full modeset is * performed whenever it's turned on again. */ if (crtc) - drm_crtc_force_disable(crtc); + drm_crtc_helper_set_mode(crtc, &crtc->mode, + crtc->x, crtc->y, + crtc->primary->fb); }
return 0;
From: George Rimar grimar@accesssoftek.com
[ Upstream commit 927185c124d62a9a4d35878d7f6d432a166b74e3 ]
The kernel uses the OUTPUT_FORMAT linker script command in it's linker scripts. Most of the time, the -m option is passed to the linker with correct architecture, but sometimes (at least for x86_64) the -m option contradicts the OUTPUT_FORMAT directive.
Specifically, arch/x86/boot and arch/x86/realmode/rm produce i386 object files, but are linked with the -m elf_x86_64 linker flag when building for x86_64.
The GNU linker manpage doesn't explicitly state any tie-breakers between -m and OUTPUT_FORMAT. But with BFD and Gold linkers, OUTPUT_FORMAT overrides the emulation value specified with the -m option.
LLVM lld has a different behavior, however. When supplied with contradicting -m and OUTPUT_FORMAT values it fails with the following error message:
ld.lld: error: arch/x86/realmode/rm/header.o is incompatible with elf_x86_64
Therefore, just add the correct -m after the incorrect one (it overrides it), so the linker invocation looks like this:
ld -m elf_x86_64 -z max-page-size=0x200000 -m elf_i386 --emit-relocs -T \ realmode.lds header.o trampoline_64.o stack.o reboot.o -o realmode.elf
This is not a functional change for GNU ld, because (although not explicitly documented) OUTPUT_FORMAT overrides -m EMULATION.
Tested by building x86_64 kernel with GNU gcc/ld toolchain and booting it in QEMU.
[ bp: massage and clarify text. ]
Suggested-by: Dmitry Golovin dima@golovin.in Signed-off-by: George Rimar grimar@accesssoftek.com Signed-off-by: Tri Vo trong@android.com Signed-off-by: Borislav Petkov bp@suse.de Tested-by: Tri Vo trong@android.com Tested-by: Nick Desaulniers ndesaulniers@google.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Michael Matz matz@suse.de Cc: Thomas Gleixner tglx@linutronix.de Cc: morbo@google.com Cc: ndesaulniers@google.com Cc: ruiu@google.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/20190111201012.71210-1-trong@android.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/boot/Makefile | 2 +- arch/x86/realmode/rm/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 9b5adae9cc40..e2839b5c246c 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -100,7 +100,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE AFLAGS_header.o += -I$(objtree)/$(obj) $(obj)/header.o: $(obj)/zoffset.h
-LDFLAGS_setup.elf := -T +LDFLAGS_setup.elf := -m elf_i386 -T $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE $(call if_changed,ld)
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 4463fa72db94..96cb20de08af 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -47,7 +47,7 @@ $(obj)/pasyms.h: $(REALMODE_OBJS) FORCE targets += realmode.lds $(obj)/realmode.lds: $(obj)/pasyms.h
-LDFLAGS_realmode.elf := --emit-relocs -T +LDFLAGS_realmode.elf := -m elf_i386 --emit-relocs -T CPPFLAGS_realmode.lds += -P -C -I$(objtree)/$(obj)
targets += realmode.elf
From: Ondrej Mosnacek omosnace@redhat.com
[ Upstream commit 53e0c2aa9a59a48e3798ef193d573ade85aa80f5 ]
Ignore all selinux_inode_notifysecctx() calls on mounts with SBLABEL_MNT flag unset. This is achived by returning -EOPNOTSUPP for this case in selinux_inode_setsecurtity() (because that function should not be called in such case anyway) and translating this error to 0 in selinux_inode_notifysecctx().
This fixes behavior of kernfs-based filesystems when mounted with the 'context=' option. Before this patch, if a node's context had been explicitly set to a non-default value and later the filesystem has been remounted with the 'context=' option, then this node would show up as having the manually-set context and not the mount-specified one.
Steps to reproduce: # mount -t cgroup2 cgroup2 /sys/fs/cgroup/unified # chcon unconfined_u:object_r:user_home_t:s0 /sys/fs/cgroup/unified/cgroup.stat # ls -lZ /sys/fs/cgroup/unified total 0 -r--r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.controllers -rw-r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.max.depth -rw-r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.max.descendants -rw-r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.procs -r--r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 0 Dec 13 10:41 cgroup.stat -rw-r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.subtree_control -rw-r--r--. 1 root root system_u:object_r:cgroup_t:s0 0 Dec 13 10:41 cgroup.threads # umount /sys/fs/cgroup/unified # mount -o context=system_u:object_r:tmpfs_t:s0 -t cgroup2 cgroup2 /sys/fs/cgroup/unified
Result before: # ls -lZ /sys/fs/cgroup/unified total 0 -r--r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.controllers -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.max.depth -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.max.descendants -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.procs -r--r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 0 Dec 13 10:41 cgroup.stat -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.subtree_control -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.threads
Result after: # ls -lZ /sys/fs/cgroup/unified total 0 -r--r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.controllers -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.max.depth -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.max.descendants -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.procs -r--r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.stat -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.subtree_control -rw-r--r--. 1 root root system_u:object_r:tmpfs_t:s0 0 Dec 13 10:41 cgroup.threads
Signed-off-by: Ondrej Mosnacek omosnace@redhat.com Reviewed-by: Stephen Smalley sds@tycho.nsa.gov Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/hooks.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6ea3d3aa1a1e..4337b6d9369e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3458,12 +3458,16 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) { struct inode_security_struct *isec = inode_security_novalidate(inode); + struct superblock_security_struct *sbsec = inode->i_sb->s_security; u32 newsid; int rc;
if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP;
+ if (!(sbsec->flags & SBLABEL_MNT)) + return -EOPNOTSUPP; + if (!value || !size) return -EACCES;
@@ -6612,7 +6616,10 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) */ static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) { - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); + int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, + ctx, ctxlen, 0); + /* Do not return error when suppressing label (SBLABEL_MNT not set). */ + return rc == -EOPNOTSUPP ? 0 : rc; }
/*
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 4ad0be160544ffbdafb7cec39bb8e6dd0a97317a ]
The linux-firmware brcmfmac firmware files contain an embedded table with per country allowed channels and strength info.
For recent hardware these versions of the firmware are specially build for linux-firmware, the firmware files directly available from Cypress rely on a separate clm_blob file for this info.
For some unknown reason Cypress refuses to provide the standard firmware files + clm_blob files it uses elsewhere for inclusion into linux-firmware, instead relying on these special builds with the clm_blob info embedded. This means that the linux-firmware firmware versions often lag behind, but I digress.
The brcmfmac driver does support the separate clm_blob file and always tries to load this. Currently we use request_firmware for this. This means that on any standard install, using the standard combo of linux-kernel + linux-firmware, we will get a warning: "Direct firmware load for ... failed with error -2"
On top of this, brcmfmac itself prints: "no clm_blob available (err=-2), device may have limited channels available".
This commit switches to firmware_request_nowarn, fixing almost any brcmfmac device logging the warning (it leaves the brcmfmac info message in place).
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index cd3651069d0c..27893af63ebc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -149,7 +149,7 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) return err; }
- err = request_firmware(&clm, clm_name, bus->dev); + err = firmware_request_nowarn(&clm, clm_name, bus->dev); if (err) { brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", err);
From: Zumeng Chen zumeng.chen@gmail.com
[ Upstream commit ba2ffc96321c8433606ceeb85c9e722b8113e5a7 ]
Release fw_status, raw_fw_status, and tx_res_if when wl12xx_fetch_firmware failed instead of meaningless goto out to avoid the following memory leak reports(Only the last one listed):
unreferenced object 0xc28a9a00 (size 512): comm "kworker/0:4", pid 31298, jiffies 2783204 (age 203.290s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<6624adab>] kmemleak_alloc+0x40/0x74 [<500ddb31>] kmem_cache_alloc_trace+0x1ac/0x270 [<db4d731d>] wl12xx_chip_wakeup+0xc4/0x1fc [wlcore] [<76c5db53>] wl1271_op_add_interface+0x4a4/0x8f4 [wlcore] [<cbf30777>] drv_add_interface+0xa4/0x1a0 [mac80211] [<65bac325>] ieee80211_reconfig+0x9c0/0x1644 [mac80211] [<2817c80e>] ieee80211_restart_work+0x90/0xc8 [mac80211] [<7e1d425a>] process_one_work+0x284/0x42c [<55f9432e>] worker_thread+0x2fc/0x48c [<abb582c6>] kthread+0x148/0x160 [<63144b13>] ret_from_fork+0x14/0x2c [< (null)>] (null) [<1f6e7715>] 0xffffffff
Signed-off-by: Zumeng Chen zumeng.chen@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ti/wlcore/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 19e3c5a0b715..2ca5658bbc2a 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1084,8 +1084,11 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) goto out;
ret = wl12xx_fetch_firmware(wl, plt); - if (ret < 0) - goto out; + if (ret < 0) { + kfree(wl->fw_status); + kfree(wl->raw_fw_status); + kfree(wl->tx_res_if); + }
out: return ret;
From: Rafael Ávila de Espíndola rafael@espindo.la
[ Upstream commit d071ae09a4a1414c1433d5ae9908959a7325b0ad ]
Accessing per-CPU variables is done by finding the offset of the variable in the per-CPU block and adding it to the address of the respective CPU's block.
Section 3.10.8 of ld.bfd's documentation states:
For expressions involving numbers, relative addresses and absolute addresses, ld follows these rules to evaluate terms:
Other binary operations, that is, between two relative addresses not in the same section, or between a relative address and an absolute address, first convert any non-absolute term to an absolute address before applying the operator."
Note that LLVM's linker does not adhere to the GNU ld's implementation and as such requires implicitly-absolute terms to be explicitly marked as absolute in the linker script. If not, it fails currently with:
ld.lld: error: ./arch/x86/kernel/vmlinux.lds:153: at least one side of the expression must be absolute ld.lld: error: ./arch/x86/kernel/vmlinux.lds:154: at least one side of the expression must be absolute Makefile:1040: recipe for target 'vmlinux' failed
This is not a functional change for ld.bfd which converts the term to an absolute symbol anyways as specified above.
Based on a previous submission by Tri Vo trong@android.com.
Reported-by: Dmitry Golovin dima@golovin.in Signed-off-by: Rafael Ávila de Espíndola rafael@espindo.la [ Update commit message per Boris' and Michael's suggestions. ] Signed-off-by: Nick Desaulniers ndesaulniers@google.com [ Massage commit message more, fix typos. ] Signed-off-by: Borislav Petkov bp@suse.de Tested-by: Dmitry Golovin dima@golovin.in Cc: "H. Peter Anvin" hpa@zytor.com Cc: Andy Lutomirski luto@kernel.org Cc: Brijesh Singh brijesh.singh@amd.com Cc: Cao Jin caoj.fnst@cn.fujitsu.com Cc: Ingo Molnar mingo@redhat.com Cc: Joerg Roedel jroedel@suse.de Cc: Masahiro Yamada yamada.masahiro@socionext.com Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Tri Vo trong@android.com Cc: dima@golovin.in Cc: morbo@google.com Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/20181219190145.252035-1-ndesaulniers@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 5dd3317d761f..c63bab98780c 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -411,7 +411,7 @@ SECTIONS * Per-cpu symbols which need to be offset from __per_cpu_load * for the boot processor. */ -#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load +#define INIT_PER_CPU(x) init_per_cpu__##x = ABSOLUTE(x) + __per_cpu_load INIT_PER_CPU(gdt_page); INIT_PER_CPU(irq_stack_union);
From: Peter Wu peter@lekensteyn.nl
[ Upstream commit 00eb5b0da8d27b3c944bfc959c3344d665caae26 ]
After drm_fb_helper_fbdev_setup calls drm_fb_helper_init, "dev->fb_helper" will be initialized (and thus drm_fb_helper_fini will have some effect). After that, drm_fb_helper_initial_config is called which may call the "fb_probe" driver callback.
This driver callback may call drm_fb_helper_defio_init (as is done by drm_fb_helper_generic_probe) or set a framebuffer (as is done by bochs) as documented. These are normally cleaned up on exit by drm_fb_helper_fbdev_teardown which also calls drm_fb_helper_fini.
If an error occurs after "fb_probe", but before setup is complete, then calling just drm_fb_helper_fini will leak resources. This was triggered by df2052cc922 ("bochs: convert to drm_fb_helper_fbdev_setup/teardown"):
[ 50.008030] bochsdrmfb: enable CONFIG_FB_LITTLE_ENDIAN to support this framebuffer [ 50.009436] bochs-drm 0000:00:02.0: [drm:drm_fb_helper_fbdev_setup] *ERROR* fbdev: Failed to set configuration (ret=-38) [ 50.011456] [drm] Initialized bochs-drm 1.0.0 20130925 for 0000:00:02.0 on minor 2 [ 50.013604] WARNING: CPU: 1 PID: 1 at drivers/gpu/drm/drm_mode_config.c:477 drm_mode_config_cleanup+0x280/0x2a0 [ 50.016175] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G T 4.20.0-rc7 #1 [ 50.017732] EIP: drm_mode_config_cleanup+0x280/0x2a0 ... [ 50.023155] Call Trace: [ 50.023155] ? bochs_kms_fini+0x1e/0x30 [ 50.023155] ? bochs_unload+0x18/0x40
This can be reproduced with QEMU and CONFIG_FB_LITTLE_ENDIAN=n.
Link: https://lkml.kernel.org/r/20181221083226.GI23332@shao2-debian Link: https://lkml.kernel.org/r/20181223004315.GA11455@al Fixes: 8741216396b2 ("drm/fb-helper: Add drm_fb_helper_fbdev_setup/teardown()") Reported-by: kernel test robot rong.a.chen@intel.com Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Peter Wu peter@lekensteyn.nl Reviewed-by: Noralf Trønnes noralf@tronnes.org Signed-off-by: Noralf Trønnes noralf@tronnes.org Link: https://patchwork.freedesktop.org/patch/msgid/20181223005507.28328-1-peter@l... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e65596617239..a0663f44e218 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2877,7 +2877,7 @@ int drm_fb_helper_fbdev_setup(struct drm_device *dev, return 0;
err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); + drm_fb_helper_fbdev_teardown(dev);
return ret; }
From: Jerome Brunet jbrunet@baylibre.com
[ Upstream commit 8d9981efbcab066d17af4d3c85c169200f6f78df ]
Order, ids and size between the table of regmap clocks and the onecell data table could be different.
Set regmap pointer in all the regmap clocks before starting the registration using the onecell data, to make sure we don't get into an incoherent situation.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com Acked-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lkml.kernel.org/r/20181221160239.26265-3-jbrunet@baylibre.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/meson/meson-aoclk.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index f965845917e3..258c8d259ea1 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -65,15 +65,20 @@ int meson_aoclkc_probe(struct platform_device *pdev) return ret; }
- /* - * Populate regmap and register all clks - */ - for (clkid = 0; clkid < data->num_clks; clkid++) { + /* Populate regmap */ + for (clkid = 0; clkid < data->num_clks; clkid++) data->clks[clkid]->map = regmap;
+ /* Register all clks */ + for (clkid = 0; clkid < data->hw_data->num; clkid++) { + if (!data->hw_data->hws[clkid]) + continue; + ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]); - if (ret) + if (ret) { + dev_err(dev, "Clock registration failed\n"); return ret; + } }
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
From: Katsuhiro Suzuki katsuhiro@katsuster.net
[ Upstream commit a0e447b0c50240a90ab84b7126b3c06b0bab4adc ]
This patch fixes settings of GPLL frequency in fractional mode for rk3328. In this mode, FOUTVCO is calcurated by following formula: FOUTVCO = FREF * FBDIV / REFDIV + ((FREF * FRAC / REFDIV) >> 24)
The problem is in FREF * FRAC >> 24 term. This result always lacks one from target value is specified by rate member. For example first itme of rk3328_pll_frac_rate originally has - rate : 1016064000 - refdiv: 3 - fbdiv : 127 - frac : 134217 - FREF * FBDIV / REFDIV = 1016000000 - (FREF * FRAC / REFDIV) >> 24 = 63999 Thus calculated rate is 1016063999. It seems wrong.
If frac has 134218 (it is increased 1 from original value), second term is 64000. All other items have same situation. So this patch adds 1 to frac member in all items of rk3328_pll_frac_rate.
Signed-off-by: Katsuhiro Suzuki katsuhiro@katsuster.net Acked-by: Elaine Zhang zhangqing@rock-chips.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/rockchip/clk-rk3328.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c index 2c5426607790..e431661fe874 100644 --- a/drivers/clk/rockchip/clk-rk3328.c +++ b/drivers/clk/rockchip/clk-rk3328.c @@ -78,17 +78,17 @@ static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = { /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ - RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217), + RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134218), /* vco = 1016064000 */ - RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088), + RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671089), /* vco = 983040000 */ - RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088), + RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671089), /* vco = 983040000 */ - RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088), + RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671089), /* vco = 860156000 */ - RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894), + RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797895), /* vco = 903168000 */ - RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329), + RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066330), /* vco = 819200000 */ { /* sentinel */ }, };
From: Ben Dooks ben.dooks@codethink.co.uk
[ Upstream commit e486df39305864604b7e25f2a95d51039517ac57 ]
The dma_desc->bytes_transferred counter tracks the number of bytes moved by the DMA channel. This is then used to calculate the information passed back in the in the tegra_dma_tx_status callback, which is usually fine.
When the DMA channel is configured as continous, then the bytes_transferred counter will increase over time and eventually overflow to become negative so the residue count will become invalid and the ALSA sound-dma code will report invalid hardware pointer values to the application. This results in some users becoming confused about the playout position and putting audio data in the wrong place.
To fix this issue, always ensure the bytes_transferred field is modulo the size of the request. We only do this for the case of the cyclic transfer done ISR as anyone attempting to move 2GiB of DMA data in one transfer is unlikely.
Note, we don't fix the issue that we should /never/ transfer a negative number of bytes so we could make those fields unsigned.
Reviewed-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Ben Dooks ben.dooks@codethink.co.uk Acked-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/tegra20-apb-dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 9a558e30c461..8219ab88a507 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -636,7 +636,10 @@ static void handle_cont_sngl_cycle_dma_done(struct tegra_dma_channel *tdc,
sgreq = list_first_entry(&tdc->pending_sg_req, typeof(*sgreq), node); dma_desc = sgreq->dma_desc; - dma_desc->bytes_transferred += sgreq->req_len; + /* if we dma for long enough the transfer count will wrap */ + dma_desc->bytes_transferred = + (dma_desc->bytes_transferred + sgreq->req_len) % + dma_desc->bytes_requested;
/* Callback need to be call */ if (!dma_desc->cb_count)
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e9eb788f9442d1b5d93efdb30c3be071ce8a22b1 ]
The Microsoft documenation for the PNP0C40 device aka the "Windows-compatible button array" describes the 5th GpioInt listed in the resources as: '5. Interrupt corresponding to the "Rotation Lock" button, if supported'.
Notice this describes the 5th entry as a button while we sofar have been mapping it to EV_SW, SW_ROTATE_LOCK. On my Point of View TAB P1006W-232 which actually comes with a rotation-lock button, the button indeed is a button and not a slider/switch. An image search for other Windows tablets has found 2 more models with a rotation-lock button and on both of those it too is a push-button and not a slider/switch.
Further evidence can be found in the HUT extension HUTRR52 from Microsoft which adds rotation lock support to the HUT, which describes 2 different usages: "0xC9 System Display Rotation Lock Button" and "0xCA System Display Rotation Lock Slider Switch" note that switch is seen as a separate thing here and the non switch wording is an exact match for the "Windows-compatible button array" spec wording.
TL;DR: our current mapping of the 5th GPIO to SW_ROTATE_LOCK is wrong because the 5th GPIO is for a push-button not a switch.
This commit fixes this by maping the 5th GPIO to KEY_ROTATE_LOCK_TOGGLE.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/soc_button_array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 23520df7650f..55cd6e0b409c 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -373,7 +373,7 @@ static struct soc_button_info soc_button_PNP0C40[] = { { "home", 1, EV_KEY, KEY_LEFTMETA, false, true }, { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false }, - { "rotation_lock", 4, EV_SW, SW_ROTATE_LOCK, false, false }, + { "rotation_lock", 4, EV_KEY, KEY_ROTATE_LOCK_TOGGLE, false, false }, { } };
From: Chris Wilson chris@chris-wilson.co.uk
[ Upstream commit 227ad6d957898a88b1746e30234ece64d305f066 ]
Delay the drm_modeset_acquire_init() until after we check for an allocation failure so that we can return immediately upon error without having to unwind.
WARNING: lock held when returning to user space! 4.20.0+ #174 Not tainted ------------------------------------------------ syz-executor556/8153 is leaving the kernel with locks still held! 1 lock held by syz-executor556/8153: #0: 000000005100c85c (crtc_ww_class_acquire){+.+.}, at: set_property_atomic+0xb3/0x330 drivers/gpu/drm/drm_mode_object.c:462
Reported-by: syzbot+6ea337c427f5083ebdf2@syzkaller.appspotmail.com Fixes: 144a7999d633 ("drm: Handle properties in the core for atomic drivers") Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Sean Paul sean@poorly.run Cc: David Airlie airlied@linux.ie Cc: stable@vger.kernel.org # v4.14+ Reviewed-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20181230122842.21917-1-chris@c...
Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_mode_object.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index fcb0ab0abb75..4ba59455c9e6 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -464,6 +464,7 @@ static int set_property_atomic(struct drm_mode_object *obj, if (!state) return -ENOMEM; state->acquire_ctx = &ctx; + retry: if (prop == state->dev->mode_config.dpms_property) { if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit c978ae9bde582e82a04c63a4071701691dd8b35c ]
We aren't supposed to force a stop+start between every i2c msg when performing multi message transfers. This should eg. cause the DDC segment address to be reset back to 0 between writing the segment address and reading the actual EDID extension block.
To quote the E-DDC spec: "... this standard requires that the segment pointer be reset to 00h when a NO ACK or a STOP condition is received."
Since we're going to touch this might as well consult the I2C_M_STOP flag to determine whether we want to force the stop or not.
Cc: Brian Vincent brainn@gmail.com References: https://bugs.freedesktop.org/show_bug.cgi?id=108081 Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20180928180403.22499-1-ville.s... Reviewed-by: Dhinakaran Pandiyan dhinakaran.pandiyan@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index d708472d93c4..65f58e23e03d 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3278,6 +3278,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr; msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len; msg.u.i2c_read.transactions[i].bytes = msgs[i].buf; + msg.u.i2c_read.transactions[i].no_stop_bit = !(msgs[i].flags & I2C_M_STOP); } msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr; msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit 1f5d861f7fefa971b2c6e766f77932c86419a319 ]
When building with -Wsometimes-uninitialized, Clang warns:
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c:111:2: error: variable 'ns' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c:111:2: error: variable 'ns' is used uninitialized whenever '&&' condition is false [-Werror,-Wsometimes-uninitialized]
Clang is concerned with the use of stmmac_do_void_callback (which stmmac_get_systime wraps), as it may fail to initialize these values if the if condition was ever false (meaning the callback doesn't exist). It's not wrong because the callback is what initializes ns. While it's unlikely that the callback is going to disappear at some point and make that condition false, we can easily avoid this warning by zero initializing the variable.
Link: https://github.com/ClangBuiltLinux/linux/issues/384 Fixes: df103170854e ("net: stmmac: Avoid sometimes uninitialized Clang warnings") Suggested-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index 2293e21f789f..cc60b3fb0892 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -105,7 +105,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts) struct stmmac_priv *priv = container_of(ptp, struct stmmac_priv, ptp_clock_ops); unsigned long flags; - u64 ns; + u64 ns = 0;
spin_lock_irqsave(&priv->ptp_lock, flags); stmmac_get_systime(priv, priv->ptpaddr, &ns);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit d693c008e3ca04db5916ff72e68ce661888a913b ]
Commit 53fa1f6e8a59 ("ACPI / video: Only default only_lcd to true on Win8-ready _desktops_") introduced chassis type detection, limiting the lcd_only check for the backlight to devices where the chassis-type indicates their is no builtin LCD panel.
The purpose of the lcd_only check is to avoid advertising a backlight interface on desktops, since skylake and newer machines seem to always have a backlight interface even if there is no LCD panel. The limiting of this check to desktops only was done to avoid breaking backlight support on some laptops which do not have the lcd flag set.
The Fujitsu ESPRIMO Q910 which is a compact (NUC like) desktop machine has a chassis type of 0x10 aka "Lunch Box". Without the lcd_only check we end up falsely advertising backlight/brightness control on this device. This commit extend the dmi_is_desktop check to return true for type 0x10 to fix this.
Fixes: 53fa1f6e8a59 ("ACPI / video: Only default only_lcd to true ...") Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpi_video.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 1ab1460c4a4e..d73afb562ad9 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -2143,6 +2143,7 @@ static bool dmi_is_desktop(void) case 0x05: /* Pizza Box */ case 0x06: /* Mini Tower */ case 0x07: /* Tower */ + case 0x10: /* Lunch Box */ case 0x11: /* Main Server Chassis */ return true; }
From: Coly Li colyli@suse.de
[ Upstream commit 5b5fd3c94eef69dcfaa8648198e54c92e5687d6d ]
Current code already uses d_strtoul_nonzero() to convert input string to an unsigned integer, to make sure writeback_rate_p_term_inverse won't be zero value. But overflow may happen when converting input string to an unsigned integer value by d_strtoul_nonzero(), then dc->writeback_rate_p_term_inverse can still be set to 0 even if the sysfs file input value is not zero, e.g. 4294967296 (a.k.a UINT_MAX+1).
If dc->writeback_rate_p_term_inverse is set to 0, it might cause a dev-zero error in following code from __update_writeback_rate(), int64_t proportional_scaled = div_s64(error, dc->writeback_rate_p_term_inverse);
This patch replaces d_strtoul_nonzero() by sysfs_strtoul_clamp() and limit the value range in [1, UINT_MAX]. Then the unsigned integer overflow and dev-zero error can be avoided.
Signed-off-by: Coly Li colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 503ad954ccc0..d9481640b3e1 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -286,7 +286,9 @@ STORE(__cached_dev) sysfs_strtoul_clamp(writeback_rate_i_term_inverse, dc->writeback_rate_i_term_inverse, 1, UINT_MAX); - d_strtoul_nonzero(writeback_rate_p_term_inverse); + sysfs_strtoul_clamp(writeback_rate_p_term_inverse, + dc->writeback_rate_p_term_inverse, + 1, UINT_MAX); d_strtoul_nonzero(writeback_rate_minimum);
sysfs_strtoul_clamp(io_error_limit, dc->error_limit, 0, INT_MAX);
linux-stable-mirror@lists.linaro.org