From: Igor Pylypiv ipylypiv@google.com
stable inclusion from stable-v5.10.85 commit 1e434d2687e8bc0b3cdc9dd093c0e9047c0b4add bugzilla: 186032 https://gitee.com/openeuler/kernel/issues/I4QVI4
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 653926205741add87a6cf452e21950eebc6ac10b upstream.
Calling scsi_remove_host() before scsi_add_host() results in a crash:
BUG: kernel NULL pointer dereference, address: 0000000000000108 RIP: 0010:device_del+0x63/0x440 Call Trace: device_unregister+0x17/0x60 scsi_remove_host+0xee/0x2a0 pm8001_pci_probe+0x6ef/0x1b90 [pm80xx] local_pci_probe+0x3f/0x90
We cannot call scsi_remove_host() in pm8001_alloc() because scsi_add_host() has not been called yet at that point in time.
Function call tree:
pm8001_pci_probe() | `- pm8001_pci_alloc() | | | `- pm8001_alloc() | | | `- scsi_remove_host() | `- scsi_add_host()
Link: https://lore.kernel.org/r/20211201041627.1592487-1-ipylypiv@google.com Fixes: 05c6c029a44d ("scsi: pm80xx: Increase number of supported queues") Reviewed-by: Vishakha Channapattan vishakhavc@google.com Acked-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Chen Jun chenjun102@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/scsi/pm8001/pm8001_init.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 13b8ddec6189..01eb2ade2070 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -280,12 +280,12 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, if (rc) { pm8001_dbg(pm8001_ha, FAIL, "pm8001_setup_irq failed [ret: %d]\n", rc); - goto err_out_shost; + goto err_out; } /* Request Interrupt */ rc = pm8001_request_irq(pm8001_ha); if (rc) - goto err_out_shost; + goto err_out;
count = pm8001_ha->max_q_num; /* Queues are chosen based on the number of cores/msix availability */ @@ -419,8 +419,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_tag_init(pm8001_ha); return 0;
-err_out_shost: - scsi_remove_host(pm8001_ha->shost); err_out_nodev: for (i = 0; i < pm8001_ha->max_memcnt; i++) { if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {