mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

September 2021

  • 25 participants
  • 125 discussions
[PATCH] arm64: smp: Fix cpu_freq print for NMI watchdog
by Wenchao Qin 17 Sep '21

17 Sep '21
hulk inclusion category: bugfix bugzilla: N/A CVE: N/A ------------------------------ When we are in the arch_get_cpu_freq func for the first time, after arch_probe_cpu_freq is excuted, the return of smp_processor_id() will change due to preemption while cpu_freq get the freq belong to original processor id, so pr_info will print the freq with wrong processor id like below table from dmesg: [ 1.713211] NMI watchdog: CPU1 freq probed as 2189072384 HZ. [ 1.810819] NMI watchdog: CPU1 freq probed as 2192003108 HZ. [ 1.909910] NMI watchdog: CPU2 freq probed as 2191345967 HZ. [ 2.015327] NMI watchdog: CPU3 freq probed as 2189460398 HZ. Actually, the first line should print the freq of CPU0, this bu can occur in virtual machine with less then 17 vCPUs. Changing smp_processor_id() to cpu will fix the bug Signed-off-by: Wenchao Qin <qinwenchao(a)cmss.chinamobile.com> --- arch/arm64/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index fe56277..d685a27 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -1457,7 +1457,7 @@ static u64 arch_get_cpu_freq(void) if (!cpu_freq) { cpu_freq = arch_probe_cpu_freq(); pr_info("NMI watchdog: CPU%u freq probed as %llu HZ.\n", - smp_processor_id(), cpu_freq); + cpu, cpu_freq); if (!cpu_freq) cpu_freq = -1; per_cpu(cpu_freq_probed, cpu) = cpu_freq; -- 1.8.3.1
1 0
0 0
[PATCH openEuler-1.0-LTS] blk-cgroup: fix UAF by grabbing blkcg lock before destroying blkg pd
by Yang Yingliang 17 Sep '21

