Commit b83d005e authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Fix System panic after loading the driver

System panic with general protection fault during driver load

The driver uses a static array sli4_hba.handler_name to store the irq
handler names. If the io_channel_irqs exceeds the pre-allocated size
(32+1), then the driver will overwrite other fields of sli4_hba.

Fix: Dynamically allocate handler_name.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ecbb227e
...@@ -9665,6 +9665,7 @@ static int ...@@ -9665,6 +9665,7 @@ static int
lpfc_sli4_enable_msix(struct lpfc_hba *phba) lpfc_sli4_enable_msix(struct lpfc_hba *phba)
{ {
int vectors, rc, index; int vectors, rc, index;
char *name;
/* Set up MSI-X multi-message vectors */ /* Set up MSI-X multi-message vectors */
vectors = phba->io_channel_irqs; vectors = phba->io_channel_irqs;
...@@ -9683,9 +9684,9 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) ...@@ -9683,9 +9684,9 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
/* Assign MSI-X vectors to interrupt handlers */ /* Assign MSI-X vectors to interrupt handlers */
for (index = 0; index < vectors; index++) { for (index = 0; index < vectors; index++) {
memset(&phba->sli4_hba.handler_name[index], 0, 16); name = phba->sli4_hba.hba_eq_hdl[index].handler_name;
snprintf((char *)&phba->sli4_hba.handler_name[index], memset(name, 0, LPFC_SLI4_HANDLER_NAME_SZ);
LPFC_SLI4_HANDLER_NAME_SZ, snprintf(name, LPFC_SLI4_HANDLER_NAME_SZ,
LPFC_DRIVER_HANDLER_NAME"%d", index); LPFC_DRIVER_HANDLER_NAME"%d", index);
phba->sli4_hba.hba_eq_hdl[index].idx = index; phba->sli4_hba.hba_eq_hdl[index].idx = index;
...@@ -9694,12 +9695,12 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) ...@@ -9694,12 +9695,12 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
if (phba->cfg_fof && (index == (vectors - 1))) if (phba->cfg_fof && (index == (vectors - 1)))
rc = request_irq(pci_irq_vector(phba->pcidev, index), rc = request_irq(pci_irq_vector(phba->pcidev, index),
&lpfc_sli4_fof_intr_handler, 0, &lpfc_sli4_fof_intr_handler, 0,
(char *)&phba->sli4_hba.handler_name[index], name,
&phba->sli4_hba.hba_eq_hdl[index]); &phba->sli4_hba.hba_eq_hdl[index]);
else else
rc = request_irq(pci_irq_vector(phba->pcidev, index), rc = request_irq(pci_irq_vector(phba->pcidev, index),
&lpfc_sli4_hba_intr_handler, 0, &lpfc_sli4_hba_intr_handler, 0,
(char *)&phba->sli4_hba.handler_name[index], name,
&phba->sli4_hba.hba_eq_hdl[index]); &phba->sli4_hba.hba_eq_hdl[index]);
if (rc) { if (rc) {
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
......
...@@ -407,8 +407,10 @@ struct lpfc_max_cfg_param { ...@@ -407,8 +407,10 @@ struct lpfc_max_cfg_param {
struct lpfc_hba; struct lpfc_hba;
/* SLI4 HBA multi-fcp queue handler struct */ /* SLI4 HBA multi-fcp queue handler struct */
#define LPFC_SLI4_HANDLER_NAME_SZ 16
struct lpfc_hba_eq_hdl { struct lpfc_hba_eq_hdl {
uint32_t idx; uint32_t idx;
char handler_name[LPFC_SLI4_HANDLER_NAME_SZ];
struct lpfc_hba *phba; struct lpfc_hba *phba;
atomic_t hba_eq_in_use; atomic_t hba_eq_in_use;
struct cpumask *cpumask; struct cpumask *cpumask;
...@@ -480,7 +482,6 @@ struct lpfc_sli4_lnk_info { ...@@ -480,7 +482,6 @@ struct lpfc_sli4_lnk_info {
#define LPFC_SLI4_HANDLER_CNT (LPFC_HBA_IO_CHAN_MAX+ \ #define LPFC_SLI4_HANDLER_CNT (LPFC_HBA_IO_CHAN_MAX+ \
LPFC_FOF_IO_CHAN_NUM) LPFC_FOF_IO_CHAN_NUM)
#define LPFC_SLI4_HANDLER_NAME_SZ 16
/* Used for IRQ vector to CPU mapping */ /* Used for IRQ vector to CPU mapping */
struct lpfc_vector_map_info { struct lpfc_vector_map_info {
...@@ -548,7 +549,6 @@ struct lpfc_sli4_hba { ...@@ -548,7 +549,6 @@ struct lpfc_sli4_hba {
uint32_t ue_to_rp; uint32_t ue_to_rp;
struct lpfc_register sli_intf; struct lpfc_register sli_intf;
struct lpfc_pc_sli4_params pc_sli4_params; struct lpfc_pc_sli4_params pc_sli4_params;
uint8_t handler_name[LPFC_SLI4_HANDLER_CNT][LPFC_SLI4_HANDLER_NAME_SZ];
struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */ struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */
/* Pointers to the constructed SLI4 queues */ /* Pointers to the constructed SLI4 queues */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment