> On Apr 19, 2021, at 6:01 AM, Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> wrote: > > Read PCI_EXT_CAP_ID_DSN to know security status. > > Driver will throw an warning message when a non-secure type controller > is detected. 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. > > Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> > Reviewed-by: Hannes Reinecke <hare@xxxxxxx> > Reviewed-by: Tomas Henzl <thenzl@xxxxxxxxxx> > > Cc: sathya.prakash@xxxxxxxxxxxx > --- > drivers/scsi/mpi3mr/mpi3mr.h | 9 ++++ > drivers/scsi/mpi3mr/mpi3mr_os.c | 80 +++++++++++++++++++++++++++++++++ > 2 files changed, 89 insertions(+) > > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h > index 505df0e7b852..db9cb11db3bf 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr.h > +++ b/drivers/scsi/mpi3mr/mpi3mr.h > @@ -149,6 +149,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 | \ > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c > index 05473b0f3c9e..836005ce6999 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c > @@ -3206,6 +3206,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 > @@ -3228,6 +3297,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) { > @@ -3344,6 +3418,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); > @@ -3464,6 +3541,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", > -- > 2.18.1 > Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> -- Himanshu Madhani Oracle Linux Engineering