+++ /dev/null
-From 7a9788c654c6bc697212df29bce0cea2cae1e4f6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 May 2022 09:27:56 +0800
-Subject: powerpc/eeh: Drop redundant spinlock initialization
-
-From: Haowen Bai <baihaowen@meizu.com>
-
-[ Upstream commit 3def164a5cedad9117859dd4610cae2cc59cb6d2 ]
-
-slot_errbuf_lock has declared and initialized by DEFINE_SPINLOCK,
-so we don't need to spin_lock_init again, drop it.
-
-Signed-off-by: Haowen Bai <baihaowen@meizu.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/1652232476-9696-1-git-send-email-baihaowen@meizu.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 7a0b9aa09d10..f56248f19ef3 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -945,8 +945,7 @@ static int __init eeh_pseries_init(void)
- return -EINVAL;
- }
-
-- /* Initialize error log lock and size */
-- spin_lock_init(&slot_errbuf_lock);
-+ /* Initialize error log size */
- eeh_error_buf_size = rtas_token("rtas-error-log-max");
- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
- pr_info("%s: unknown EEH error log size\n",
---
-2.35.1
-
+++ /dev/null
-From 7364ac257fcea41fcce6deec87df6b6756ac5375 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 16 Aug 2019 14:48:09 +1000
-Subject: powerpc/eeh: EEH for pSeries hot plug
-
-From: Sam Bobroff <sbobroff@linux.ibm.com>
-
-[ Upstream commit b905f8cdca7725e750a84f7188ea6821750124c3 ]
-
-On PowerNV and pSeries, devices currently acquire EEH support from
-several different places: Boot-time devices from eeh_probe_devices()
-and eeh_addr_cache_build(), Virtual Function devices from the pcibios
-bus add device hooks and hot plugged devices from pci_hp_add_devices()
-(with other platforms using other methods as well). Unfortunately,
-pSeries machines currently discover hot plugged devices using
-pci_rescan_bus(), not pci_hp_add_devices(), and so those devices do
-not receive EEH support.
-
-Rather than adding another case for pci_rescan_bus(), this change
-widens the scope of the pcibios bus add device hooks so that they can
-handle all devices. As a side effect this also supports devices
-discovered after manually rescanning via /sys/bus/pci/rescan.
-
-Note that on PowerNV, this change allows the EEH subsystem to become
-enabled after boot as long as it has not been forced off, which was
-not previously possible (it was already possible on pSeries).
-
-Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/72ae8ae9c54097158894a52de23690448de38ea9.1565930772.git.sbobroff@linux.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/kernel/eeh.c | 4 +-
- arch/powerpc/platforms/powernv/eeh-powernv.c | 39 +++++++++-----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 54 ++++++++++----------
- 3 files changed, 56 insertions(+), 41 deletions(-)
-
-diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
-index 2b81e9a056b5..be475e946306 100644
---- a/arch/powerpc/kernel/eeh.c
-+++ b/arch/powerpc/kernel/eeh.c
-@@ -1170,7 +1170,7 @@ void eeh_add_device_late(struct pci_dev *dev)
- struct pci_dn *pdn;
- struct eeh_dev *edev;
-
-- if (!dev || !eeh_enabled())
-+ if (!dev)
- return;
-
- pr_debug("EEH: Adding device %s\n", pci_name(dev));
-@@ -1226,6 +1226,8 @@ void eeh_add_device_tree_late(struct pci_bus *bus)
- {
- struct pci_dev *dev;
-
-+ if (eeh_has_flag(EEH_FORCE_DISABLED))
-+ return;
- list_for_each_entry(dev, &bus->devices, bus_list) {
- eeh_add_device_late(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
-index 4fa601feb860..4dab6ffa3f69 100644
---- a/arch/powerpc/platforms/powernv/eeh-powernv.c
-+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
-@@ -47,7 +47,7 @@ void pnv_pcibios_bus_add_device(struct pci_dev *pdev)
- {
- struct pci_dn *pdn = pci_get_pdn(pdev);
-
-- if (!pdev->is_virtfn)
-+ if (eeh_has_flag(EEH_FORCE_DISABLED))
- return;
-
- pr_debug("%s: EEH: Setting up device %s.\n", __func__, pci_name(pdev));
-@@ -202,6 +202,25 @@ PNV_EEH_DBGFS_ENTRY(inbB, 0xE10);
-
- #endif /* CONFIG_DEBUG_FS */
-
-+void pnv_eeh_enable_phbs(void)
-+{
-+ struct pci_controller *hose;
-+ struct pnv_phb *phb;
-+
-+ list_for_each_entry(hose, &hose_list, list_node) {
-+ phb = hose->private_data;
-+ /*
-+ * If EEH is enabled, we're going to rely on that.
-+ * Otherwise, we restore to conventional mechanism
-+ * to clear frozen PE during PCI config access.
-+ */
-+ if (eeh_enabled())
-+ phb->flags |= PNV_PHB_FLAG_EEH;
-+ else
-+ phb->flags &= ~PNV_PHB_FLAG_EEH;
-+ }
-+}
-+
- /**
- * pnv_eeh_post_init - EEH platform dependent post initialization
- *
-@@ -248,19 +267,11 @@ int pnv_eeh_post_init(void)
- if (!eeh_enabled())
- disable_irq(eeh_event_irq);
-
-+ pnv_eeh_enable_phbs();
-+
- list_for_each_entry(hose, &hose_list, list_node) {
- phb = hose->private_data;
-
-- /*
-- * If EEH is enabled, we're going to rely on that.
-- * Otherwise, we restore to conventional mechanism
-- * to clear frozen PE during PCI config access.
-- */
-- if (eeh_enabled())
-- phb->flags |= PNV_PHB_FLAG_EEH;
-- else
-- phb->flags &= ~PNV_PHB_FLAG_EEH;
--
- /* Create debugfs entries */
- #ifdef CONFIG_DEBUG_FS
- if (phb->has_dbgfs || !phb->dbgfs)
-@@ -474,7 +485,11 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
- * Enable EEH explicitly so that we will do EEH check
- * while accessing I/O stuff
- */
-- eeh_add_flag(EEH_ENABLED);
-+ if (!eeh_has_flag(EEH_ENABLED)) {
-+ enable_irq(eeh_event_irq);
-+ pnv_eeh_enable_phbs();
-+ eeh_add_flag(EEH_ENABLED);
-+ }
-
- /* Save memory bars */
- eeh_save_bars(edev);
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index b4f77bc5f8bf..2713d2aa963c 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -55,44 +55,44 @@ static int ibm_get_config_addr_info;
- static int ibm_get_config_addr_info2;
- static int ibm_configure_pe;
-
--#ifdef CONFIG_PCI_IOV
- void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
- {
- struct pci_dn *pdn = pci_get_pdn(pdev);
-- struct pci_dn *physfn_pdn;
-- struct eeh_dev *edev;
-
-- if (!pdev->is_virtfn)
-+ if (eeh_has_flag(EEH_FORCE_DISABLED))
- return;
-
- pr_debug("%s: EEH: Setting up device %s.\n", __func__, pci_name(pdev));
-+#ifdef CONFIG_PCI_IOV
-+ if (pdev->is_virtfn) {
-+ struct pci_dn *physfn_pdn;
-
-- pdn->device_id = pdev->device;
-- pdn->vendor_id = pdev->vendor;
-- pdn->class_code = pdev->class;
-- /*
-- * Last allow unfreeze return code used for retrieval
-- * by user space in eeh-sysfs to show the last command
-- * completion from platform.
-- */
-- pdn->last_allow_rc = 0;
-- physfn_pdn = pci_get_pdn(pdev->physfn);
-- pdn->pe_number = physfn_pdn->pe_num_map[pdn->vf_index];
-- edev = pdn_to_eeh_dev(pdn);
--
-- /*
-- * The following operations will fail if VF's sysfs files
-- * aren't created or its resources aren't finalized.
-- */
-+ pdn->device_id = pdev->device;
-+ pdn->vendor_id = pdev->vendor;
-+ pdn->class_code = pdev->class;
-+ /*
-+ * Last allow unfreeze return code used for retrieval
-+ * by user space in eeh-sysfs to show the last command
-+ * completion from platform.
-+ */
-+ pdn->last_allow_rc = 0;
-+ physfn_pdn = pci_get_pdn(pdev->physfn);
-+ pdn->pe_number = physfn_pdn->pe_num_map[pdn->vf_index];
-+ }
-+#endif
- eeh_add_device_early(pdn);
- eeh_add_device_late(pdev);
-- edev->pe_config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
-- eeh_rmv_from_parent_pe(edev); /* Remove as it is adding to bus pe */
-- eeh_add_to_parent_pe(edev); /* Add as VF PE type */
-- eeh_sysfs_add_device(pdev);
-+#ifdef CONFIG_PCI_IOV
-+ if (pdev->is_virtfn) {
-+ struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
-
--}
-+ edev->pe_config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
-+ eeh_rmv_from_parent_pe(edev); /* Remove as it is adding to bus pe */
-+ eeh_add_to_parent_pe(edev); /* Add as VF PE type */
-+ }
- #endif
-+ eeh_sysfs_add_device(pdev);
-+}
-
- /*
- * Buffer for reporting slot-error-detail rtas calls. Its here
-@@ -159,10 +159,8 @@ static int pseries_eeh_init(void)
- /* Set EEH probe mode */
- eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
-
--#ifdef CONFIG_PCI_IOV
- /* Set EEH machine dependent code */
- ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
--#endif
-
- return 0;
- }
---
-2.35.1
-
+++ /dev/null
-From 03c8a9c0fa59b5b5bbb8a2e0bdede1e851845d2e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Apr 2020 13:45:05 +1000
-Subject: powerpc/eeh: Fix pseries_eeh_configure_bridge()
-
-From: Sam Bobroff <sbobroff@linux.ibm.com>
-
-[ Upstream commit 6fa13640aea7bb0760846981aa2da4245307bd26 ]
-
-If a device is hot unplgged during EEH recovery, it's possible for the
-RTAS call to ibm,configure-pe in pseries_eeh_configure() to return
-parameter error (-3), however negative return values are not checked
-for and this leads to an infinite loop.
-
-Fix this by correctly bailing out on negative values.
-
-Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Reviewed-by: Nathan Lynch <nathanl@linux.ibm.com>
-Link: https://lore.kernel.org/r/1b0a6010a647dc915816e44845b64d72066676a7.1588045502.git.sbobroff@linux.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 2713d2aa963c..0fc93f7e167d 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -684,6 +684,8 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
-
- if (!ret)
- return ret;
-+ if (ret < 0)
-+ break;
-
- /*
- * If RTAS returns a delay value that's above 100ms, cut it
-@@ -704,7 +706,11 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
-
- pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
- __func__, pe->phb->global_number, pe->addr, ret);
-- return ret;
-+ /* PAPR defines -3 as "Parameter Error" for this function: */
-+ if (ret == -3)
-+ return -EINVAL;
-+ else
-+ return -EIO;
- }
-
- /**
---
-2.35.1
-
+++ /dev/null
-From 8b8010a7292e03ac4ad0b2f8eae13cb845a01200 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 16 Aug 2019 14:48:07 +1000
-Subject: powerpc/eeh: Improve debug messages around device addition
-
-From: Sam Bobroff <sbobroff@linux.ibm.com>
-
-[ Upstream commit 617082a4817a4354fa3de05c80b5f6088e2083b7 ]
-
-Also remove useless comment.
-
-Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
-Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/59db84f4bf94718a12f206bc923ac797d47e4cc1.1565930772.git.sbobroff@linux.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/kernel/eeh.c | 2 +-
- arch/powerpc/platforms/powernv/eeh-powernv.c | 14 ++++++++----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 23 +++++++++++++++-----
- 3 files changed, 28 insertions(+), 11 deletions(-)
-
-diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
-index 44bb522fb4a2..2b81e9a056b5 100644
---- a/arch/powerpc/kernel/eeh.c
-+++ b/arch/powerpc/kernel/eeh.c
-@@ -1178,7 +1178,7 @@ void eeh_add_device_late(struct pci_dev *dev)
- pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
- edev = pdn_to_eeh_dev(pdn);
- if (edev->pdev == dev) {
-- pr_debug("EEH: Already referenced !\n");
-+ pr_debug("EEH: Device %s already referenced!\n", pci_name(dev));
- return;
- }
-
-diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
-index 9dd5b8909178..4fa601feb860 100644
---- a/arch/powerpc/platforms/powernv/eeh-powernv.c
-+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
-@@ -50,10 +50,7 @@ void pnv_pcibios_bus_add_device(struct pci_dev *pdev)
- if (!pdev->is_virtfn)
- return;
-
-- /*
-- * The following operations will fail if VF's sysfs files
-- * aren't created or its resources aren't finalized.
-- */
-+ pr_debug("%s: EEH: Setting up device %s.\n", __func__, pci_name(pdev));
- eeh_add_device_early(pdn);
- eeh_add_device_late(pdev);
- eeh_sysfs_add_device(pdev);
-@@ -378,6 +375,10 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
- int ret;
- int config_addr = (pdn->busno << 8) | (pdn->devfn);
-
-+ pr_debug("%s: probing %04x:%02x:%02x.%01x\n",
-+ __func__, hose->global_number, pdn->busno,
-+ PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
-+
- /*
- * When probing the root bridge, which doesn't have any
- * subordinate PCI devices. We don't have OF node for
-@@ -478,6 +479,11 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
- /* Save memory bars */
- eeh_save_bars(edev);
-
-+ pr_debug("%s: EEH enabled on %02x:%02x.%01x PHB#%x-PE#%x\n",
-+ __func__, pdn->busno, PCI_SLOT(pdn->devfn),
-+ PCI_FUNC(pdn->devfn), edev->pe->phb->global_number,
-+ edev->pe->addr);
-+
- return NULL;
- }
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 823cb27efa8b..b4f77bc5f8bf 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -65,6 +65,8 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
- if (!pdev->is_virtfn)
- return;
-
-+ pr_debug("%s: EEH: Setting up device %s.\n", __func__, pci_name(pdev));
-+
- pdn->device_id = pdev->device;
- pdn->vendor_id = pdev->vendor;
- pdn->class_code = pdev->class;
-@@ -251,6 +253,10 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
- int enable = 0;
- int ret;
-
-+ pr_debug("%s: probing %04x:%02x:%02x.%01x\n",
-+ __func__, pdn->phb->global_number, pdn->busno,
-+ PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
-+
- /* Retrieve OF node and eeh device */
- edev = pdn_to_eeh_dev(pdn);
- if (!edev || edev->pe)
-@@ -294,7 +300,12 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
-
- /* Enable EEH on the device */
- ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
-- if (!ret) {
-+ if (ret) {
-+ pr_debug("%s: EEH failed to enable on %02x:%02x.%01x PHB#%x-PE#%x (code %d)\n",
-+ __func__, pdn->busno, PCI_SLOT(pdn->devfn),
-+ PCI_FUNC(pdn->devfn), pe.phb->global_number,
-+ pe.addr, ret);
-+ } else {
- /* Retrieve PE address */
- edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
- pe.addr = edev->pe_config_addr;
-@@ -310,11 +321,6 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
- if (enable) {
- eeh_add_flag(EEH_ENABLED);
- eeh_add_to_parent_pe(edev);
--
-- pr_debug("%s: EEH enabled on %02x:%02x.%01x PHB#%x-PE#%x\n",
-- __func__, pdn->busno, PCI_SLOT(pdn->devfn),
-- PCI_FUNC(pdn->devfn), pe.phb->global_number,
-- pe.addr);
- } else if (pdn->parent && pdn_to_eeh_dev(pdn->parent) &&
- (pdn_to_eeh_dev(pdn->parent))->pe) {
- /* This device doesn't support EEH, but it may have an
-@@ -323,6 +329,11 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
- edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr;
- eeh_add_to_parent_pe(edev);
- }
-+ pr_debug("%s: EEH %s on %02x:%02x.%01x PHB#%x-PE#%x (code %d)\n",
-+ __func__, (enable ? "enabled" : "unsupported"),
-+ pdn->busno, PCI_SLOT(pdn->devfn),
-+ PCI_FUNC(pdn->devfn), pe.phb->global_number,
-+ pe.addr, ret);
- }
-
- /* Save memory bars */
---
-2.35.1
-
+++ /dev/null
-From a8a30219ba78b1abb92091102b632f8e9bbdbf03 Mon Sep 17 00:00:00 2001
-From: Frederic Barrat <fbarrat@linux.ibm.com>
-Date: Wed, 16 Oct 2019 18:28:33 +0200
-Subject: powerpc/powernv/eeh: Fix oops when probing cxl devices
-
-From: Frederic Barrat <fbarrat@linux.ibm.com>
-
-commit a8a30219ba78b1abb92091102b632f8e9bbdbf03 upstream.
-
-Recent cleanup in the way EEH support is added to a device causes a
-kernel oops when the cxl driver probes a device and creates virtual
-devices discovered on the FPGA:
-
- BUG: Kernel NULL pointer dereference at 0x000000a0
- Faulting instruction address: 0xc000000000048070
- Oops: Kernel access of bad area, sig: 7 [#1]
- ...
- NIP eeh_add_device_late.part.9+0x50/0x1e0
- LR eeh_add_device_late.part.9+0x3c/0x1e0
- Call Trace:
- _dev_info+0x5c/0x6c (unreliable)
- pnv_pcibios_bus_add_device+0x60/0xb0
- pcibios_bus_add_device+0x40/0x60
- pci_bus_add_device+0x30/0x100
- pci_bus_add_devices+0x64/0xd0
- cxl_pci_vphb_add+0xe0/0x130 [cxl]
- cxl_probe+0x504/0x5b0 [cxl]
- local_pci_probe+0x6c/0x110
- work_for_cpu_fn+0x38/0x60
-
-The root cause is that those cxl virtual devices don't have a
-representation in the device tree and therefore no associated pci_dn
-structure. In eeh_add_device_late(), pdn is NULL, so edev is NULL and
-we oops.
-
-We never had explicit support for EEH for those virtual devices.
-Instead, EEH events are reported to the (real) pci device and handled
-by the cxl driver. Which can then forward to the virtual devices and
-handle dependencies. The fact that we try adding EEH support for the
-virtual devices is new and a side-effect of the recent cleanup.
-
-This patch fixes it by skipping adding EEH support on powernv for
-devices which don't have a pci_dn structure.
-
-The cxl driver doesn't create virtual devices on pseries so this patch
-doesn't fix it there intentionally.
-
-Fixes: b905f8cdca77 ("powerpc/eeh: EEH for pSeries hot plug")
-Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
-Reviewed-by: Sam Bobroff <sbobroff@linux.ibm.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20191016162833.22509-1-fbarrat@linux.ibm.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/powerpc/platforms/powernv/eeh-powernv.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/powerpc/platforms/powernv/eeh-powernv.c
-+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
-@@ -47,7 +47,7 @@ void pnv_pcibios_bus_add_device(struct p
- {
- struct pci_dn *pdn = pci_get_pdn(pdev);
-
-- if (eeh_has_flag(EEH_FORCE_DISABLED))
-+ if (!pdn || eeh_has_flag(EEH_FORCE_DISABLED))
- return;
-
- pr_debug("%s: EEH: Setting up device %s.\n", __func__, pci_name(pdev));
+++ /dev/null
-From 9b93c0e853b02c24c8a300ca45ac2e5cf01e58ad Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 18 Nov 2022 09:07:43 -0600
-Subject: powerpc/pseries/eeh: use correct API for error log size
-
-From: Nathan Lynch <nathanl@linux.ibm.com>
-
-[ Upstream commit 9aafbfa5f57a4b75bafd3bed0191e8429c5fa618 ]
-
-rtas-error-log-max is not the name of an RTAS function, so rtas_token()
-is not the appropriate API for retrieving its value. We already have
-rtas_get_error_log_max() which returns a sensible value if the property
-is absent for any reason, so use that instead.
-
-Fixes: 8d633291b4fc ("powerpc/eeh: pseries platform EEH error log retrieval")
-Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
-[mpe: Drop no-longer possible error handling as noticed by ajd]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20221118150751.469393-6-nathanl@linux.ibm.com
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 11 +----------
- 1 file changed, 1 insertion(+), 10 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index f56248f19ef3..b7160120c0bb 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -946,16 +946,7 @@ static int __init eeh_pseries_init(void)
- }
-
- /* Initialize error log size */
-- eeh_error_buf_size = rtas_token("rtas-error-log-max");
-- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-- pr_info("%s: unknown EEH error log size\n",
-- __func__);
-- eeh_error_buf_size = 1024;
-- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-- pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-- eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-- }
-+ eeh_error_buf_size = rtas_get_error_log_max();
-
- /* Set EEH probe mode */
- eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
---
-2.35.1
-
+++ /dev/null
-From 61659a948f6a31e0e0ca4aacd1861ac75a5aebde Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 13 Jul 2020 09:39:33 -0500
-Subject: powerpc/pseries: PCIE PHB reset
-
-From: Wen Xiong <wenxiong@linux.vnet.ibm.com>
-
-[ Upstream commit 5a090f7c363fdc09b99222eae679506a58e7cc68 ]
-
-Several device drivers hit EEH(Extended Error handling) when
-triggering kdump on Pseries PowerVM. This patch implemented a reset of
-the PHBs in pci general code when triggering kdump. PHB reset stop all
-PCI transactions from normal kernel. We have tested the patch in
-several enviroments:
- - direct slot adapters
- - adapters under the switch
- - a VF adapter in PowerVM
- - a VF adapter/adapter in KVM guest.
-
-Signed-off-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
-[mpe: Fix broken whitespace, subject & SOB formatting]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/1594651173-32166-1-git-send-email-wenxiong@linux.vnet.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 232 ++++++++++++++-----
- 1 file changed, 169 insertions(+), 63 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 0fc93f7e167d..560d7401496c 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -37,6 +37,7 @@
- #include <linux/sched.h>
- #include <linux/seq_file.h>
- #include <linux/spinlock.h>
-+#include <linux/crash_dump.h>
-
- #include <asm/eeh.h>
- #include <asm/eeh_event.h>
-@@ -94,6 +95,152 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
- eeh_sysfs_add_device(pdev);
- }
-
-+
-+/**
-+ * pseries_eeh_get_config_addr - Retrieve config address
-+ *
-+ * Retrieve the assocated config address. Actually, there're 2 RTAS
-+ * function calls dedicated for the purpose. We need implement
-+ * it through the new function and then the old one. Besides,
-+ * you should make sure the config address is figured out from
-+ * FDT node before calling the function.
-+ *
-+ * It's notable that zero'ed return value means invalid PE config
-+ * address.
-+ */
-+static int pseries_eeh_get_config_addr(struct pci_controller *phb, int config_addr)
-+{
-+ int ret = 0;
-+ int rets[3];
-+
-+ if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
-+ /*
-+ * First of all, we need to make sure there has one PE
-+ * associated with the device. Otherwise, PE address is
-+ * meaningless.
-+ */
-+ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 1);
-+ if (ret || (rets[0] == 0))
-+ return 0;
-+
-+ /* Retrieve the associated PE config address */
-+ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 0);
-+ if (ret) {
-+ pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
-+ __func__, phb->global_number, config_addr);
-+ return 0;
-+ }
-+
-+ return rets[0];
-+ }
-+
-+ if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
-+ ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 0);
-+ if (ret) {
-+ pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
-+ __func__, phb->global_number, config_addr);
-+ return 0;
-+ }
-+
-+ return rets[0];
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * pseries_eeh_phb_reset - Reset the specified PHB
-+ * @phb: PCI controller
-+ * @config_adddr: the associated config address
-+ * @option: reset option
-+ *
-+ * Reset the specified PHB/PE
-+ */
-+static int pseries_eeh_phb_reset(struct pci_controller *phb, int config_addr, int option)
-+{
-+ int ret;
-+
-+ /* Reset PE through RTAS call */
-+ ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), option);
-+
-+ /* If fundamental-reset not supported, try hot-reset */
-+ if (option == EEH_RESET_FUNDAMENTAL &&
-+ ret == -8) {
-+ option = EEH_RESET_HOT;
-+ ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), option);
-+ }
-+
-+ /* We need reset hold or settlement delay */
-+ if (option == EEH_RESET_FUNDAMENTAL ||
-+ option == EEH_RESET_HOT)
-+ msleep(EEH_PE_RST_HOLD_TIME);
-+ else
-+ msleep(EEH_PE_RST_SETTLE_TIME);
-+
-+ return ret;
-+}
-+
-+/**
-+ * pseries_eeh_phb_configure_bridge - Configure PCI bridges in the indicated PE
-+ * @phb: PCI controller
-+ * @config_adddr: the associated config address
-+ *
-+ * The function will be called to reconfigure the bridges included
-+ * in the specified PE so that the mulfunctional PE would be recovered
-+ * again.
-+ */
-+static int pseries_eeh_phb_configure_bridge(struct pci_controller *phb, int config_addr)
-+{
-+ int ret;
-+ /* Waiting 0.2s maximum before skipping configuration */
-+ int max_wait = 200;
-+
-+ while (max_wait > 0) {
-+ ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid));
-+
-+ if (!ret)
-+ return ret;
-+ if (ret < 0)
-+ break;
-+
-+ /*
-+ * If RTAS returns a delay value that's above 100ms, cut it
-+ * down to 100ms in case firmware made a mistake. For more
-+ * on how these delay values work see rtas_busy_delay_time
-+ */
-+ if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
-+ ret <= RTAS_EXTENDED_DELAY_MAX)
-+ ret = RTAS_EXTENDED_DELAY_MIN+2;
-+
-+ max_wait -= rtas_busy_delay_time(ret);
-+
-+ if (max_wait < 0)
-+ break;
-+
-+ rtas_busy_delay(ret);
-+ }
-+
-+ pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
-+ __func__, phb->global_number, config_addr, ret);
-+ /* PAPR defines -3 as "Parameter Error" for this function: */
-+ if (ret == -3)
-+ return -EINVAL;
-+ else
-+ return -EIO;
-+}
-+
- /*
- * Buffer for reporting slot-error-detail rtas calls. Its here
- * in BSS, and not dynamically alloced, so that it ends up in
-@@ -110,6 +257,10 @@ static int eeh_error_buf_size;
- */
- static int pseries_eeh_init(void)
- {
-+ struct pci_controller *phb;
-+ struct pci_dn *pdn;
-+ int addr, config_addr;
-+
- /* figure out EEH RTAS function call tokens */
- ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
- ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-@@ -162,6 +313,22 @@ static int pseries_eeh_init(void)
- /* Set EEH machine dependent code */
- ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
-
-+ if (is_kdump_kernel() || reset_devices) {
-+ pr_info("Issue PHB reset ...\n");
-+ list_for_each_entry(phb, &hose_list, list_node) {
-+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-+ addr = (pdn->busno << 16) | (pdn->devfn << 8);
-+ config_addr = pseries_eeh_get_config_addr(phb, addr);
-+ /* invalid PE config addr */
-+ if (config_addr == 0)
-+ continue;
-+
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-+ pseries_eeh_phb_configure_bridge(phb, config_addr);
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -531,35 +698,13 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *state)
- static int pseries_eeh_reset(struct eeh_pe *pe, int option)
- {
- int config_addr;
-- int ret;
-
- /* Figure out PE address */
- config_addr = pe->config_addr;
- if (pe->addr)
- config_addr = pe->addr;
-
-- /* Reset PE through RTAS call */
-- ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid), option);
--
-- /* If fundamental-reset not supported, try hot-reset */
-- if (option == EEH_RESET_FUNDAMENTAL &&
-- ret == -8) {
-- option = EEH_RESET_HOT;
-- ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid), option);
-- }
--
-- /* We need reset hold or settlement delay */
-- if (option == EEH_RESET_FUNDAMENTAL ||
-- option == EEH_RESET_HOT)
-- msleep(EEH_PE_RST_HOLD_TIME);
-- else
-- msleep(EEH_PE_RST_SETTLE_TIME);
--
-- return ret;
-+ return pseries_eeh_phb_reset(pe->phb, config_addr, option);
- }
-
- /**
-@@ -661,56 +806,17 @@ static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, u
- * pseries_eeh_configure_bridge - Configure PCI bridges in the indicated PE
- * @pe: EEH PE
- *
-- * The function will be called to reconfigure the bridges included
-- * in the specified PE so that the mulfunctional PE would be recovered
-- * again.
- */
- static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
- {
- int config_addr;
-- int ret;
-- /* Waiting 0.2s maximum before skipping configuration */
-- int max_wait = 200;
-
- /* Figure out the PE address */
- config_addr = pe->config_addr;
- if (pe->addr)
- config_addr = pe->addr;
-
-- while (max_wait > 0) {
-- ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid));
--
-- if (!ret)
-- return ret;
-- if (ret < 0)
-- break;
--
-- /*
-- * If RTAS returns a delay value that's above 100ms, cut it
-- * down to 100ms in case firmware made a mistake. For more
-- * on how these delay values work see rtas_busy_delay_time
-- */
-- if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
-- ret <= RTAS_EXTENDED_DELAY_MAX)
-- ret = RTAS_EXTENDED_DELAY_MIN+2;
--
-- max_wait -= rtas_busy_delay_time(ret);
--
-- if (max_wait < 0)
-- break;
--
-- rtas_busy_delay(ret);
-- }
--
-- pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
-- __func__, pe->phb->global_number, pe->addr, ret);
-- /* PAPR defines -3 as "Parameter Error" for this function: */
-- if (ret == -3)
-- return -EINVAL;
-- else
-- return -EIO;
-+ return pseries_eeh_phb_configure_bridge(pe->phb, config_addr);
- }
-
- /**
---
-2.35.1
-
+++ /dev/null
-From dca24723685a88aa098119be7fec7df6cdb82e91 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 18 Sep 2020 19:30:44 +1000
-Subject: powerpc/pseries: Stop using eeh_ops->init()
-
-From: Oliver O'Halloran <oohall@gmail.com>
-
-[ Upstream commit 1f8fa0cd6a848ff072bffe0ee776554387128f60 ]
-
-Fold pseries_eeh_init() into eeh_pseries_init() rather than having
-eeh_init() call it via eeh_ops->init(). It's simpler and it'll let us
-delete eeh_ops.init.
-
-Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20200918093050.37344-3-oohall@gmail.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 155 +++++++++----------
- 1 file changed, 71 insertions(+), 84 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 560d7401496c..7a0b9aa09d10 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -250,88 +250,6 @@ static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
- static DEFINE_SPINLOCK(slot_errbuf_lock);
- static int eeh_error_buf_size;
-
--/**
-- * pseries_eeh_init - EEH platform dependent initialization
-- *
-- * EEH platform dependent initialization on pseries.
-- */
--static int pseries_eeh_init(void)
--{
-- struct pci_controller *phb;
-- struct pci_dn *pdn;
-- int addr, config_addr;
--
-- /* figure out EEH RTAS function call tokens */
-- ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
-- ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-- ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
-- ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-- ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-- ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
-- ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
-- ibm_configure_pe = rtas_token("ibm,configure-pe");
--
-- /*
-- * ibm,configure-pe and ibm,configure-bridge have the same semantics,
-- * however ibm,configure-pe can be faster. If we can't find
-- * ibm,configure-pe then fall back to using ibm,configure-bridge.
-- */
-- if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
-- ibm_configure_pe = rtas_token("ibm,configure-bridge");
--
-- /*
-- * Necessary sanity check. We needn't check "get-config-addr-info"
-- * and its variant since the old firmware probably support address
-- * of domain/bus/slot/function for EEH RTAS operations.
-- */
-- if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE ||
-- ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE ||
-- (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
-- ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
-- ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
-- ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
-- pr_info("EEH functionality not supported\n");
-- return -EINVAL;
-- }
--
-- /* Initialize error log lock and size */
-- spin_lock_init(&slot_errbuf_lock);
-- eeh_error_buf_size = rtas_token("rtas-error-log-max");
-- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-- pr_info("%s: unknown EEH error log size\n",
-- __func__);
-- eeh_error_buf_size = 1024;
-- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-- pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-- eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-- }
--
-- /* Set EEH probe mode */
-- eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
--
-- /* Set EEH machine dependent code */
-- ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
--
-- if (is_kdump_kernel() || reset_devices) {
-- pr_info("Issue PHB reset ...\n");
-- list_for_each_entry(phb, &hose_list, list_node) {
-- pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-- addr = (pdn->busno << 16) | (pdn->devfn << 8);
-- config_addr = pseries_eeh_get_config_addr(phb, addr);
-- /* invalid PE config addr */
-- if (config_addr == 0)
-- continue;
--
-- pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-- pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-- pseries_eeh_phb_configure_bridge(phb, config_addr);
-- }
-- }
--
-- return 0;
--}
--
- static int pseries_eeh_cap_start(struct pci_dn *pdn)
- {
- u32 status;
-@@ -964,7 +882,6 @@ static int pseries_notify_resume(struct pci_dn *pdn)
-
- static struct eeh_ops pseries_eeh_ops = {
- .name = "pseries",
-- .init = pseries_eeh_init,
- .probe = pseries_eeh_probe,
- .set_option = pseries_eeh_set_option,
- .get_pe_addr = pseries_eeh_get_pe_addr,
-@@ -991,7 +908,77 @@ static struct eeh_ops pseries_eeh_ops = {
- */
- static int __init eeh_pseries_init(void)
- {
-- int ret;
-+ struct pci_controller *phb;
-+ struct pci_dn *pdn;
-+ int ret, addr, config_addr;
-+
-+ /* figure out EEH RTAS function call tokens */
-+ ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
-+ ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-+ ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
-+ ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-+ ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-+ ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
-+ ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
-+ ibm_configure_pe = rtas_token("ibm,configure-pe");
-+
-+ /*
-+ * ibm,configure-pe and ibm,configure-bridge have the same semantics,
-+ * however ibm,configure-pe can be faster. If we can't find
-+ * ibm,configure-pe then fall back to using ibm,configure-bridge.
-+ */
-+ if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
-+ ibm_configure_pe = rtas_token("ibm,configure-bridge");
-+
-+ /*
-+ * Necessary sanity check. We needn't check "get-config-addr-info"
-+ * and its variant since the old firmware probably support address
-+ * of domain/bus/slot/function for EEH RTAS operations.
-+ */
-+ if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE ||
-+ ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE ||
-+ (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
-+ ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
-+ ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
-+ ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
-+ pr_info("EEH functionality not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Initialize error log lock and size */
-+ spin_lock_init(&slot_errbuf_lock);
-+ eeh_error_buf_size = rtas_token("rtas-error-log-max");
-+ if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-+ pr_info("%s: unknown EEH error log size\n",
-+ __func__);
-+ eeh_error_buf_size = 1024;
-+ } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-+ pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-+ __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-+ eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-+ }
-+
-+ /* Set EEH probe mode */
-+ eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
-+
-+ /* Set EEH machine dependent code */
-+ ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
-+
-+ if (is_kdump_kernel() || reset_devices) {
-+ pr_info("Issue PHB reset ...\n");
-+ list_for_each_entry(phb, &hose_list, list_node) {
-+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-+ addr = (pdn->busno << 16) | (pdn->devfn << 8);
-+ config_addr = pseries_eeh_get_config_addr(phb, addr);
-+ /* invalid PE config addr */
-+ if (config_addr == 0)
-+ continue;
-+
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-+ pseries_eeh_phb_configure_bridge(phb, config_addr);
-+ }
-+ }
-
- ret = eeh_ops_register(&pseries_eeh_ops);
- if (!ret)
---
-2.35.1
-
+++ /dev/null
-From eb8257a12192f43ffd41bd90932c39dade958042 Mon Sep 17 00:00:00 2001
-From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-Date: Mon, 20 Sep 2021 22:03:26 +0530
-Subject: pseries/eeh: Fix the kdump kernel crash during eeh_pseries_init
-
-From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-
-commit eb8257a12192f43ffd41bd90932c39dade958042 upstream.
-
-On pseries LPAR when an empty slot is assigned to partition OR in single
-LPAR mode, kdump kernel crashes during issuing PHB reset.
-
-In the kdump scenario, we traverse all PHBs and issue reset using the
-pe_config_addr of the first child device present under each PHB. However
-the code assumes that none of the PHB slots can be empty and uses
-list_first_entry() to get the first child device under the PHB. Since
-list_first_entry() expects the list to be non-empty, it returns an
-invalid pci_dn entry and ends up accessing NULL phb pointer under
-pci_dn->phb causing kdump kernel crash.
-
-This patch fixes the below kdump kernel crash by skipping empty slots:
-
- audit: initializing netlink subsys (disabled)
- thermal_sys: Registered thermal governor 'fair_share'
- thermal_sys: Registered thermal governor 'step_wise'
- cpuidle: using governor menu
- pstore: Registered nvram as persistent store backend
- Issue PHB reset ...
- audit: type=2000 audit(1631267818.000:1): state=initialized audit_enabled=0 res=1
- BUG: Kernel NULL pointer dereference on read at 0x00000268
- Faulting instruction address: 0xc000000008101fb0
- Oops: Kernel access of bad area, sig: 7 [#1]
- LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
- Modules linked in:
- CPU: 7 PID: 1 Comm: swapper/7 Not tainted 5.14.0 #1
- NIP: c000000008101fb0 LR: c000000009284ccc CTR: c000000008029d70
- REGS: c00000001161b840 TRAP: 0300 Not tainted (5.14.0)
- MSR: 8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 28000224 XER: 20040002
- CFAR: c000000008101f0c DAR: 0000000000000268 DSISR: 00080000 IRQMASK: 0
- ...
- NIP pseries_eeh_get_pe_config_addr+0x100/0x1b0
- LR __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
- Call Trace:
- 0xc00000001161bb80 (unreliable)
- __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
- do_one_initcall+0x60/0x2d0
- kernel_init_freeable+0x350/0x3f8
- kernel_init+0x3c/0x17c
- ret_from_kernel_thread+0x5c/0x64
-
-Fixes: 5a090f7c363fd ("powerpc/pseries: PCIE PHB reset")
-Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-[mpe: Tweak wording and trim oops]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/163215558252.413351.8600189949820258982.stgit@jupiter
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -957,6 +957,10 @@ static int __init eeh_pseries_init(void)
- if (is_kdump_kernel() || reset_devices) {
- pr_info("Issue PHB reset ...\n");
- list_for_each_entry(phb, &hose_list, list_node) {
-+ // Skip if the slot is empty
-+ if (list_empty(&PCI_DN(phb->dn)->child_list))
-+ continue;
-+
- pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
- addr = (pdn->busno << 16) | (pdn->devfn << 8);
- config_addr = pseries_eeh_get_config_addr(phb, addr);
selftests-powerpc-fix-resource-leaks.patch
remoteproc-qcom-rename-hexagon-v5-pas-driver.patch
remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch
-powerpc-eeh-improve-debug-messages-around-device-add.patch
-powerpc-eeh-eeh-for-pseries-hot-plug.patch
-powerpc-eeh-fix-pseries_eeh_configure_bridge.patch
-powerpc-pseries-pcie-phb-reset.patch
-powerpc-pseries-stop-using-eeh_ops-init.patch
-powerpc-eeh-drop-redundant-spinlock-initialization.patch
-powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch
rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch
nfsd-under-nfsv4.1-fix-double-svc_xprt_put-on-rpc_cr.patch
misdn-hfcsusb-don-t-call-dev_kfree_skb-kfree_skb-und.patch
efi-fix-null-deref-in-init-error-path.patch
revert-usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch
tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch
-pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch
alsa-hda-realtek-fix-inverted-bass-gpio-pin-on-acer-8951g.patch
alsa-hda-realtek-fixed-one-of-hp-alc671-platform-headset-mic-supported.patch
-powerpc-powernv-eeh-fix-oops-when-probing-cxl-devices.patch
serial-tegra-only-print-fifo-error-message-when-an-error-occurs.patch
+++ /dev/null
-From 86876db2705a1ebfcf17c0dcbc7ed2f6cd314552 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 May 2022 09:27:56 +0800
-Subject: powerpc/eeh: Drop redundant spinlock initialization
-
-From: Haowen Bai <baihaowen@meizu.com>
-
-[ Upstream commit 3def164a5cedad9117859dd4610cae2cc59cb6d2 ]
-
-slot_errbuf_lock has declared and initialized by DEFINE_SPINLOCK,
-so we don't need to spin_lock_init again, drop it.
-
-Signed-off-by: Haowen Bai <baihaowen@meizu.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/1652232476-9696-1-git-send-email-baihaowen@meizu.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 4232ba62b1c3..7e36c617282f 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -867,8 +867,7 @@ static int __init eeh_pseries_init(void)
- return -EINVAL;
- }
-
-- /* Initialize error log lock and size */
-- spin_lock_init(&slot_errbuf_lock);
-+ /* Initialize error log size */
- eeh_error_buf_size = rtas_token("rtas-error-log-max");
- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
- pr_info("%s: unknown EEH error log size\n",
---
-2.35.1
-
+++ /dev/null
-From c90dfe7b8aa57a67b77af290483d57eaa533aabc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Apr 2020 13:45:05 +1000
-Subject: powerpc/eeh: Fix pseries_eeh_configure_bridge()
-
-From: Sam Bobroff <sbobroff@linux.ibm.com>
-
-[ Upstream commit 6fa13640aea7bb0760846981aa2da4245307bd26 ]
-
-If a device is hot unplgged during EEH recovery, it's possible for the
-RTAS call to ibm,configure-pe in pseries_eeh_configure() to return
-parameter error (-3), however negative return values are not checked
-for and this leads to an infinite loop.
-
-Fix this by correctly bailing out on negative values.
-
-Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Reviewed-by: Nathan Lynch <nathanl@linux.ibm.com>
-Link: https://lore.kernel.org/r/1b0a6010a647dc915816e44845b64d72066676a7.1588045502.git.sbobroff@linux.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 893ba3f562c4..04c1ed79bc6e 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -607,6 +607,8 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
-
- if (!ret)
- return ret;
-+ if (ret < 0)
-+ break;
-
- /*
- * If RTAS returns a delay value that's above 100ms, cut it
-@@ -627,7 +629,11 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
-
- pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
- __func__, pe->phb->global_number, pe->addr, ret);
-- return ret;
-+ /* PAPR defines -3 as "Parameter Error" for this function: */
-+ if (ret == -3)
-+ return -EINVAL;
-+ else
-+ return -EIO;
- }
-
- /**
---
-2.35.1
-
+++ /dev/null
-From f31586566c1f971dc3fd14a3713f5681566430b6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 18 Nov 2022 09:07:43 -0600
-Subject: powerpc/pseries/eeh: use correct API for error log size
-
-From: Nathan Lynch <nathanl@linux.ibm.com>
-
-[ Upstream commit 9aafbfa5f57a4b75bafd3bed0191e8429c5fa618 ]
-
-rtas-error-log-max is not the name of an RTAS function, so rtas_token()
-is not the appropriate API for retrieving its value. We already have
-rtas_get_error_log_max() which returns a sensible value if the property
-is absent for any reason, so use that instead.
-
-Fixes: 8d633291b4fc ("powerpc/eeh: pseries platform EEH error log retrieval")
-Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
-[mpe: Drop no-longer possible error handling as noticed by ajd]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20221118150751.469393-6-nathanl@linux.ibm.com
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 11 +----------
- 1 file changed, 1 insertion(+), 10 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 7e36c617282f..33c1dd7ee432 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -868,16 +868,7 @@ static int __init eeh_pseries_init(void)
- }
-
- /* Initialize error log size */
-- eeh_error_buf_size = rtas_token("rtas-error-log-max");
-- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-- pr_info("%s: unknown EEH error log size\n",
-- __func__);
-- eeh_error_buf_size = 1024;
-- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-- pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-- eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-- }
-+ eeh_error_buf_size = rtas_get_error_log_max();
-
- /* Set EEH probe mode */
- eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
---
-2.35.1
-
+++ /dev/null
-From aa9036f1f3c1396968eeb5776efe0740e69dd61a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 13 Jul 2020 09:39:33 -0500
-Subject: powerpc/pseries: PCIE PHB reset
-
-From: Wen Xiong <wenxiong@linux.vnet.ibm.com>
-
-[ Upstream commit 5a090f7c363fdc09b99222eae679506a58e7cc68 ]
-
-Several device drivers hit EEH(Extended Error handling) when
-triggering kdump on Pseries PowerVM. This patch implemented a reset of
-the PHBs in pci general code when triggering kdump. PHB reset stop all
-PCI transactions from normal kernel. We have tested the patch in
-several enviroments:
- - direct slot adapters
- - adapters under the switch
- - a VF adapter in PowerVM
- - a VF adapter/adapter in KVM guest.
-
-Signed-off-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
-[mpe: Fix broken whitespace, subject & SOB formatting]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/1594651173-32166-1-git-send-email-wenxiong@linux.vnet.ibm.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 232 ++++++++++++++-----
- 1 file changed, 169 insertions(+), 63 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index 04c1ed79bc6e..bb34ce56312a 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -24,6 +24,7 @@
- #include <linux/sched.h>
- #include <linux/seq_file.h>
- #include <linux/spinlock.h>
-+#include <linux/crash_dump.h>
-
- #include <asm/eeh.h>
- #include <asm/eeh_event.h>
-@@ -81,6 +82,152 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
- eeh_sysfs_add_device(pdev);
- }
-
-+
-+/**
-+ * pseries_eeh_get_config_addr - Retrieve config address
-+ *
-+ * Retrieve the assocated config address. Actually, there're 2 RTAS
-+ * function calls dedicated for the purpose. We need implement
-+ * it through the new function and then the old one. Besides,
-+ * you should make sure the config address is figured out from
-+ * FDT node before calling the function.
-+ *
-+ * It's notable that zero'ed return value means invalid PE config
-+ * address.
-+ */
-+static int pseries_eeh_get_config_addr(struct pci_controller *phb, int config_addr)
-+{
-+ int ret = 0;
-+ int rets[3];
-+
-+ if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
-+ /*
-+ * First of all, we need to make sure there has one PE
-+ * associated with the device. Otherwise, PE address is
-+ * meaningless.
-+ */
-+ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 1);
-+ if (ret || (rets[0] == 0))
-+ return 0;
-+
-+ /* Retrieve the associated PE config address */
-+ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 0);
-+ if (ret) {
-+ pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
-+ __func__, phb->global_number, config_addr);
-+ return 0;
-+ }
-+
-+ return rets[0];
-+ }
-+
-+ if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
-+ ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), 0);
-+ if (ret) {
-+ pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
-+ __func__, phb->global_number, config_addr);
-+ return 0;
-+ }
-+
-+ return rets[0];
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * pseries_eeh_phb_reset - Reset the specified PHB
-+ * @phb: PCI controller
-+ * @config_adddr: the associated config address
-+ * @option: reset option
-+ *
-+ * Reset the specified PHB/PE
-+ */
-+static int pseries_eeh_phb_reset(struct pci_controller *phb, int config_addr, int option)
-+{
-+ int ret;
-+
-+ /* Reset PE through RTAS call */
-+ ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), option);
-+
-+ /* If fundamental-reset not supported, try hot-reset */
-+ if (option == EEH_RESET_FUNDAMENTAL &&
-+ ret == -8) {
-+ option = EEH_RESET_HOT;
-+ ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid), option);
-+ }
-+
-+ /* We need reset hold or settlement delay */
-+ if (option == EEH_RESET_FUNDAMENTAL ||
-+ option == EEH_RESET_HOT)
-+ msleep(EEH_PE_RST_HOLD_TIME);
-+ else
-+ msleep(EEH_PE_RST_SETTLE_TIME);
-+
-+ return ret;
-+}
-+
-+/**
-+ * pseries_eeh_phb_configure_bridge - Configure PCI bridges in the indicated PE
-+ * @phb: PCI controller
-+ * @config_adddr: the associated config address
-+ *
-+ * The function will be called to reconfigure the bridges included
-+ * in the specified PE so that the mulfunctional PE would be recovered
-+ * again.
-+ */
-+static int pseries_eeh_phb_configure_bridge(struct pci_controller *phb, int config_addr)
-+{
-+ int ret;
-+ /* Waiting 0.2s maximum before skipping configuration */
-+ int max_wait = 200;
-+
-+ while (max_wait > 0) {
-+ ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-+ config_addr, BUID_HI(phb->buid),
-+ BUID_LO(phb->buid));
-+
-+ if (!ret)
-+ return ret;
-+ if (ret < 0)
-+ break;
-+
-+ /*
-+ * If RTAS returns a delay value that's above 100ms, cut it
-+ * down to 100ms in case firmware made a mistake. For more
-+ * on how these delay values work see rtas_busy_delay_time
-+ */
-+ if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
-+ ret <= RTAS_EXTENDED_DELAY_MAX)
-+ ret = RTAS_EXTENDED_DELAY_MIN+2;
-+
-+ max_wait -= rtas_busy_delay_time(ret);
-+
-+ if (max_wait < 0)
-+ break;
-+
-+ rtas_busy_delay(ret);
-+ }
-+
-+ pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
-+ __func__, phb->global_number, config_addr, ret);
-+ /* PAPR defines -3 as "Parameter Error" for this function: */
-+ if (ret == -3)
-+ return -EINVAL;
-+ else
-+ return -EIO;
-+}
-+
- /*
- * Buffer for reporting slot-error-detail rtas calls. Its here
- * in BSS, and not dynamically alloced, so that it ends up in
-@@ -97,6 +244,10 @@ static int eeh_error_buf_size;
- */
- static int pseries_eeh_init(void)
- {
-+ struct pci_controller *phb;
-+ struct pci_dn *pdn;
-+ int addr, config_addr;
-+
- /* figure out EEH RTAS function call tokens */
- ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
- ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-@@ -149,6 +300,22 @@ static int pseries_eeh_init(void)
- /* Set EEH machine dependent code */
- ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
-
-+ if (is_kdump_kernel() || reset_devices) {
-+ pr_info("Issue PHB reset ...\n");
-+ list_for_each_entry(phb, &hose_list, list_node) {
-+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-+ addr = (pdn->busno << 16) | (pdn->devfn << 8);
-+ config_addr = pseries_eeh_get_config_addr(phb, addr);
-+ /* invalid PE config addr */
-+ if (config_addr == 0)
-+ continue;
-+
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-+ pseries_eeh_phb_configure_bridge(phb, config_addr);
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -512,35 +679,13 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay)
- static int pseries_eeh_reset(struct eeh_pe *pe, int option)
- {
- int config_addr;
-- int ret;
-
- /* Figure out PE address */
- config_addr = pe->config_addr;
- if (pe->addr)
- config_addr = pe->addr;
-
-- /* Reset PE through RTAS call */
-- ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid), option);
--
-- /* If fundamental-reset not supported, try hot-reset */
-- if (option == EEH_RESET_FUNDAMENTAL &&
-- ret == -8) {
-- option = EEH_RESET_HOT;
-- ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid), option);
-- }
--
-- /* We need reset hold or settlement delay */
-- if (option == EEH_RESET_FUNDAMENTAL ||
-- option == EEH_RESET_HOT)
-- msleep(EEH_PE_RST_HOLD_TIME);
-- else
-- msleep(EEH_PE_RST_SETTLE_TIME);
--
-- return ret;
-+ return pseries_eeh_phb_reset(pe->phb, config_addr, option);
- }
-
- /**
-@@ -584,56 +729,17 @@ static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, u
- * pseries_eeh_configure_bridge - Configure PCI bridges in the indicated PE
- * @pe: EEH PE
- *
-- * The function will be called to reconfigure the bridges included
-- * in the specified PE so that the mulfunctional PE would be recovered
-- * again.
- */
- static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
- {
- int config_addr;
-- int ret;
-- /* Waiting 0.2s maximum before skipping configuration */
-- int max_wait = 200;
-
- /* Figure out the PE address */
- config_addr = pe->config_addr;
- if (pe->addr)
- config_addr = pe->addr;
-
-- while (max_wait > 0) {
-- ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid));
--
-- if (!ret)
-- return ret;
-- if (ret < 0)
-- break;
--
-- /*
-- * If RTAS returns a delay value that's above 100ms, cut it
-- * down to 100ms in case firmware made a mistake. For more
-- * on how these delay values work see rtas_busy_delay_time
-- */
-- if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
-- ret <= RTAS_EXTENDED_DELAY_MAX)
-- ret = RTAS_EXTENDED_DELAY_MIN+2;
--
-- max_wait -= rtas_busy_delay_time(ret);
--
-- if (max_wait < 0)
-- break;
--
-- rtas_busy_delay(ret);
-- }
--
-- pr_warn("%s: Unable to configure bridge PHB#%x-PE#%x (%d)\n",
-- __func__, pe->phb->global_number, pe->addr, ret);
-- /* PAPR defines -3 as "Parameter Error" for this function: */
-- if (ret == -3)
-- return -EINVAL;
-- else
-- return -EIO;
-+ return pseries_eeh_phb_configure_bridge(pe->phb, config_addr);
- }
-
- /**
---
-2.35.1
-
+++ /dev/null
-From 9d075ba78a32fa2907c5e9875ac1f3c30f72b4e9 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 18 Sep 2020 19:30:44 +1000
-Subject: powerpc/pseries: Stop using eeh_ops->init()
-
-From: Oliver O'Halloran <oohall@gmail.com>
-
-[ Upstream commit 1f8fa0cd6a848ff072bffe0ee776554387128f60 ]
-
-Fold pseries_eeh_init() into eeh_pseries_init() rather than having
-eeh_init() call it via eeh_ops->init(). It's simpler and it'll let us
-delete eeh_ops.init.
-
-Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/20200918093050.37344-3-oohall@gmail.com
-Stable-dep-of: 9aafbfa5f57a ("powerpc/pseries/eeh: use correct API for error log size")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 155 +++++++++----------
- 1 file changed, 71 insertions(+), 84 deletions(-)
-
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index bb34ce56312a..4232ba62b1c3 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -237,88 +237,6 @@ static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
- static DEFINE_SPINLOCK(slot_errbuf_lock);
- static int eeh_error_buf_size;
-
--/**
-- * pseries_eeh_init - EEH platform dependent initialization
-- *
-- * EEH platform dependent initialization on pseries.
-- */
--static int pseries_eeh_init(void)
--{
-- struct pci_controller *phb;
-- struct pci_dn *pdn;
-- int addr, config_addr;
--
-- /* figure out EEH RTAS function call tokens */
-- ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
-- ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-- ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
-- ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-- ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-- ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
-- ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
-- ibm_configure_pe = rtas_token("ibm,configure-pe");
--
-- /*
-- * ibm,configure-pe and ibm,configure-bridge have the same semantics,
-- * however ibm,configure-pe can be faster. If we can't find
-- * ibm,configure-pe then fall back to using ibm,configure-bridge.
-- */
-- if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
-- ibm_configure_pe = rtas_token("ibm,configure-bridge");
--
-- /*
-- * Necessary sanity check. We needn't check "get-config-addr-info"
-- * and its variant since the old firmware probably support address
-- * of domain/bus/slot/function for EEH RTAS operations.
-- */
-- if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE ||
-- ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE ||
-- (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
-- ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
-- ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
-- ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
-- pr_info("EEH functionality not supported\n");
-- return -EINVAL;
-- }
--
-- /* Initialize error log lock and size */
-- spin_lock_init(&slot_errbuf_lock);
-- eeh_error_buf_size = rtas_token("rtas-error-log-max");
-- if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-- pr_info("%s: unknown EEH error log size\n",
-- __func__);
-- eeh_error_buf_size = 1024;
-- } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-- pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-- __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-- eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-- }
--
-- /* Set EEH probe mode */
-- eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
--
-- /* Set EEH machine dependent code */
-- ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
--
-- if (is_kdump_kernel() || reset_devices) {
-- pr_info("Issue PHB reset ...\n");
-- list_for_each_entry(phb, &hose_list, list_node) {
-- pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-- addr = (pdn->busno << 16) | (pdn->devfn << 8);
-- config_addr = pseries_eeh_get_config_addr(phb, addr);
-- /* invalid PE config addr */
-- if (config_addr == 0)
-- continue;
--
-- pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-- pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-- pseries_eeh_phb_configure_bridge(phb, config_addr);
-- }
-- }
--
-- return 0;
--}
--
- static int pseries_eeh_cap_start(struct pci_dn *pdn)
- {
- u32 status;
-@@ -887,7 +805,6 @@ static int pseries_notify_resume(struct pci_dn *pdn)
-
- static struct eeh_ops pseries_eeh_ops = {
- .name = "pseries",
-- .init = pseries_eeh_init,
- .probe = pseries_eeh_probe,
- .set_option = pseries_eeh_set_option,
- .get_pe_addr = pseries_eeh_get_pe_addr,
-@@ -913,7 +830,77 @@ static struct eeh_ops pseries_eeh_ops = {
- */
- static int __init eeh_pseries_init(void)
- {
-- int ret;
-+ struct pci_controller *phb;
-+ struct pci_dn *pdn;
-+ int ret, addr, config_addr;
-+
-+ /* figure out EEH RTAS function call tokens */
-+ ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
-+ ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
-+ ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
-+ ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-+ ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
-+ ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
-+ ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
-+ ibm_configure_pe = rtas_token("ibm,configure-pe");
-+
-+ /*
-+ * ibm,configure-pe and ibm,configure-bridge have the same semantics,
-+ * however ibm,configure-pe can be faster. If we can't find
-+ * ibm,configure-pe then fall back to using ibm,configure-bridge.
-+ */
-+ if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
-+ ibm_configure_pe = rtas_token("ibm,configure-bridge");
-+
-+ /*
-+ * Necessary sanity check. We needn't check "get-config-addr-info"
-+ * and its variant since the old firmware probably support address
-+ * of domain/bus/slot/function for EEH RTAS operations.
-+ */
-+ if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE ||
-+ ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE ||
-+ (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
-+ ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
-+ ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
-+ ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
-+ pr_info("EEH functionality not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Initialize error log lock and size */
-+ spin_lock_init(&slot_errbuf_lock);
-+ eeh_error_buf_size = rtas_token("rtas-error-log-max");
-+ if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
-+ pr_info("%s: unknown EEH error log size\n",
-+ __func__);
-+ eeh_error_buf_size = 1024;
-+ } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
-+ pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
-+ __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
-+ eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
-+ }
-+
-+ /* Set EEH probe mode */
-+ eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
-+
-+ /* Set EEH machine dependent code */
-+ ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device;
-+
-+ if (is_kdump_kernel() || reset_devices) {
-+ pr_info("Issue PHB reset ...\n");
-+ list_for_each_entry(phb, &hose_list, list_node) {
-+ pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
-+ addr = (pdn->busno << 16) | (pdn->devfn << 8);
-+ config_addr = pseries_eeh_get_config_addr(phb, addr);
-+ /* invalid PE config addr */
-+ if (config_addr == 0)
-+ continue;
-+
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);
-+ pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE);
-+ pseries_eeh_phb_configure_bridge(phb, config_addr);
-+ }
-+ }
-
- ret = eeh_ops_register(&pseries_eeh_ops);
- if (!ret)
---
-2.35.1
-
+++ /dev/null
-From eb8257a12192f43ffd41bd90932c39dade958042 Mon Sep 17 00:00:00 2001
-From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-Date: Mon, 20 Sep 2021 22:03:26 +0530
-Subject: pseries/eeh: Fix the kdump kernel crash during eeh_pseries_init
-
-From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-
-commit eb8257a12192f43ffd41bd90932c39dade958042 upstream.
-
-On pseries LPAR when an empty slot is assigned to partition OR in single
-LPAR mode, kdump kernel crashes during issuing PHB reset.
-
-In the kdump scenario, we traverse all PHBs and issue reset using the
-pe_config_addr of the first child device present under each PHB. However
-the code assumes that none of the PHB slots can be empty and uses
-list_first_entry() to get the first child device under the PHB. Since
-list_first_entry() expects the list to be non-empty, it returns an
-invalid pci_dn entry and ends up accessing NULL phb pointer under
-pci_dn->phb causing kdump kernel crash.
-
-This patch fixes the below kdump kernel crash by skipping empty slots:
-
- audit: initializing netlink subsys (disabled)
- thermal_sys: Registered thermal governor 'fair_share'
- thermal_sys: Registered thermal governor 'step_wise'
- cpuidle: using governor menu
- pstore: Registered nvram as persistent store backend
- Issue PHB reset ...
- audit: type=2000 audit(1631267818.000:1): state=initialized audit_enabled=0 res=1
- BUG: Kernel NULL pointer dereference on read at 0x00000268
- Faulting instruction address: 0xc000000008101fb0
- Oops: Kernel access of bad area, sig: 7 [#1]
- LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
- Modules linked in:
- CPU: 7 PID: 1 Comm: swapper/7 Not tainted 5.14.0 #1
- NIP: c000000008101fb0 LR: c000000009284ccc CTR: c000000008029d70
- REGS: c00000001161b840 TRAP: 0300 Not tainted (5.14.0)
- MSR: 8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 28000224 XER: 20040002
- CFAR: c000000008101f0c DAR: 0000000000000268 DSISR: 00080000 IRQMASK: 0
- ...
- NIP pseries_eeh_get_pe_config_addr+0x100/0x1b0
- LR __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
- Call Trace:
- 0xc00000001161bb80 (unreliable)
- __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
- do_one_initcall+0x60/0x2d0
- kernel_init_freeable+0x350/0x3f8
- kernel_init+0x3c/0x17c
- ret_from_kernel_thread+0x5c/0x64
-
-Fixes: 5a090f7c363fd ("powerpc/pseries: PCIE PHB reset")
-Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
-[mpe: Tweak wording and trim oops]
-Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-Link: https://lore.kernel.org/r/163215558252.413351.8600189949820258982.stgit@jupiter
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/powerpc/platforms/pseries/eeh_pseries.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -879,6 +879,10 @@ static int __init eeh_pseries_init(void)
- if (is_kdump_kernel() || reset_devices) {
- pr_info("Issue PHB reset ...\n");
- list_for_each_entry(phb, &hose_list, list_node) {
-+ // Skip if the slot is empty
-+ if (list_empty(&PCI_DN(phb->dn)->child_list))
-+ continue;
-+
- pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
- addr = (pdn->busno << 16) | (pdn->devfn << 8);
- config_addr = pseries_eeh_get_config_addr(phb, addr);
pwm-sifive-call-pwm_sifive_update_clock-while-mutex-.patch
remoteproc-sysmon-fix-memory-leak-in-qcom_add_sysmon.patch
remoteproc-qcom_q6v5_pas-fix-missing-of_node_put-in-.patch
-powerpc-eeh-fix-pseries_eeh_configure_bridge.patch
-powerpc-pseries-pcie-phb-reset.patch
-powerpc-pseries-stop-using-eeh_ops-init.patch
-powerpc-eeh-drop-redundant-spinlock-initialization.patch
-powerpc-pseries-eeh-use-correct-api-for-error-log-si.patch
rtc-st-lpc-add-missing-clk_disable_unprepare-in-st_r.patch
rtc-pic32-move-devm_rtc_allocate_device-earlier-in-p.patch
nfsd-define-the-file-access-mode-enum-for-tracing.patch
tipc-fix-use-after-free-in-tipc_disc_rcv.patch
tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch
tipc-add-a-missing-case-of-tipc_direct_msg-type.patch
-pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch
ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch
tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch