[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250828103357000A2MUuzw_xx2PHM0W4Y74K@zte.com.cn>
Date: Thu, 28 Aug 2025 10:33:57 +0800 (CST)
From: <liu.xuemei1@....com.cn>
To: <mani@...nel.org>, <kwilczynski@...nel.org>, <kishon@...nel.org>,
<bhelgaas@...gle.com>, <lpieralisi@...nel.org>
Cc: <liu.song13@....com.cn>, <linux-pci@...r.kernel.org>,
<linux-kernel@...r.kernel.org>
Subject: Re: [PATCH RESEND] PCI: endpoint: Avoid creating sub-groups asynchronously
>On Thu, Jul 10, 2025 at 02:38:45PM GMT, liu.xuemei1@....com.cn wrote:
>> From: Liu Song <liu.song13@....com.cn>
>>
>> The asynchronous creation of sub-groups by a delayed work could lead to an
>> null-pointer-dereference exception when the driver directory gets
>> removed before the work completes.
>>
>> The crash can be easily reproduced with the following commands.
>>
>> # mkdir test && rmdir test
>>
>
>Could you please share more info on repro? Where did you execute above commands?
>I see that you used QEMU, so I'm curious to repro the issue.
Sorry for the ambiguousness, the complete reproducer will be like:
# modprobe pci_epf_test
# cd /sys/kernel/config/pci_ep/functions/pci_epf_test
# mkdir test && rmdir test # repeated
I found this problem in testing an out-of-tree pci_epf driver in kernel 6.6. The
problem can be reproduced without a hardware, so I tested it with the newest
kernel in a VM.
>
>- Mani
>
>> Fixes this by using configfs_add_default_group() which does not have the
>> deadlock problem as configfs_register_group().
>>
>> Backtraces of the crash:
>> BUG: kernel NULL pointer dereference, address: 0000000000000088
>> #PF: supervisor write access in kernel mode
>> #PF: error_code(0x0002) - not-present page
>> PGD 0
>> Oops: Oops: 0002 [#1] SMP NOPTI
>> CPU: 4 UID: 0 PID: 371 Comm: kworker/4:1 Kdump: loaded Tainted: G E 6.16.0-rc3 #2 PREEMPT(lazy)
>> Tainted: [E]=UNSIGNED_MODULE
>> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>> Workqueue: events pci_epf_cfs_work
>> RIP: 0010:mutex_lock+0x1c/0x30
>> Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 53 48 89 fb 2e 2e 2e 31 c0 65 48 8b 15 5e 4c 29 02 31 c0 <f0> 48 0f b1 13 75 06 5b e9 97 8a 00 00 48 89 df 5b eb b1 90 90 90
>> RSP: 0018:ff64babb4111fdf0 EFLAGS: 00010246
>> RAX: 0000000000000000 RBX: 0000000000000088 RCX: 0000000000000000
>> RDX: ff2de9c80f5d3080 RSI: ffffffffb9e58559 RDI: 0000000000000088
>> RBP: ff2de9c8269df9c0 R08: 0000000000000040 R09: 0000000000000000
>> R10: ff64babb4111fdf0 R11: 00000000ffffffff R12: ff2de9c80f753e88
>> R13: ff2de9c80f753e00 R14: 0000000000000000 R15: ff2de9c80f753f98
>> FS: 0000000000000000(0000) GS:ff2de9d78069f000(0000) knlGS:0000000000000000
>> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: 0000000000000088 CR3: 0000000ac782c003 CR4: 0000000000773ef0
>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
>> PKRU: 55555554
>> Call Trace:
>> <TASK>
>> configfs_register_group+0x3d/0x190
>> pci_epf_cfs_work+0x41/0x110
>> process_one_work+0x18f/0x350
>> worker_thread+0x25a/0x3a0
>> ? __pfx_worker_thread+0x10/0x10
>> kthread+0xfc/0x240
>> ? __pfx_kthread+0x10/0x10
>> ? __pfx_kthread+0x10/0x10
>> ret_from_fork+0x14f/0x180
>> ? __pfx_kthread+0x10/0x10
>> ret_from_fork_asm+0x1a/0x30
>> </TASK>
>> Modules linked in: pci_epf_test(E) nft_fib_inet(E) nft_fib_ipv4(E) nft_fib_ipv6(E) nft_fib(E) nft_reject_inet(E) nf_reject_ipv4(E) nf_reject_ipv6(E) nft_reject(E) nft_ct(E) nft_chain_nat(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) rfkill(E) ip_set(E) nf_tables(E) intel_rapl_msr(E) intel_rapl_common(E) intel_uncore_frequency_common(E) qrtr(E) isst_if_common(E) skx_edac_common(E) nfit(E) libnvdimm(E) sunrpc(E) kvm_intel(E) vfat(E) fat(E) kvm(E) irqbypass(E) rapl(E) iTCO_wdt(E) 8139too(E) intel_pmc_bxt(E) iTCO_vendor_support(E) 8139cp(E) virtio_gpu(E) mii(E) virtio_input(E) virtio_dma_buf(E) i2c_i801(E) pcspkr(E) lpc_ich(E) i2c_smbus(E) virtio_balloon(E) joydev(E) loop(E) dm_multipath(E) nfnetlink(E) vsock_loopback(E) vmw_vsock_virtio_transport_common(E) vmw_vsock_vmci_transport(E) vsock(E) zram(E) lz4hc_compress(E) vmw_vmci(E) lz4_compress(E) xfs(E) polyval_clmulni(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha1_ssse3(E) serio_raw(E) scsi_dh_rdac(E) scsi_dh_emc(E)
>> scsi_dh_alua(E) fuse(E)
>> qemu_fw_cfg(E)
>> Unloaded tainted modules: intel_uncore_frequency(E):1 i10nm_edac(E):1 intel_cstate(E):1 intel_uncore(E):1 hv_vmbus(E):1
>> CR2: 0000000000000088
>> ---[ end trace 0000000000000000 ]---
>>
>> Fixes: e85a2d783762 ("PCI: endpoint: Add support in configfs to associate two EPCs with EPF")
>> Signed-off-by: Liu Song <liu.song13@....com.cn>
>> ---
>> drivers/pci/endpoint/pci-ep-cfs.c | 15 +++++----------
>> 1 file changed, 5 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
>> index ef50c82e647f..43feb6139fa3 100644
>> --- a/drivers/pci/endpoint/pci-ep-cfs.c
>> +++ b/drivers/pci/endpoint/pci-ep-cfs.c
>> @@ -23,7 +23,6 @@ struct pci_epf_group {
>> struct config_group group;
>> struct config_group primary_epc_group;
>> struct config_group secondary_epc_group;
>> - struct delayed_work cfs_work;
>> struct pci_epf *epf;
>> int index;
>> };
>> @@ -103,7 +102,7 @@ static struct config_group
>> secondary_epc_group = &epf_group->secondary_epc_group;
>> config_group_init_type_name(secondary_epc_group, "secondary",
>> &pci_secondary_epc_type);
>> - configfs_register_group(&epf_group->group, secondary_epc_group);
>> + configfs_add_default_group(secondary_epc_group, &epf_group->group);
>>
>> return secondary_epc_group;
>> }
>> @@ -166,7 +165,7 @@ static struct config_group
>>
>> config_group_init_type_name(primary_epc_group, "primary",
>> &pci_primary_epc_type);
>> - configfs_register_group(&epf_group->group, primary_epc_group);
>> + configfs_add_default_group(primary_epc_group, &epf_group->group);
>>
>> return primary_epc_group;
>> }
>> @@ -570,15 +569,13 @@ static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)
>> return;
>> }
>>
>> - configfs_register_group(&epf_group->group, group);
>> + configfs_add_default_group(group, &epf_group->group);
>> }
>>
>> -static void pci_epf_cfs_work(struct work_struct *work)
>> +static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group)
>> {
>> - struct pci_epf_group *epf_group;
>> struct config_group *group;
>>
>> - epf_group = container_of(work, struct pci_epf_group, cfs_work.work);
>> group = pci_ep_cfs_add_primary_group(epf_group);
>> if (IS_ERR(group)) {
>> pr_err("failed to create 'primary' EPC interface\n");
>> @@ -637,9 +634,7 @@ static struct config_group *pci_epf_make(struct config_group *group,
>>
>> kfree(epf_name);
>>
>> - INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work);
>> - queue_delayed_work(system_wq, &epf_group->cfs_work,
>> - msecs_to_jiffies(1));
>> + pci_epf_cfs_add_sub_groups(epf_group);
>>
>> return &epf_group->group;
>>
>> --
>> 2.27.0
>
>--
>மணிவண்ணன் சதாசிவம்
<div class="zcontentRow"><div><div><div class="control-group zhistoryPanel"><div class="zhistoryContent">>On Thu, Jul 10, 2025 at 02:38:45PM GMT, liu.xuemei1@....com.cn wrote:<br>>> From: Liu Song <liu.song13@....com.cn><br>>><br>>> The asynchronous creation of sub-groups by a delayed work could lead to an<br>>> null-pointer-dereference exception when the driver directory gets<br>>> removed before the work completes.<br>>><br>>> The crash can be easily reproduced with the following commands.<br>>><br>>> # mkdir test && rmdir test<br>>><br>><br>>Could you please share more info on repro? Where did you execute above commands?<br>>I see that you used QEMU, so I'm curious to repro the issue.<br><br>Sorry for the ambiguousness, the complete reproducer will be like:<br><br># modprobe pci_epf_test<br># cd /sys/kernel/config/pci_ep/functions/pci_epf_test<br># mkdir test && rmdir test # repeated<br><br>I found this problem in testing an out-of-tree pci_epf driver in kernel 6.6. The<br>problem can be reproduced without a hardware, so I tested it with the newest<br>kernel in a VM.<br><br>><br>>- Mani<br>><br>>> Fixes this by using configfs_add_default_group() which does not have the<br>>> deadlock problem as configfs_register_group().<br>>><br>>> Backtraces of the crash:<br>>> BUG: kernel NULL pointer dereference, address: 0000000000000088<br>>> #PF: supervisor write access in kernel mode<br>>> #PF: error_code(0x0002) - not-present page<br>>> PGD 0<br>>> Oops: Oops: 0002 [#1] SMP NOPTI<br>>> CPU: 4 UID: 0 PID: 371 Comm: kworker/4:1 Kdump: loaded Tainted: G E 6.16.0-rc3 #2 PREEMPT(lazy)<br>>> Tainted: [E]=UNSIGNED_MODULE<br>>> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015<br>>> Workqueue: events pci_epf_cfs_work<br>>> RIP: 0010:mutex_lock+0x1c/0x30<br>>> Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 53 48 89 fb 2e 2e 2e 31 c0 65 48 8b 15 5e 4c 29 02 31 c0 <f0> 48 0f b1 13 75 06 5b e9 97 8a 00 00 48 89 df 5b eb b1 90 90 90<br>>> RSP: 0018:ff64babb4111fdf0 EFLAGS: 00010246<br>>> RAX: 0000000000000000 RBX: 0000000000000088 RCX: 0000000000000000<br>>> RDX: ff2de9c80f5d3080 RSI: ffffffffb9e58559 RDI: 0000000000000088<br>>> RBP: ff2de9c8269df9c0 R08: 0000000000000040 R09: 0000000000000000<br>>> R10: ff64babb4111fdf0 R11: 00000000ffffffff R12: ff2de9c80f753e88<br>>> R13: ff2de9c80f753e00 R14: 0000000000000000 R15: ff2de9c80f753f98<br>>> FS: 0000000000000000(0000) GS:ff2de9d78069f000(0000) knlGS:0000000000000000<br>>> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br>>> CR2: 0000000000000088 CR3: 0000000ac782c003 CR4: 0000000000773ef0<br>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000<br>>> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400<br>>> PKRU: 55555554<br>>> Call Trace:<br>>> <TASK><br>>> configfs_register_group+0x3d/0x190<br>>> pci_epf_cfs_work+0x41/0x110<br>>> process_one_work+0x18f/0x350<br>>> worker_thread+0x25a/0x3a0<br>>> ? __pfx_worker_thread+0x10/0x10<br>>> kthread+0xfc/0x240<br>>> ? __pfx_kthread+0x10/0x10<br>>> ? __pfx_kthread+0x10/0x10<br>>> ret_from_fork+0x14f/0x180<br>>> ? __pfx_kthread+0x10/0x10<br>>> ret_from_fork_asm+0x1a/0x30<br>>> </TASK><br>>> Modules linked in: pci_epf_test(E) nft_fib_inet(E) nft_fib_ipv4(E) nft_fib_ipv6(E) nft_fib(E) nft_reject_inet(E) nf_reject_ipv4(E) nf_reject_ipv6(E) nft_reject(E) nft_ct(E) nft_chain_nat(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) rfkill(E) ip_set(E) nf_tables(E) intel_rapl_msr(E) intel_rapl_common(E) intel_uncore_frequency_common(E) qrtr(E) isst_if_common(E) skx_edac_common(E) nfit(E) libnvdimm(E) sunrpc(E) kvm_intel(E) vfat(E) fat(E) kvm(E) irqbypass(E) rapl(E) iTCO_wdt(E) 8139too(E) intel_pmc_bxt(E) iTCO_vendor_support(E) 8139cp(E) virtio_gpu(E) mii(E) virtio_input(E) virtio_dma_buf(E) i2c_i801(E) pcspkr(E) lpc_ich(E) i2c_smbus(E) virtio_balloon(E) joydev(E) loop(E) dm_multipath(E) nfnetlink(E) vsock_loopback(E) vmw_vsock_virtio_transport_common(E) vmw_vsock_vmci_transport(E) vsock(E) zram(E) lz4hc_compress(E) vmw_vmci(E) lz4_compress(E) xfs(E) polyval_clmulni(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha1_ssse3(E) serio_raw(E) scsi_dh_rdac(E) scsi_dh_emc(E)<br>>> scsi_dh_alua(E) fuse(E)<br>>> qemu_fw_cfg(E)<br>>> Unloaded tainted modules: intel_uncore_frequency(E):1 i10nm_edac(E):1 intel_cstate(E):1 intel_uncore(E):1 hv_vmbus(E):1<br>>> CR2: 0000000000000088<br>>> ---[ end trace 0000000000000000 ]---<br>>><br>>> Fixes: e85a2d783762 ("PCI: endpoint: Add support in configfs to associate two EPCs with EPF")<br>>> Signed-off-by: Liu Song <liu.song13@....com.cn><br>>> ---<br>>> drivers/pci/endpoint/pci-ep-cfs.c | 15 +++++----------<br>>> 1 file changed, 5 insertions(+), 10 deletions(-)<br>>><br>>> diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c<br>>> index ef50c82e647f..43feb6139fa3 100644<br>>> --- a/drivers/pci/endpoint/pci-ep-cfs.c<br>>> +++ b/drivers/pci/endpoint/pci-ep-cfs.c<br>>> @@ -23,7 +23,6 @@ struct pci_epf_group {<br>>> struct config_group group;<br>>> struct config_group primary_epc_group;<br>>> struct config_group secondary_epc_group;<br>>> - struct delayed_work cfs_work;<br>>> struct pci_epf *epf;<br>>> int index;<br>>> };<br>>> @@ -103,7 +102,7 @@ static struct config_group<br>>> secondary_epc_group = &epf_group->secondary_epc_group;<br>>> config_group_init_type_name(secondary_epc_group, "secondary",<br>>> &pci_secondary_epc_type);<br>>> - configfs_register_group(&epf_group->group, secondary_epc_group);<br>>> + configfs_add_default_group(secondary_epc_group, &epf_group->group);<br>>><br>>> return secondary_epc_group;<br>>> }<br>>> @@ -166,7 +165,7 @@ static struct config_group<br>>><br>>> config_group_init_type_name(primary_epc_group, "primary",<br>>> &pci_primary_epc_type);<br>>> - configfs_register_group(&epf_group->group, primary_epc_group);<br>>> + configfs_add_default_group(primary_epc_group, &epf_group->group);<br>>><br>>> return primary_epc_group;<br>>> }<br>>> @@ -570,15 +569,13 @@ static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)<br>>> return;<br>>> }<br>>><br>>> - configfs_register_group(&epf_group->group, group);<br>>> + configfs_add_default_group(group, &epf_group->group);<br>>> }<br>>><br>>> -static void pci_epf_cfs_work(struct work_struct *work)<br>>> +static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group)<br>>> {<br>>> - struct pci_epf_group *epf_group;<br>>> struct config_group *group;<br>>><br>>> - epf_group = container_of(work, struct pci_epf_group, cfs_work.work);<br>>> group = pci_ep_cfs_add_primary_group(epf_group);<br>>> if (IS_ERR(group)) {<br>>> pr_err("failed to create 'primary' EPC interface\n");<br>>> @@ -637,9 +634,7 @@ static struct config_group *pci_epf_make(struct config_group *group,<br>>><br>>> kfree(epf_name);<br>>><br>>> - INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work);<br>>> - queue_delayed_work(system_wq, &epf_group->cfs_work,<br>>> - msecs_to_jiffies(1));<br>>> + pci_epf_cfs_add_sub_groups(epf_group);<br>>><br>>> return &epf_group->group;<br>>><br>>> --<br>>> 2.27.0<br>><br>>--<br>>மணிவண்ணன் சதாசிவம்<br></div></div></div></div><p><br style="white-space: normal;"></p><p style="font-size:14px;font-family:微软雅黑,Microsoft YaHei;"><br></p><p style="font-size:14px;font-family:微软雅黑,Microsoft YaHei;"><br></p><p style="font-size:14px;font-family:微软雅黑,Microsoft YaHei;"><br></p><p style="font-size:14px;font-family:微软雅黑,Microsoft YaHei;"><br></p><p><br></p></div>
Powered by blists - more mailing lists