diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1599566..7b077a7 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -502,6 +502,45 @@ static void ghes_do_proc(const struct acpi_hest_generic_status *estatus)
 	}
 }
 
+/*
+ * If an uncorrected recoverable PCIe error is reported, the corresponding
+ * PCI device is marked as tainted. The device remains tainted until the
+ * claiming driver does a recovery. The PCI device is identified from the
+ * error record.
+ */
+static void ghes_mark_dev_err(const struct acpi_hest_generic_status *estatus)
+{
+	int sev, sec_sev;
+	struct acpi_hest_generic_data *gdata;
+
+	sev = ghes_severity(estatus->error_severity);
+	apei_estatus_for_each_section(estatus, gdata) {
+		sec_sev = ghes_severity(gdata->error_severity);
+		if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
+				      CPER_SEC_PCIE)) {
+			struct cper_sec_pcie *pcie_err;
+			pcie_err = (struct cper_sec_pcie *)(gdata+1);
+			if (sev == GHES_SEV_RECOVERABLE &&
+					sec_sev == GHES_SEV_RECOVERABLE &&
+					pcie_err->validation_bits &
+						CPER_PCIE_VALID_DEVICE_ID &&
+					pcie_err->validation_bits &
+						CPER_PCIE_VALID_AER_INFO) {
+				unsigned int devfn;
+				struct pci_dev *pdev;
+				devfn = PCI_DEVFN(pcie_err->device_id.device,
+						  pcie_err->device_id.function);
+				pdev = pci_get_domain_bus_and_slot(
+						pcie_err->device_id.segment,
+						pcie_err->device_id.bus,
+						devfn);
+				if (!pdev)
+					continue;
+				pdev->dev_flags |= PCI_DEV_FLAGS_ERR_DETECTED;
+			}
+		}
+	}
+}
 static void __ghes_print_estatus(const char *pfx,
 				 const struct acpi_hest_generic *generic,
 				 const struct acpi_hest_generic_status *estatus)
@@ -868,6 +907,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
 			estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
 			memcpy(estatus, ghes->estatus, len);
 			llist_add(&estatus_node->llnode, &ghes_estatus_llist);
+			ghes_mark_dev_err(estatus);
+			aer_notify(0, NULL);
 		}
 next:
 #endif
