@@ -195,6 +195,21 @@ void pci_cma_init(struct pci_dev *pdev)
spdm_authenticate(pdev->spdm_state);
}
+/**
+ * pci_cma_reauthenticate() - Perform CMA-SPDM authentication again
+ * @pdev: Device to reauthenticate
+ *
+ * Can be called by drivers after device identity has mutated,
+ * e.g. after downloading firmware to an FPGA device.
+ */
+void pci_cma_reauthenticate(struct pci_dev *pdev)
+{
+ if (!pdev->spdm_state)
+ return;
+
+ spdm_authenticate(pdev->spdm_state);
+}
+
void pci_cma_destroy(struct pci_dev *pdev)
{
if (!pdev->spdm_state)
@@ -566,6 +566,7 @@ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
pci_pm_power_up_and_verify_state(pci_dev);
pci_restore_state(pci_dev);
pci_pme_restore(pci_dev);
+ pci_cma_reauthenticate(pci_dev);
}
static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
@@ -5074,8 +5074,16 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
rc = pci_dev_reset_slot_function(dev, probe);
if (rc != -ENOTTY)
- return rc;
- return pci_parent_bus_reset(dev, probe);
+ goto done;
+
+ rc = pci_parent_bus_reset(dev, probe);
+
+done:
+ /* CMA-SPDM state is lost upon a Conventional Reset */
+ if (!probe)
+ pci_cma_reauthenticate(dev);
+
+ return rc;
}
static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
@@ -451,9 +451,11 @@ static inline void pci_doe_disconnected(struct pci_dev *pdev) { }
#ifdef CONFIG_PCI_CMA
void pci_cma_init(struct pci_dev *pdev);
void pci_cma_destroy(struct pci_dev *pdev);
+void pci_cma_reauthenticate(struct pci_dev *pdev);
#else
static inline void pci_cma_init(struct pci_dev *pdev) { }
static inline void pci_cma_destroy(struct pci_dev *pdev) { }
+static inline void pci_cma_reauthenticate(struct pci_dev *pdev) { }
#endif
#ifdef CONFIG_PCI_NPEM
@@ -133,6 +133,9 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
+ /* CMA-SPDM state is lost upon a Conventional Reset */
+ pci_cma_reauthenticate(dev);
+
device_lock(&dev->dev);
pdrv = dev->driver;
if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset)