scsi: mpi3mr: Add support for DSN secure firmware check
Read PCI_EXT_CAP_ID_DSN to query security status. The driver will throw a warning message when a non-secure type controller is detected. The purpose of this interface 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. Link: https://lore.kernel.org/r/20210520152545.2710479-23-kashyap.desai@broadcom.com Cc: sathya.prakash@broadcom.com Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Родитель
2f9c4d520a
Коммит
28cbe2f420
|
@ -154,6 +154,15 @@ extern struct list_head mrioc_list;
|
|||
#define MPI3MR_IRQ_POLL_SLEEP 2
|
||||
#define MPI3MR_IRQ_POLL_TRIGGER_IOCOUNT 8
|
||||
|
||||
/* Definitions for the controller security status*/
|
||||
#define MPI3MR_CTLR_SECURITY_STATUS_MASK 0x0C
|
||||
#define MPI3MR_CTLR_SECURE_DBG_STATUS_MASK 0x02
|
||||
|
||||
#define MPI3MR_INVALID_DEVICE 0x00
|
||||
#define MPI3MR_CONFIG_SECURE_DEVICE 0x04
|
||||
#define MPI3MR_HARD_SECURE_DEVICE 0x08
|
||||
#define MPI3MR_TAMPERED_DEVICE 0x0C
|
||||
|
||||
/* SGE Flag definition */
|
||||
#define MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST \
|
||||
(MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE | MPI3_SGE_FLAGS_DLAS_SYSTEM | \
|
||||
|
|
|
@ -3188,6 +3188,75 @@ static inline void mpi3mr_init_drv_cmd(struct mpi3mr_drv_cmd *cmdptr,
|
|||
cmdptr->host_tag = host_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* osintfc_mrioc_security_status -Check controller secure status
|
||||
* @pdev: PCI device instance
|
||||
*
|
||||
* Read the Device Serial Number capability from PCI config
|
||||
* space and decide whether the controller is secure or not.
|
||||
*
|
||||
* Return: 0 on success, non-zero on failure.
|
||||
*/
|
||||
static int
|
||||
osintfc_mrioc_security_status(struct pci_dev *pdev)
|
||||
{
|
||||
u32 cap_data;
|
||||
int base;
|
||||
u32 ctlr_status;
|
||||
u32 debug_status;
|
||||
int retval = 0;
|
||||
|
||||
base = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN);
|
||||
if (!base) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: PCI_EXT_CAP_ID_DSN is not supported\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pci_read_config_dword(pdev, base + 4, &cap_data);
|
||||
|
||||
debug_status = cap_data & MPI3MR_CTLR_SECURE_DBG_STATUS_MASK;
|
||||
ctlr_status = cap_data & MPI3MR_CTLR_SECURITY_STATUS_MASK;
|
||||
|
||||
switch (ctlr_status) {
|
||||
case MPI3MR_INVALID_DEVICE:
|
||||
dev_err(&pdev->dev,
|
||||
"%s: Non secure ctlr (Invalid) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",
|
||||
__func__, pdev->device, pdev->subsystem_vendor,
|
||||
pdev->subsystem_device);
|
||||
retval = -1;
|
||||
break;
|
||||
case MPI3MR_CONFIG_SECURE_DEVICE:
|
||||
if (!debug_status)
|
||||
dev_info(&pdev->dev,
|
||||
"%s: Config secure ctlr is detected\n",
|
||||
__func__);
|
||||
break;
|
||||
case MPI3MR_HARD_SECURE_DEVICE:
|
||||
break;
|
||||
case MPI3MR_TAMPERED_DEVICE:
|
||||
dev_err(&pdev->dev,
|
||||
"%s: Non secure ctlr (Tampered) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",
|
||||
__func__, pdev->device, pdev->subsystem_vendor,
|
||||
pdev->subsystem_device);
|
||||
retval = -1;
|
||||
break;
|
||||
default:
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!retval && debug_status) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: Non secure ctlr (Secure Dbg) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",
|
||||
__func__, pdev->device, pdev->subsystem_vendor,
|
||||
pdev->subsystem_device);
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_probe - PCI probe callback
|
||||
* @pdev: PCI device instance
|
||||
|
@ -3210,6 +3279,11 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
struct Scsi_Host *shost = NULL;
|
||||
int retval = 0, i;
|
||||
|
||||
if (osintfc_mrioc_security_status(pdev)) {
|
||||
warn_non_secure_ctlr = 1;
|
||||
return 1; /* For Invalid and Tampered device */
|
||||
}
|
||||
|
||||
shost = scsi_host_alloc(&mpi3mr_driver_template,
|
||||
sizeof(struct mpi3mr_ioc));
|
||||
if (!shost) {
|
||||
|
@ -3326,6 +3400,9 @@ static void mpi3mr_remove(struct pci_dev *pdev)
|
|||
unsigned long flags;
|
||||
struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next;
|
||||
|
||||
if (!shost)
|
||||
return;
|
||||
|
||||
mrioc = shost_priv(shost);
|
||||
while (mrioc->reset_in_progress || mrioc->is_driver_loading)
|
||||
ssleep(1);
|
||||
|
@ -3444,6 +3521,9 @@ static int mpi3mr_resume(struct pci_dev *pdev)
|
|||
pci_power_t device_state = pdev->current_state;
|
||||
int r;
|
||||
|
||||
if (!shost)
|
||||
return 0;
|
||||
|
||||
mrioc = shost_priv(shost);
|
||||
|
||||
ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
|
||||
|
|
Загрузка…
Ссылка в новой задаче