scsi: mpt3sas: Detect tampered Aero and Sea adapters
The driver will throw an error message when a tampered type controller is detected. The intent is to avoid interacting with any firmware which is not secured/signed by Broadcom. Any tampering on firmware component will be detected by hardware and it will be communicated to the driver to avoid any further interaction with that component. [mkp: switched back to dev_err] Link: https://lore.kernel.org/r/20200814130426.2741171-1-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
62aa501dc9
commit
f38c43a0e9
@ -10091,6 +10091,34 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
|
||||
mutex_unlock(&ioc->scsih_cmds.mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* _scsih_get_shost_and_ioc - get shost and ioc
|
||||
* and verify whether they are NULL or not
|
||||
* @pdev: PCI device struct
|
||||
* @shost: address of scsi host pointer
|
||||
* @ioc: address of HBA adapter pointer
|
||||
*
|
||||
* Return zero if *shost and *ioc are not NULL otherwise return error number.
|
||||
*/
|
||||
static int
|
||||
_scsih_get_shost_and_ioc(struct pci_dev *pdev,
|
||||
struct Scsi_Host **shost, struct MPT3SAS_ADAPTER **ioc)
|
||||
{
|
||||
*shost = pci_get_drvdata(pdev);
|
||||
if (*shost == NULL) {
|
||||
dev_err(&pdev->dev, "pdev's driver data is null\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
*ioc = shost_priv(*shost);
|
||||
if (*ioc == NULL) {
|
||||
dev_err(&pdev->dev, "shost's private data is null\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* scsih_remove - detach and remove add host
|
||||
* @pdev: PCI device struct
|
||||
@ -10099,8 +10127,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
|
||||
*/
|
||||
static void scsih_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
struct _sas_port *mpt3sas_port, *next_port;
|
||||
struct _raid_device *raid_device, *next;
|
||||
struct MPT3SAS_TARGET *sas_target_priv_data;
|
||||
@ -10109,6 +10137,9 @@ static void scsih_remove(struct pci_dev *pdev)
|
||||
unsigned long flags;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return;
|
||||
|
||||
ioc->remove_host = 1;
|
||||
|
||||
if (!pci_device_is_present(pdev))
|
||||
@ -10188,12 +10219,15 @@ static void scsih_remove(struct pci_dev *pdev)
|
||||
static void
|
||||
scsih_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
struct workqueue_struct *wq;
|
||||
unsigned long flags;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return;
|
||||
|
||||
ioc->remove_host = 1;
|
||||
|
||||
if (!pci_device_is_present(pdev))
|
||||
@ -10763,6 +10797,10 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
|
||||
case MPI26_MFGPAGE_DEVID_HARD_SEC_3916:
|
||||
case MPI26_MFGPAGE_DEVID_CFG_SEC_3816:
|
||||
case MPI26_MFGPAGE_DEVID_HARD_SEC_3816:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID0_3916:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID1_3916:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID0_3816:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID1_3816:
|
||||
return MPI26_VERSION;
|
||||
}
|
||||
return 0;
|
||||
@ -10852,6 +10890,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
case MPI26_ATLAS_PCIe_SWITCH_DEVID:
|
||||
ioc->is_gen35_ioc = 1;
|
||||
break;
|
||||
case MPI26_MFGPAGE_DEVID_INVALID0_3816:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID0_3916:
|
||||
dev_err(&pdev->dev,
|
||||
"HBA with DeviceId 0x%04x, sub VendorId 0x%04x, sub DeviceId 0x%04x is Invalid",
|
||||
pdev->device, pdev->subsystem_vendor,
|
||||
pdev->subsystem_device);
|
||||
return 1;
|
||||
case MPI26_MFGPAGE_DEVID_INVALID1_3816:
|
||||
case MPI26_MFGPAGE_DEVID_INVALID1_3916:
|
||||
dev_err(&pdev->dev,
|
||||
"HBA with DeviceId 0x%04x, sub VendorId 0x%04x, sub DeviceId 0x%04x is Tampered",
|
||||
pdev->device, pdev->subsystem_vendor,
|
||||
pdev->subsystem_device);
|
||||
return 1;
|
||||
case MPI26_MFGPAGE_DEVID_CFG_SEC_3816:
|
||||
case MPI26_MFGPAGE_DEVID_CFG_SEC_3916:
|
||||
dev_info(&pdev->dev,
|
||||
@ -11043,9 +11095,14 @@ out_add_shost_fail:
|
||||
static int
|
||||
scsih_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
pci_power_t device_state;
|
||||
int rc;
|
||||
|
||||
rc = _scsih_get_shost_and_ioc(pdev, &shost, &ioc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
mpt3sas_base_stop_watchdog(ioc);
|
||||
flush_scheduled_work();
|
||||
@ -11070,11 +11127,15 @@ scsih_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int
|
||||
scsih_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
pci_power_t device_state = pdev->current_state;
|
||||
int r;
|
||||
|
||||
r = _scsih_get_shost_and_ioc(pdev, &shost, &ioc);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ioc_info(ioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
|
||||
pdev, pci_name(pdev), device_state);
|
||||
|
||||
@ -11105,8 +11166,11 @@ scsih_resume(struct pci_dev *pdev)
|
||||
static pci_ers_result_t
|
||||
scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
ioc_info(ioc, "PCI error: detected callback, state(%d)!!\n", state);
|
||||
|
||||
@ -11141,10 +11205,13 @@ scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
|
||||
static pci_ers_result_t
|
||||
scsih_pci_slot_reset(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
int rc;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
ioc_info(ioc, "PCI error: slot reset callback!!\n");
|
||||
|
||||
ioc->pci_error_recovery = 0;
|
||||
@ -11177,8 +11244,11 @@ scsih_pci_slot_reset(struct pci_dev *pdev)
|
||||
static void
|
||||
scsih_pci_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return;
|
||||
|
||||
ioc_info(ioc, "PCI error: resume callback!!\n");
|
||||
|
||||
@ -11193,8 +11263,11 @@ scsih_pci_resume(struct pci_dev *pdev)
|
||||
static pci_ers_result_t
|
||||
scsih_pci_mmio_enabled(struct pci_dev *pdev)
|
||||
{
|
||||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
struct Scsi_Host *shost;
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
|
||||
if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc))
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
||||
ioc_info(ioc, "PCI error: mmio enabled callback!!\n");
|
||||
|
||||
@ -11342,6 +11415,14 @@ static const struct pci_device_id mpt3sas_pci_table[] = {
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3916,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
|
||||
/*
|
||||
* Aero SI –> 0x00E0 Invalid, 0x00E3 Tampered
|
||||
*/
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID0_3916,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID1_3916,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
|
||||
/* Atlas PCIe Switch Management Port */
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_ATLAS_PCIe_SWITCH_DEVID,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
@ -11354,6 +11435,14 @@ static const struct pci_device_id mpt3sas_pci_table[] = {
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3816,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
|
||||
/*
|
||||
* Sea SI –> 0x00E4 Invalid, 0x00E7 Tampered
|
||||
*/
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID0_3816,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_INVALID1_3816,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mpt3sas_pci_table);
|
||||
|
Loading…
Reference in New Issue
Block a user