diff mbox

[2/3] powerpc/eeh: Restore config from edev in eeh_pe_reset_and_recover()

Message ID 1461239595-5627-2-git-send-email-gwshan@linux.vnet.ibm.com (mailing list archive)
State Superseded
Headers show

Commit Message

Gavin Shan April 21, 2016, 11:53 a.m. UTC
The function eeh_pe_reset_and_recover() is used to recover EEH
error when the passthrou device are transferred to guest and
backwords. The content in the device's config space will be lost
on PE reset issued in the middle of the recovery. The function
saves/restores it before/after the reset. However, config access
to some adapters like Broadcom BCM5719 at this point will causes
fended PHB. The config space is always blocked and we save 0xFF's
that are restored at late point. The memory BARs are totally
corrupted, causing another EEH error upon access to one of the
memory BARs.

This restores the config space from the content saved to the
EEH device when it's populated, to resolve above issue.

Fixes: 5cfb20b9 ("powerpc/eeh: Emulate EEH recovery for VFIO devices")
Cc: stable@vger.kernel.org #v3.18+
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/eeh_driver.c | 39 ++-------------------------------------
 1 file changed, 2 insertions(+), 37 deletions(-)

Comments

Russell Currey April 22, 2016, 6:37 a.m. UTC | #1
On Thu, 2016-04-21 at 21:53 +1000, Gavin Shan wrote:
> The function eeh_pe_reset_and_recover() is used to recover EEH
> error when the passthrou device are transferred to guest and
> backwords. The content in the device's config space will be lost

Spelling, as before :)

> on PE reset issued in the middle of the recovery. The function
> saves/restores it before/after the reset. However, config access
> to some adapters like Broadcom BCM5719 at this point will causes
> fended PHB. The config space is always blocked and we save 0xFF's

"fended" should be "fenced"

> that are restored at late point. The memory BARs are totally
> corrupted, causing another EEH error upon access to one of the
> memory BARs.
> 
> This restores the config space from the content saved to the
> EEH device when it's populated, to resolve above issue.
> 
> Fixes: 5cfb20b9 ("powerpc/eeh: Emulate EEH recovery for VFIO devices")
> Cc: stable@vger.kernel.org #v3.18+
> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
> ---

Reviewed-by: Russell Currey <ruscur@russell.cc>
Gavin Shan April 22, 2016, 1:17 p.m. UTC | #2
On Fri, Apr 22, 2016 at 04:37:52PM +1000, Russell Currey wrote:
>On Thu, 2016-04-21 at 21:53 +1000, Gavin Shan wrote:
>> The function eeh_pe_reset_and_recover() is used to recover EEH
>> error when the passthrou device are transferred to guest and
>> backwords. The content in the device's config space will be lost
>
>Spelling, as before :)
>
>> on PE reset issued in the middle of the recovery. The function
>> saves/restores it before/after the reset. However, config access
>> to some adapters like Broadcom BCM5719 at this point will causes
>> fended PHB. The config space is always blocked and we save 0xFF's
>
>"fended" should be "fenced"
>

Thanks, Russell. I'll fix it in next revision ;-)

>> that are restored at late point. The memory BARs are totally
>> corrupted, causing another EEH error upon access to one of the
>> memory BARs.
>> 
>> This restores the config space from the content saved to the
>> EEH device when it's populated, to resolve above issue.
>> 
>> Fixes: 5cfb20b9 ("powerpc/eeh: Emulate EEH recovery for VFIO devices")
>> Cc: stable@vger.kernel.org #v3.18+
>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>> ---
>
>Reviewed-by: Russell Currey <ruscur@russell.cc>
>
diff mbox

Patch

diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 1c7d703..ec6e889 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -163,22 +163,6 @@  static bool eeh_dev_removed(struct eeh_dev *edev)
 	return false;
 }
 
-static void *eeh_dev_save_state(void *data, void *userdata)
-{
-	struct eeh_dev *edev = data;
-	struct pci_dev *pdev;
-
-	if (!edev)
-		return NULL;
-
-	pdev = eeh_dev_to_pci_dev(edev);
-	if (!pdev)
-		return NULL;
-
-	pci_save_state(pdev);
-	return NULL;
-}
-
 /**
  * eeh_report_error - Report pci error to each device driver
  * @data: eeh device
@@ -304,22 +288,6 @@  static void *eeh_report_reset(void *data, void *userdata)
 	return NULL;
 }
 
-static void *eeh_dev_restore_state(void *data, void *userdata)
-{
-	struct eeh_dev *edev = data;
-	struct pci_dev *pdev;
-
-	if (!edev)
-		return NULL;
-
-	pdev = eeh_dev_to_pci_dev(edev);
-	if (!pdev)
-		return NULL;
-
-	pci_restore_state(pdev);
-	return NULL;
-}
-
 /**
  * eeh_report_resume - Tell device to resume normal operations
  * @data: eeh device
@@ -561,9 +529,6 @@  int eeh_pe_reset_and_recover(struct eeh_pe *pe)
 	/* Put the PE into recovery mode */
 	eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
 
-	/* Save states */
-	eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL);
-
 	/* Issue reset */
 	ret = eeh_reset_pe(pe);
 	if (ret) {
@@ -578,8 +543,8 @@  int eeh_pe_reset_and_recover(struct eeh_pe *pe)
 		return ret;
 	}
 
-	/* Restore device state */
-	eeh_pe_dev_traverse(pe, eeh_dev_restore_state, NULL);
+	/* Restore device's config space */
+	eeh_pe_restore_bars(pe);
 
 	/* Clear recovery mode */
 	eeh_pe_state_clear(pe, EEH_PE_RECOVERING);