17 Sep '21
From: Laibin Qiu <qiulaibin(a)huawei.com> hulk inclusion category: bugfix bugzilla: 181879, https://gitee.com/openeuler/kernel/issues/I4AJ00 CVE: NA -------------------------- KASAN reports a use-after-free report when doing fuzz test: [693354.104835] ================================================================== [693354.105094] BUG: KASAN: use-after-free in bfq_io_set_weight_legacy+0xd3/0x160 [693354.105336] Read of size 4 at addr ffff888be0a35664 by task sh/1453338 [693354.105607] CPU: 41 PID: 1453338 Comm: sh Kdump: loaded Not tainted 4.18.0-147 [693354.105610] Hardware name: Huawei 2288H V5/BC11SPSCB0, BIOS 0.81 07/02/2018 [693354.105612] Call Trace: [693354.105621] dump_stack+0xf1/0x19b [693354.105626] ? show_regs_print_info+0x5/0x5 [693354.105634] ? printk+0x9c/0xc3 [693354.105638] ? cpumask_weight+0x1f/0x1f [693354.105648] print_address_description+0x70/0x360 [693354.105654] kasan_report+0x1b2/0x330 [693354.105659] ? bfq_io_set_weight_legacy+0xd3/0x160 [693354.105665] ? bfq_io_set_weight_legacy+0xd3/0x160 [693354.105670] bfq_io_set_weight_legacy+0xd3/0x160 [693354.105675] ? bfq_cpd_init+0x20/0x20 [693354.105683] cgroup_file_write+0x3aa/0x510 [693354.105693] ? ___slab_alloc+0x507/0x540 [693354.105698] ? cgroup_file_poll+0x60/0x60 [693354.105702] ? 0xffffffff89600000 [693354.105708] ? usercopy_abort+0x90/0x90 [693354.105716] ? mutex_lock+0xef/0x180 [693354.105726] kernfs_fop_write+0x1ab/0x280 [693354.105732] ? cgroup_file_poll+0x60/0x60 [693354.105738] vfs_write+0xe7/0x230 [693354.105744] ksys_write+0xb0/0x140 [693354.105749] ? __ia32_sys_read+0x50/0x50 [693354.105760] do_syscall_64+0x112/0x370 [693354.105766] ? syscall_return_slowpath+0x260/0x260 [693354.105772] ? do_page_fault+0x9b/0x270 [693354.105779] ? prepare_exit_to_usermode+0xf9/0x1a0 [693354.105784] ? enter_from_user_mode+0x30/0x30 [693354.105793] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.105875] Allocated by task 1453337: [693354.106001] kasan_kmalloc+0xa0/0xd0 [693354.106006] kmem_cache_alloc_node_trace+0x108/0x220 [693354.106010] bfq_pd_alloc+0x96/0x120 [693354.106015] blkcg_activate_policy+0x1b7/0x2b0 [693354.106020] bfq_create_group_hierarchy+0x1e/0x80 [693354.106026] bfq_init_queue+0x678/0x8c0 [693354.106031] blk_mq_init_sched+0x1f8/0x460 [693354.106037] elevator_switch_mq+0xe1/0x240 [693354.106041] elevator_switch+0x25/0x40 [693354.106045] elv_iosched_store+0x1a1/0x230 [693354.106049] queue_attr_store+0x78/0xb0 [693354.106053] kernfs_fop_write+0x1ab/0x280 [693354.106056] vfs_write+0xe7/0x230 [693354.106060] ksys_write+0xb0/0x140 [693354.106064] do_syscall_64+0x112/0x370 [693354.106069] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.106114] Freed by task 1453336: [693354.106225] __kasan_slab_free+0x130/0x180 [693354.106229] kfree+0x90/0x1b0 [693354.106233] blkcg_deactivate_policy+0x12c/0x220 [693354.106238] bfq_exit_queue+0xf5/0x110 [693354.106241] blk_mq_exit_sched+0x104/0x130 [693354.106245] __elevator_exit+0x45/0x60 [693354.106249] elevator_switch_mq+0xd6/0x240 [693354.106253] elevator_switch+0x25/0x40 [693354.106257] elv_iosched_store+0x1a1/0x230 [693354.106261] queue_attr_store+0x78/0xb0 [693354.106264] kernfs_fop_write+0x1ab/0x280 [693354.106268] vfs_write+0xe7/0x230 [693354.106271] ksys_write+0xb0/0x140 [693354.106275] do_syscall_64+0x112/0x370 [693354.106280] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.106329] The buggy address belongs to the object at ffff888be0a35580 which belongs to the cache kmalloc-1k of size 1024 [693354.106736] The buggy address is located 228 bytes inside of 1024-byte region [ffff888be0a35580, ffff888be0a35980) [693354.107114] The buggy address belongs to the page: [693354.107273] page:ffffea002f828c00 count:1 mapcount:0 mapping:ffff888107c17080 index:0x0 compound_mapcount: 0 [693354.107606] flags: 0x17ffffc0008100(slab|head) [693354.107760] raw: 0017ffffc0008100 ffffea002fcbc808 ffffea0030bd3a08 ffff888107c17080 [693354.108020] raw: 0000000000000000 00000000001c001c 00000001ffffffff 0000000000000000 [693354.108278] page dumped because: kasan: bad access detected [693354.108511] Memory state around the buggy address: [693354.108671] ffff888be0a35500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [693354.116396] ffff888be0a35580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.124473] >ffff888be0a35600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.132421] ^ [693354.140284] ffff888be0a35680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.147912] ffff888be0a35700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.155281] ================================================================== blkgs are protected by both queue and blkcg locks and holding either should stabilize them. However, the path of destroying blkg policy data is only protected by queue lock in blkcg_activate_policy()/blkcg_deactivate_policy(). Other tasks can get the blkg policy data before the blkg policy data is destroyed, and use it after destroyed, which will result in a use-after-free. CPU0 CPU1 blkcg_deactivate_policy spin_lock_irq(&q->queue_lock) bfq_io_set_weight_legacy spin_lock_irq(&blkcg->lock) blkg_to_bfqg(blkg) pd_to_bfqg(blkg->pd[pol->plid]) ^^^^^^blkg->pd[pol->plid] != NULL bfqg != NULL pol->pd_free_fn(blkg->pd[pol->plid]) pd_to_bfqg(blkg->pd[pol->plid]) bfqg_put(bfqg) kfree(bfqg) blkg->pd[pol->plid] = NULL spin_unlock_irq(q->queue_lock); bfq_group_set_weight(bfqg, val, 0) bfqg->entity.new_weight ^^^^^^trigger uaf here spin_unlock_irq(&blkcg->lock); Fix by garbbing the matching blkcg lock before trying to destroy blkg policy data. [Resolve conflict in blkcg_activate_policy() flow due to lack of 9d179b865449b ("blkcg: Fix multiple bugs in blkcg_activate_policy()"). 4.18 no need to merge this patch. So there is no problem in blkcg_activate_policy() flow.] Signed-off-by: Li Jinlin <lijinlin3(a)huawei.com> Link: https://lore.kernel.org/linux-block/YUDLt9uBNLhWL6Gt@slm.duckdns.org/T/#r07… Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com> Reviewed-by: Jason Yan <yanaijie(a)huawei.com> Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com> --- block/blk-cgroup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 7ded51051e0bc..592befc26584f 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1509,12 +1509,16 @@ void blkcg_deactivate_policy(struct request_queue *q, __clear_bit(pol->plid, q->blkcg_pols); list_for_each_entry(blkg, &q->blkg_list, q_node) { + struct blkcg *blkcg = blkg->blkcg; + + spin_lock(&blkcg->lock); if (blkg->pd[pol->plid]) { if (pol->pd_offline_fn) pol->pd_offline_fn(blkg->pd[pol->plid]); pol->pd_free_fn(blkg->pd[pol->plid]); blkg->pd[pol->plid] = NULL; } + spin_unlock(&blkcg->lock); } spin_unlock_irq(q->queue_lock); -- 2.25.1
1 0
0 0
[PATCH kernel-4.19] blk-cgroup: fix UAF by grabbing blkcg lock before destroying blkg pd
by Yang Yingliang 17 Sep '21

