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

scsi: lpfc: Fix driver release of fw-logging buffers

On driver termination, after the driver stops fw logging by writing a
register on the chip, the driver immediately unmaps and frees the logging
buffer, without confirming in any way that the chip has received the write
and terminated the logging. As termination on the chip is not immediate,
the chip may issue a dma request to the now unmapped dma buffer, resulting
in a iommu fault.

Change the driver to receive a confirmation that logging ahs been
terminated. As the driver always issues an SLI reset with the device as
part of shutdown, and as part of that is receiving confirmation that the
reset is complete - the driver was modified to perform the write to disable
fw logging prior to the SLI reset and only free the fw log buffer after the
SLI reset is complete. That guarantees use of the fw log buffer is fully
terminated when it is unmapped.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 76558b25
...@@ -5380,25 +5380,6 @@ lpfc_bsg_get_ras_config(struct bsg_job *job) ...@@ -5380,25 +5380,6 @@ lpfc_bsg_get_ras_config(struct bsg_job *job)
return rc; return rc;
} }
/**
* lpfc_ras_stop_fwlog: Disable FW logging by the adapter
* @phba: Pointer to HBA context object.
*
* Disable FW logging into host memory on the adapter. To
* be done before reading logs from the host memory.
**/
static void
lpfc_ras_stop_fwlog(struct lpfc_hba *phba)
{
struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog;
ras_fwlog->ras_active = false;
/* Disable FW logging to host memory */
writel(LPFC_CTL_PDEV_CTL_DDL_RAS,
phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
}
/** /**
* lpfc_bsg_set_ras_config: Set FW logging parameters * lpfc_bsg_set_ras_config: Set FW logging parameters
* @job: fc_bsg_job to handle * @job: fc_bsg_job to handle
...@@ -5519,7 +5500,8 @@ lpfc_bsg_get_ras_lwpd(struct bsg_job *job) ...@@ -5519,7 +5500,8 @@ lpfc_bsg_get_ras_lwpd(struct bsg_job *job)
if (!ras_fwlog->lwpd.virt) { if (!ras_fwlog->lwpd.virt) {
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
"6193 Restart FW Logging\n"); "6193 Restart FW Logging\n");
return -EINVAL; rc = -EINVAL;
goto ras_job_error;
} }
/* Get lwpd offset */ /* Get lwpd offset */
......
...@@ -551,6 +551,7 @@ void lpfc_sli4_ras_init(struct lpfc_hba *phba); ...@@ -551,6 +551,7 @@ void lpfc_sli4_ras_init(struct lpfc_hba *phba);
void lpfc_sli4_ras_setup(struct lpfc_hba *phba); void lpfc_sli4_ras_setup(struct lpfc_hba *phba);
int lpfc_sli4_ras_fwlog_init(struct lpfc_hba *phba, uint32_t fwlog_level, int lpfc_sli4_ras_fwlog_init(struct lpfc_hba *phba, uint32_t fwlog_level,
uint32_t fwlog_enable); uint32_t fwlog_enable);
void lpfc_ras_stop_fwlog(struct lpfc_hba *phba);
int lpfc_check_fwlog_support(struct lpfc_hba *phba); int lpfc_check_fwlog_support(struct lpfc_hba *phba);
/* NVME interfaces. */ /* NVME interfaces. */
......
...@@ -10690,12 +10690,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) ...@@ -10690,12 +10690,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
kthread_stop(phba->worker_thread); kthread_stop(phba->worker_thread);
/* Disable FW logging to host memory */ /* Disable FW logging to host memory */
writel(LPFC_CTL_PDEV_CTL_DDL_RAS, lpfc_ras_stop_fwlog(phba);
phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
/* Free RAS DMA memory */
if (phba->ras_fwlog.ras_enabled == true)
lpfc_sli4_ras_dma_free(phba);
/* Unset the queues shared with the hardware then release all /* Unset the queues shared with the hardware then release all
* allocated resources. * allocated resources.
...@@ -10706,6 +10701,10 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) ...@@ -10706,6 +10701,10 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
/* Reset SLI4 HBA FCoE function */ /* Reset SLI4 HBA FCoE function */
lpfc_pci_function_reset(phba); lpfc_pci_function_reset(phba);
/* Free RAS DMA memory */
if (phba->ras_fwlog.ras_enabled)
lpfc_sli4_ras_dma_free(phba);
/* Stop the SLI4 device port */ /* Stop the SLI4 device port */
phba->pport->work_port_events = 0; phba->pport->work_port_events = 0;
} }
......
...@@ -6197,6 +6197,25 @@ lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox, ...@@ -6197,6 +6197,25 @@ lpfc_set_features(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox,
return; return;
} }
/**
* lpfc_ras_stop_fwlog: Disable FW logging by the adapter
* @phba: Pointer to HBA context object.
*
* Disable FW logging into host memory on the adapter. To
* be done before reading logs from the host memory.
**/
void
lpfc_ras_stop_fwlog(struct lpfc_hba *phba)
{
struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog;
ras_fwlog->ras_active = false;
/* Disable FW logging to host memory */
writel(LPFC_CTL_PDEV_CTL_DDL_RAS,
phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
}
/** /**
* lpfc_sli4_ras_dma_free - Free memory allocated for FW logging. * lpfc_sli4_ras_dma_free - Free memory allocated for FW logging.
* @phba: Pointer to HBA context object. * @phba: Pointer to HBA context object.
......
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