17 Sep '21
From: Laibin Qiu <qiulaibin(a)huawei.com> hulk inclusion category: bugfix bugzilla: 181879, https://gitee.com/openeuler/kernel/issues/I4AJ00 CVE: NA -------------------------- KASAN reports a use-after-free report when doing fuzz test: [693354.104835] ================================================================== [693354.105094] BUG: KASAN: use-after-free in bfq_io_set_weight_legacy+0xd3/0x160 [693354.105336] Read of size 4 at addr ffff888be0a35664 by task sh/1453338 [693354.105607] CPU: 41 PID: 1453338 Comm: sh Kdump: loaded Not tainted 4.18.0-147 [693354.105610] Hardware name: Huawei 2288H V5/BC11SPSCB0, BIOS 0.81 07/02/2018 [693354.105612] Call Trace: [693354.105621] dump_stack+0xf1/0x19b [693354.105626] ? show_regs_print_info+0x5/0x5 [693354.105634] ? printk+0x9c/0xc3 [693354.105638] ? cpumask_weight+0x1f/0x1f [693354.105648] print_address_description+0x70/0x360 [693354.105654] kasan_report+0x1b2/0x330 [693354.105659] ? bfq_io_set_weight_legacy+0xd3/0x160 [693354.105665] ? bfq_io_set_weight_legacy+0xd3/0x160 [693354.105670] bfq_io_set_weight_legacy+0xd3/0x160 [693354.105675] ? bfq_cpd_init+0x20/0x20 [693354.105683] cgroup_file_write+0x3aa/0x510 [693354.105693] ? ___slab_alloc+0x507/0x540 [693354.105698] ? cgroup_file_poll+0x60/0x60 [693354.105702] ? 0xffffffff89600000 [693354.105708] ? usercopy_abort+0x90/0x90 [693354.105716] ? mutex_lock+0xef/0x180 [693354.105726] kernfs_fop_write+0x1ab/0x280 [693354.105732] ? cgroup_file_poll+0x60/0x60 [693354.105738] vfs_write+0xe7/0x230 [693354.105744] ksys_write+0xb0/0x140 [693354.105749] ? __ia32_sys_read+0x50/0x50 [693354.105760] do_syscall_64+0x112/0x370 [693354.105766] ? syscall_return_slowpath+0x260/0x260 [693354.105772] ? do_page_fault+0x9b/0x270 [693354.105779] ? prepare_exit_to_usermode+0xf9/0x1a0 [693354.105784] ? enter_from_user_mode+0x30/0x30 [693354.105793] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.105875] Allocated by task 1453337: [693354.106001] kasan_kmalloc+0xa0/0xd0 [693354.106006] kmem_cache_alloc_node_trace+0x108/0x220 [693354.106010] bfq_pd_alloc+0x96/0x120 [693354.106015] blkcg_activate_policy+0x1b7/0x2b0 [693354.106020] bfq_create_group_hierarchy+0x1e/0x80 [693354.106026] bfq_init_queue+0x678/0x8c0 [693354.106031] blk_mq_init_sched+0x1f8/0x460 [693354.106037] elevator_switch_mq+0xe1/0x240 [693354.106041] elevator_switch+0x25/0x40 [693354.106045] elv_iosched_store+0x1a1/0x230 [693354.106049] queue_attr_store+0x78/0xb0 [693354.106053] kernfs_fop_write+0x1ab/0x280 [693354.106056] vfs_write+0xe7/0x230 [693354.106060] ksys_write+0xb0/0x140 [693354.106064] do_syscall_64+0x112/0x370 [693354.106069] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.106114] Freed by task 1453336: [693354.106225] __kasan_slab_free+0x130/0x180 [693354.106229] kfree+0x90/0x1b0 [693354.106233] blkcg_deactivate_policy+0x12c/0x220 [693354.106238] bfq_exit_queue+0xf5/0x110 [693354.106241] blk_mq_exit_sched+0x104/0x130 [693354.106245] __elevator_exit+0x45/0x60 [693354.106249] elevator_switch_mq+0xd6/0x240 [693354.106253] elevator_switch+0x25/0x40 [693354.106257] elv_iosched_store+0x1a1/0x230 [693354.106261] queue_attr_store+0x78/0xb0 [693354.106264] kernfs_fop_write+0x1ab/0x280 [693354.106268] vfs_write+0xe7/0x230 [693354.106271] ksys_write+0xb0/0x140 [693354.106275] do_syscall_64+0x112/0x370 [693354.106280] entry_SYSCALL_64_after_hwframe+0x65/0xca [693354.106329] The buggy address belongs to the object at ffff888be0a35580 which belongs to the cache kmalloc-1k of size 1024 [693354.106736] The buggy address is located 228 bytes inside of 1024-byte region [ffff888be0a35580, ffff888be0a35980) [693354.107114] The buggy address belongs to the page: [693354.107273] page:ffffea002f828c00 count:1 mapcount:0 mapping:ffff888107c17080 index:0x0 compound_mapcount: 0 [693354.107606] flags: 0x17ffffc0008100(slab|head) [693354.107760] raw: 0017ffffc0008100 ffffea002fcbc808 ffffea0030bd3a08 ffff888107c17080 [693354.108020] raw: 0000000000000000 00000000001c001c 00000001ffffffff 0000000000000000 [693354.108278] page dumped because: kasan: bad access detected [693354.108511] Memory state around the buggy address: [693354.108671] ffff888be0a35500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [693354.116396] ffff888be0a35580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.124473] >ffff888be0a35600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.132421] ^ [693354.140284] ffff888be0a35680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.147912] ffff888be0a35700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [693354.155281] ================================================================== blkgs are protected by both queue and blkcg locks and holding either should stabilize them. However, the path of destroying blkg policy data is only protected by queue lock in blkcg_activate_policy()/blkcg_deactivate_policy(). Other tasks can get the blkg policy data before the blkg policy data is destroyed, and use it after destroyed, which will result in a use-after-free. CPU0 CPU1 blkcg_deactivate_policy spin_lock_irq(&q->queue_lock) bfq_io_set_weight_legacy spin_lock_irq(&blkcg->lock) blkg_to_bfqg(blkg) pd_to_bfqg(blkg->pd[pol->plid]) ^^^^^^blkg->pd[pol->plid] != NULL bfqg != NULL pol->pd_free_fn(blkg->pd[pol->plid]) pd_to_bfqg(blkg->pd[pol->plid]) bfqg_put(bfqg) kfree(bfqg) blkg->pd[pol->plid] = NULL spin_unlock_irq(q->queue_lock); bfq_group_set_weight(bfqg, val, 0) bfqg->entity.new_weight ^^^^^^trigger uaf here spin_unlock_irq(&blkcg->lock); Fix by garbbing the matching blkcg lock before trying to destroy blkg policy data. Signed-off-by: Li Jinlin <lijinlin3(a)huawei.com> Link: https://lore.kernel.org/linux-block/YUDLt9uBNLhWL6Gt@slm.duckdns.org/T/#r07… Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com> Reviewed-by: Jason Yan <yanaijie(a)huawei.com> Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com> --- block/blk-cgroup.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 05980d1a03f70..492e49f8e76c0 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1531,10 +1531,14 @@ int blkcg_activate_policy(struct request_queue *q, /* alloc failed, nothing's initialized yet, free everything */ spin_lock_irq(q->queue_lock); list_for_each_entry(blkg, &q->blkg_list, q_node) { + struct blkcg *blkcg = blkg->blkcg; + + spin_lock(&blkcg->lock); if (blkg->pd[pol->plid]) { pol->pd_free_fn(blkg->pd[pol->plid]); blkg->pd[pol->plid] = NULL; } + spin_unlock(&blkcg->lock); } spin_unlock_irq(q->queue_lock); ret = -ENOMEM; @@ -1568,12 +1572,16 @@ void blkcg_deactivate_policy(struct request_queue *q, __clear_bit(pol->plid, q->blkcg_pols); list_for_each_entry(blkg, &q->blkg_list, q_node) { + struct blkcg *blkcg = blkg->blkcg; + + spin_lock(&blkcg->lock); if (blkg->pd[pol->plid]) { if (pol->pd_offline_fn) pol->pd_offline_fn(blkg->pd[pol->plid]); pol->pd_free_fn(blkg->pd[pol->plid]); blkg->pd[pol->plid] = NULL; } + spin_unlock(&blkcg->lock); } spin_unlock_irq(q->queue_lock); -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS 1/6] Revert "sched/membarrier: fix NULL poiner in membarrier_global_expedited"
by Yang Yingliang 17 Sep '21

17 Sep '21
From: Li Hua <hucool.lihua(a)huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I3UKOW CVE: NA ------------------------------------------------- This reverts commit 3eb3533c1cb849559fc5a01410e7c863624b2ae5. Remove the work aroud to fix NULL poiner in membarrier_global_expedited, so as to prepare to introduce formal bug fix solution. Signed-off-by: Li Hua <hucool.lihua(a)huawei.com> Signed-off-by: Zheng Zucheng <zhengzucheng(a)huawei.com> Reviewed-by: Cheng Jian <cj.chengjian(a)huawei.com> Reviewed-by: Xie XiuQi <xiexiuqi(a)huawei.com> Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com> --- kernel/sched/membarrier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c index ea888ddb914f6..c4ea07e857985 100644 --- a/kernel/sched/membarrier.c +++ b/kernel/sched/membarrier.c @@ -115,7 +115,7 @@ static int membarrier_global_expedited(void) * scheduling a kthread. */ p = task_rcu_dereference(&cpu_rq(cpu)->curr); - if (p && p->flags & PF_KTHREAD) + if (p->flags & PF_KTHREAD) continue; __cpumask_set_cpu(cpu, tmpmask); -- 2.25.1
1 5
0 0
[PATCH kernel-4.19] ext4: update last_pos for the case ext4_htree_fill_tree return fail
by Yang Yingliang 17 Sep '21

17 Sep '21
From: yangerkun <yangerkun(a)huawei.com> hulk inclusion category: bugfix bugzilla: 181452, https://gitee.com/openeuler/kernel/issues/I4AI46 CVE: NA --------------------------- Or the ls for ext4 dir can run into a deadloop since info->last_pos != ctx->pos which will reset the world and start read the entry which has already got before. Details see below: 1. a dx_dir which has 3 block, block 0 as dx_root block, block 1/2 as leaf block which own the ext4_dir_entry_2 2. block 1 read ok and call_filldir which will fill the dirent and update the ctx->pos 3. block 2 read fail, but we has already fill some dirent, so we will return back to userspace will a positive return val(see ksys_getdents64) 4. the second ext4_dx_readdir will reset the world since info->last_pos != ctx->pos, and will also init the curr_hash which pos to block 1 5. So we will read block1 too, and once block2 still read fail, we can only fill one dirent because the hash of the entry in block1(besides the last one) won't greater than curr_hash 6. this time, we forget update last_pos too since the read for block2 will fail, and since we has got the one entry, ksys_getdents64 can return success 7. Latter we will trapped in a loop with step 4~6 Fix it by update last_pos too once ext4_htree_fill_tree return fail. Signed-off-by: yangerkun <yangerkun(a)huawei.com> Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com> Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com> --- fs/ext4/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index ae520a7263395..aed33af7551ee 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -535,7 +535,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx) struct dir_private_info *info = file->private_data; struct inode *inode = file_inode(file); struct fname *fname; - int ret; + int ret = 0; if (!info) { info = ext4_htree_create_dir_info(file, ctx->pos); @@ -583,7 +583,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx) info->curr_minor_hash, &info->next_hash); if (ret < 0) - return ret; + goto finished; if (ret == 0) { ctx->pos = ext4_get_htree_eof(file); break; @@ -614,7 +614,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx) } finished: info->last_pos = ctx->pos; - return 0; + return ret < 0 ? ret : 0; } static int ext4_dir_open(struct inode * inode, struct file * filp) -- 2.25.1
1 0
0 0
Re: [PATCH openEuler-1.0-LTS] net:fix tcp timeout retransmits are always missing 2 times
by Xie XiuQi 17 Sep '21

17 Sep '21
Hi zhenyuan, Thanks for your patch. Please subscribe the kernel(a)openeuler.org mailing list first, and then resend this patch again, or your patch would be blocked. Others could not receive this email. Click this link for subscribe mailing list: https://openeuler.org/zh/community/mailing-list/ On 2021/9/17 11:40, jiazhenyuan wrote: > mainline inclusion > from mainline-v5.3.0 > commit 3256a2d6ab1f71f9a1bd2d7f6f18eb8108c48d17 > category: bugfix > bugzilla: https://gitee.com/openeuler/kernel/issues/I4AFRJ?from=project-issue > CVE: NA > > --------------------------------------------------------------- > > tcp: adjust rto_base in retransmits_timed_out() > The cited commit exposed an old retransmits_timed_out() bug > which assumed it could call tcp_model_timeout() with > TCP_RTO_MIN as rto_base for all states. > > But flows in SYN_SENT or SYN_RECV state uses a different > RTO base (1 sec instead of 200 ms, unless BPF choses > another value) > > This caused a reduction of SYN retransmits from 6 to 4 with > the default /proc/sys/net/ipv4/tcp_syn_retries value. > > Fixes: a41e8a8 ("tcp: better handle TCP_USER_TIMEOUT in SYN_SENT state") > Signed-off-by: Eric Dumazet <edumazet(a)google.com> > Cc: Yuchung Cheng <ycheng(a)google.com> > Cc: Marek Majkowski <marek(a)cloudflare.com> > Signed-off-by: David S. Miller <davem(a)davemloft.net> > > Signed-off-by: jiazhenyuan <jiazhenyuan(a)uniontech.com> > --- > net/ipv4/tcp_timer.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c > index 681882a40968..81a47e87c35d 100644 > --- a/net/ipv4/tcp_timer.c > +++ b/net/ipv4/tcp_timer.c > @@ -190,7 +190,7 @@ static bool retransmits_timed_out(struct sock *sk, > unsigned int boundary, > unsigned int timeout) > { > - const unsigned int rto_base = TCP_RTO_MIN; > + unsigned int rto_base = TCP_RTO_MIN; > unsigned int linear_backoff_thresh, start_ts; > > if (!inet_csk(sk)->icsk_retransmits) > @@ -201,6 +201,9 @@ static bool retransmits_timed_out(struct sock *sk, > return false; > > if (likely(timeout == 0)) { > + if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) > + rto_base = tcp_timeout_init(sk); > + > linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); > > if (boundary <= linear_backoff_thresh) >
1 0
0 0
Re: [PATCH] arm64: smp: Fix cpu_freq print for NMI watchdog
by Xie XiuQi 17 Sep '21

17 Sep '21
Hi Wenchao, Thanks for your patch. Please subscribe the kernel(a)openeuler.org mailing list first, and then resend this patch again, or your patch would be blocked. Others who in the mailing list could not receive the emails. Click this link for subscribe mailing list: https://openeuler.org/zh/community/mailing-list/ On 2021/9/17 17:16, Wenchao Qin wrote: > hulk inclusion > category: bugfix > bugzilla: N/A > CVE: N/A > > ------------------------------ > > When we are in the arch_get_cpu_freq func for the first time, > after arch_probe_cpu_freq is excuted, the return of smp_processor_id() > will change due to preemption while cpu_freq get the freq belong to > original processor id, so pr_info will print the freq with wrong > processor id like below table from dmesg: > > [ 1.713211] NMI watchdog: CPU1 freq probed as 2189072384 HZ. > [ 1.810819] NMI watchdog: CPU1 freq probed as 2192003108 HZ. > [ 1.909910] NMI watchdog: CPU2 freq probed as 2191345967 HZ. > [ 2.015327] NMI watchdog: CPU3 freq probed as 2189460398 HZ. > > Actually, the first line should print the freq of CPU0, this bu > can occur in virtual machine with less then 17 vCPUs. > > Changing smp_processor_id() to cpu will fix the bug > > Signed-off-by: Wenchao Qin <qinwenchao(a)cmss.chinamobile.com> > --- > arch/arm64/kernel/smp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index fe56277..d685a27 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -1457,7 +1457,7 @@ static u64 arch_get_cpu_freq(void) > if (!cpu_freq) { > cpu_freq = arch_probe_cpu_freq(); > pr_info("NMI watchdog: CPU%u freq probed as %llu HZ.\n", > - smp_processor_id(), cpu_freq); > + cpu, cpu_freq); arch_probe_cpu_freq() 一样也会调用 smp_processor_id(),也可能存在被抢占的情况。 是不是需要关抢占? > if (!cpu_freq) > cpu_freq = -1; > per_cpu(cpu_freq_probed, cpu) = cpu_freq; >
1 0
0 0
[PATCH kernel-4.19] blk-throttle: fix UAF by deleteing timer in blk_throtl_exit()
by Yang Yingliang 16 Sep '21

16 Sep '21
From: Li Jinlin <lijinlin3(a)huawei.com> mainline inclusion from mainline-5.14 commit 884f0e84f1e3195b801319c8ec3d5774e9bf2710 category: bugfix bugzilla: NA CVE: NA The pending timer has been set up in blk_throtl_init(). However, the timer is not deleted in blk_throtl_exit(). This means that the timer handler may still be running after freeing the timer, which would result in a use-after-free. Fix by calling del_timer_sync() to delete the timer in blk_throtl_exit(). Signed-off-by: Li Jinlin <lijinlin3(a)huawei.com> Link: https://lore.kernel.org/r/20210907121242.2885564-1-lijinlin3@huawei.com Signed-off-by: Jens Axboe <axboe(a)kernel.dk> Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com> Reviewed-by: Jason Yan <yanaijie(a)huawei.com> Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com> --- block/blk-throttle.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 9426330d99dda..2c6df348faf5f 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -2482,6 +2482,7 @@ int blk_throtl_init(struct request_queue *q) void blk_throtl_exit(struct request_queue *q) { BUG_ON(!q->td); + del_timer_sync(&q->td->service_queue.pending_timer); throtl_shutdown_wq(q); blkcg_deactivate_policy(q, &blkcg_policy_throtl); free_percpu(q->td->latency_buckets[READ]); -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] fix hibmc did not get edid
by Gou Hao 16 Sep '21

16 Sep '21
From: gouhao <gouhao(a)uniontech.com> uniontech inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I469VQ CVE: NA ---------------------------------------------------------- fix hibmc did not get edid. backport from openEuler master branch: 4eb4d99dfe: drm/hisilicon: Support i2c driver algorithms for bit-shift a0d078d06e: drm/hisilicon: Features to support reading resolutions from EDID. Modified the a0d078d06e original patch. add include/drm/drm_probe_helper.h add drm_connector_init_with_ddc interface in /drivers/gpu/drm/drm_connector.c Signed-off-by: Daniel Vetter <daniel.vetter(a)ffwll.ch> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p(a)collabora.com> Signed-off-by: Tian Tao <tiantao6(a)hisilicon.com> Signed-off-by: Gou Hao <gouhao(a)uniontech.com> --- drivers/gpu/drm/drm_connector.c | 35 +++++++ drivers/gpu/drm/hisilicon/hibmc/Makefile | 3 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 27 +++++ .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 99 +++++++++++++++++++ .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 59 ++++++++--- include/drm/drm_connector.h | 17 ++++ include/drm/drm_probe_helper.h | 27 +++++ 7 files changed, 250 insertions(+), 17 deletions(-) create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c create mode 100644 include/drm/drm_probe_helper.h diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 6011d769d..ed49d0e93 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -290,6 +290,41 @@ out_put: } EXPORT_SYMBOL(drm_connector_init); +/** + * drm_connector_init_with_ddc - Init a preallocated connector + * @dev: DRM device + * @connector: the connector to init + * @funcs: callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: pointer to the associated ddc adapter + * + * Initialises a preallocated connector. Connectors should be + * subclassed as part of driver connector objects. + * + * Ensures that the ddc field of the connector is correctly set. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_connector_init_with_ddc(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) +{ + int ret; + + ret = drm_connector_init(dev, connector, funcs, connector_type); + if (ret) + return ret; + + /* provide ddc symlink in sysfs */ + connector->ddc = ddc; + + return ret; +} +EXPORT_SYMBOL(drm_connector_init_with_ddc); + /** * drm_connector_attach_encoder - attach a connector to an encoder * @connector: connector to attach diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile index 3df726696..14c1ca9c9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,3 +1,4 @@ -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_fbdev.o hibmc_ttm.o +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o \ + hibmc_drm_fbdev.o hibmc_ttm.o hibmc_drm_i2c.o obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 4395dc667..2b42864ba 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -19,12 +19,24 @@ #ifndef HIBMC_DRM_DRV_H #define HIBMC_DRM_DRV_H +#include <linux/gpio/consumer.h> +#include <linux/i2c-algo-bit.h> +#include <linux/i2c.h> + +#include <drm/drm_edid.h> #include <drm/drmP.h> #include <drm/drm_atomic.h> #include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> #include <drm/ttm/ttm_bo_driver.h> +struct hibmc_connector { + struct drm_connector base; + + struct i2c_adapter adapter; + struct i2c_algo_bit_data bit_data; +}; + struct hibmc_framebuffer { struct drm_framebuffer fb; struct drm_gem_object *obj; @@ -43,6 +55,8 @@ struct hibmc_drm_private { unsigned long fb_base; unsigned long fb_size; bool msi_enabled; + struct drm_encoder encoder; + struct hibmc_connector connector; /* drm */ struct drm_device *dev; @@ -60,6 +74,17 @@ struct hibmc_drm_private { bool mm_inited; }; +static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector) +{ + return container_of(connector, struct hibmc_connector, base); +} + +static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_device *dev) +{ + return dev->dev_private; +} + + #define to_hibmc_framebuffer(x) container_of(x, struct hibmc_framebuffer, fb) struct hibmc_bo { @@ -111,6 +136,8 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, u32 handle, u64 *offset); int hibmc_mmap(struct file *filp, struct vm_area_struct *vma); +int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); + extern const struct drm_mode_config_funcs hibmc_mode_funcs; #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c new file mode 100644 index 000000000..86d712090 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Hisilicon Hibmc SoC drm driver + * + * Based on the bochs drm driver. + * + * Copyright (c) 2016 Huawei Limited. + * + * Author: + * Tian Tao <tiantao6(a)hisilicon.com> + */ + +#include <linux/delay.h> +#include <linux/pci.h> + +#include <drm/drm_atomic_helper.h> +#include <drm/drm_probe_helper.h> + +#include "hibmc_drm_drv.h" + +#define GPIO_DATA 0x0802A0 +#define GPIO_DATA_DIRECTION 0x0802A4 + +#define I2C_SCL_MASK BIT(0) +#define I2C_SDA_MASK BIT(1) + +static void hibmc_set_i2c_signal(void *data, u32 mask, int value) +{ + struct hibmc_connector *hibmc_connector = data; + struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); + u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); + + if (value) { + tmp_dir &= ~mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } else { + u32 tmp_data = readl(priv->mmio + GPIO_DATA); + + tmp_data &= ~mask; + writel(tmp_data, priv->mmio + GPIO_DATA); + + tmp_dir |= mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } +} + +static int hibmc_get_i2c_signal(void *data, u32 mask) +{ + struct hibmc_connector *hibmc_connector = data; + struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); + u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); + + if ((tmp_dir & mask) != mask) { + tmp_dir &= ~mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } + + return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0; +} + +static void hibmc_ddc_setsda(void *data, int state) +{ + hibmc_set_i2c_signal(data, I2C_SDA_MASK, state); +} + +static void hibmc_ddc_setscl(void *data, int state) +{ + hibmc_set_i2c_signal(data, I2C_SCL_MASK, state); +} + +static int hibmc_ddc_getsda(void *data) +{ + return hibmc_get_i2c_signal(data, I2C_SDA_MASK); +} + +static int hibmc_ddc_getscl(void *data) +{ + return hibmc_get_i2c_signal(data, I2C_SCL_MASK); +} + +int hibmc_ddc_create(struct drm_device *drm_dev, + struct hibmc_connector *connector) +{ + connector->adapter.owner = THIS_MODULE; + connector->adapter.class = I2C_CLASS_DDC; + snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); + connector->adapter.dev.parent = &drm_dev->pdev->dev; + i2c_set_adapdata(&connector->adapter, connector); + connector->adapter.algo_data = &connector->bit_data; + + connector->bit_data.udelay = 20; + connector->bit_data.timeout = usecs_to_jiffies(2000); + connector->bit_data.data = connector; + connector->bit_data.setsda = hibmc_ddc_setsda; + connector->bit_data.setscl = hibmc_ddc_setscl; + connector->bit_data.getsda = hibmc_ddc_getsda; + connector->bit_data.getscl = hibmc_ddc_getscl; + + return i2c_bit_add_bus(&connector->adapter); +} diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 90319a902..3f176d500 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -59,11 +59,24 @@ static int hibmc_valid_mode(int w, int h) static int hibmc_connector_get_modes(struct drm_connector *connector) { int count; + void *edid; + struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + + edid = drm_get_edid(connector, &hibmc_connector->adapter); + if (edid) { + drm_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + if (count) + goto out; + } - drm_connector_update_edid_property(connector, NULL); - count = drm_add_modes_noedid(connector, 1920, 1200); + count = drm_add_modes_noedid(connector, + connector->dev->mode_config.max_width, + connector->dev->mode_config.max_height); drm_set_preferred_mode(connector, 1024, 768); +out: + kfree(edid); return count; } @@ -86,6 +99,14 @@ hibmc_connector_best_encoder(struct drm_connector *connector) return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); } +static void hibmc_connector_destroy(struct drm_connector *connector) +{ + struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + + i2c_del_adapter(&hibmc_connector->adapter); + drm_connector_cleanup(connector); +} + static const struct drm_connector_helper_funcs hibmc_connector_helper_funcs = { .get_modes = hibmc_connector_get_modes, @@ -95,7 +116,7 @@ static const struct drm_connector_helper_funcs static const struct drm_connector_funcs hibmc_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = drm_connector_cleanup, + .destroy = hibmc_connector_destroy, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, @@ -155,21 +176,15 @@ static const struct drm_encoder_funcs hibmc_encoder_funcs = { int hibmc_vdac_init(struct hibmc_drm_private *priv) { struct drm_device *dev = priv->dev; - struct drm_encoder *encoder; - struct drm_connector *connector; + struct hibmc_connector *hibmc_connector = &priv->connector; + struct drm_encoder *encoder = &priv->encoder; + struct drm_connector *connector = &hibmc_connector->base; int ret; - connector = hibmc_connector_init(priv); - if (IS_ERR(connector)) { - DRM_ERROR("failed to create connector: %ld\n", - PTR_ERR(connector)); - return PTR_ERR(connector); - } - - encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) { - DRM_ERROR("failed to alloc memory when init encoder\n"); - return -ENOMEM; + ret = hibmc_ddc_create(dev, hibmc_connector); + if (ret) { + DRM_ERROR("failed to create ddc: %d\n", ret); + return ret; } encoder->possible_crtcs = 0x1; @@ -181,6 +196,18 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) } drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); + + ret = drm_connector_init_with_ddc(dev, connector, + &hibmc_connector_funcs, + DRM_MODE_CONNECTOR_VGA, + &hibmc_connector->adapter); + if (ret) { + DRM_ERROR("failed to init connector: %d\n", ret); + return ret; + } + + drm_connector_helper_add(connector, &hibmc_connector_helper_funcs); + drm_connector_attach_encoder(connector, encoder); return 0; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 97ea41dc6..b9efb4564 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -998,6 +998,18 @@ struct drm_connector { * [0]: progressive, [1]: interlaced */ int audio_latency[2]; + + /** + * @ddc: associated ddc adapter. + * A connector usually has its associated ddc adapter. If a driver uses + * this field, then an appropriate symbolic link is created in connector + * sysfs directory to make it easy for the user to tell which i2c + * adapter is for a particular display. + * + * The field should be set by calling drm_connector_init_with_ddc(). + */ + struct i2c_adapter *ddc; + /** * @null_edid_counter: track sinks that give us all zeros for the EDID. * Needed to workaround some HW bugs where we get all 0s @@ -1083,6 +1095,11 @@ int drm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type); +int drm_connector_init_with_ddc(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); int drm_connector_attach_encoder(struct drm_connector *connector, diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h new file mode 100644 index 000000000..8d3ed2834 --- /dev/null +++ b/include/drm/drm_probe_helper.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +#ifndef __DRM_PROBE_HELPER_H__ +#define __DRM_PROBE_HELPER_H__ + +#include <linux/types.h> + +struct drm_connector; +struct drm_device; +struct drm_modeset_acquire_ctx; + +int drm_helper_probe_single_connector_modes(struct drm_connector + *connector, uint32_t maxX, + uint32_t maxY); +int drm_helper_probe_detect(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force); +void drm_kms_helper_poll_init(struct drm_device *dev); +void drm_kms_helper_poll_fini(struct drm_device *dev); +bool drm_helper_hpd_irq_event(struct drm_device *dev); +void drm_kms_helper_hotplug_event(struct drm_device *dev); + +void drm_kms_helper_poll_disable(struct drm_device *dev); +void drm_kms_helper_poll_enable(struct drm_device *dev); +bool drm_kms_helper_is_poll_worker(void); + +#endif -- 2.20.1
2 1
0 0
【Meeting Notice】openEuler kernel 技术分享第十二期 & 双周例会 Time: 2021-09-17 14:00-17:00
by Meeting Book 16 Sep '21

16 Sep '21
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • ...
  • 13
  • Older →

HyperKitty Powered by HyperKitty