From patchwork Fri Feb 13 04:54:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 439389 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9A14E140218 for ; Fri, 13 Feb 2015 15:56:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751477AbbBME4H (ORCPT ); Thu, 12 Feb 2015 23:56:07 -0500 Received: from e23smtp07.au.ibm.com ([202.81.31.140]:52165 "EHLO e23smtp07.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751440AbbBME4F (ORCPT ); Thu, 12 Feb 2015 23:56:05 -0500 Received: from /spool/local by e23smtp07.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 13 Feb 2015 14:56:03 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp07.au.ibm.com (202.81.31.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 13 Feb 2015 14:56:00 +1000 Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id 1FF5D2BB0051 for ; Fri, 13 Feb 2015 15:56:00 +1100 (EST) Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1D4tp9t29753560 for ; Fri, 13 Feb 2015 15:56:00 +1100 Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1D4tPq4013588 for ; Fri, 13 Feb 2015 15:55:26 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1D4tPnM013092; Fri, 13 Feb 2015 15:55:25 +1100 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.253.15]) by ozlabs.au.ibm.com (Postfix) with ESMTP id B4255A03BC; Fri, 13 Feb 2015 15:55:02 +1100 (AEDT) Received: from shangw (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 721FF16A9BC; Fri, 13 Feb 2015 15:55:01 +1100 (AEDT) Received: by shangw (Postfix, from userid 1000) id 262423E0735; Fri, 13 Feb 2015 15:55:01 +1100 (EST) From: Gavin Shan To: linux-pci@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, bhelgaas@google.com, cascardo@linux.vnet.ibm.com, Gavin Shan Subject: [PATCH 4/4] powerpc/powernv: Register PCI dev specific reset handlers Date: Fri, 13 Feb 2015 15:54:59 +1100 Message-Id: <1423803299-22356-5-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1423803299-22356-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1423803299-22356-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15021304-0025-0000-0000-0000010B5A77 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Currently, PCI VFIO infrastructure depends on pci_reset_function() to ensure the PCI device in clean state when passing to guest, or being returned back to host. However, the function doesn't work (or well) on some PCI devices, which potentially brings pending traffic over the boundary between host/guest and usually causes memory corruption. The patch registers PCI device specific reset handlers for those PCI devices, pci_reset_function() doesn't work or not well, to translate the request to EEH PE reset if possible. Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/pci.c | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index e69142f..c68d508 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -727,6 +727,64 @@ static void pnv_pci_dma_fallback_setup(struct pci_controller *hose, set_iommu_table_base_and_group(&pdev->dev, pdn->iommu_table); } +/* + * VFIO infrastructure depends on pci_reset_function() to do + * reset on the PCI devices when their owership is changed to + * ensure consistent clean state on those devices when someone + * grabs them. However, pci_reset_function() doesn't work for + * some deivces that require EEH PE reset. + */ +static int pnv_pci_dev_specific_reset(struct pci_dev *pdev, int probe) +{ + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); + struct eeh_pe *pe = edev ? edev->pe : NULL; + + if (!pe) + return -ENOTTY; + + if (probe) + return 0; + + pci_set_pcie_reset_state(pdev, pcie_hot_reset); + pci_set_pcie_reset_state(pdev, pcie_deassert_reset); + return 0; +} + +static int pnv_pci_root_bridge_prepare(struct pci_host_bridge *bridge) +{ + static bool pnv_pci_reset_registered = false; + int ret = 0; + + if (pnv_pci_reset_registered) + return 0; + + pnv_pci_reset_registered = true; + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_IBM, + PCI_ANY_ID, + pnv_pci_dev_specific_reset); + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_BROADCOM, + PCI_DEVICE_ID_NX2_57800, + pnv_pci_dev_specific_reset); + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_BROADCOM, + PCI_DEVICE_ID_NX2_57840, + pnv_pci_dev_specific_reset); + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_BROADCOM, + PCI_DEVICE_ID_NX2_57810, + pnv_pci_dev_specific_reset); + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_MELLANOX, + PCI_ANY_ID, + pnv_pci_dev_specific_reset); + ret += pci_dev_add_specific_reset(PCI_VENDOR_ID_TI, + PCI_ANY_ID, + pnv_pci_dev_specific_reset); + if (ret) + pr_warn("%s: Failure adding PCI specific reset handlers\n", + __func__); + + /* Don't return error to keep PCI core going */ + return 0; +} + static void pnv_pci_dma_dev_setup(struct pci_dev *pdev) { struct pci_controller *hose = pci_bus_to_host(pdev->bus); @@ -820,6 +878,9 @@ void __init pnv_pci_init(void) /* Setup the linkage between OF nodes and PHBs */ pci_devs_phb_init(); + /* Setup root bridge */ + ppc_md.pcibios_root_bridge_prepare = pnv_pci_root_bridge_prepare; + /* Configure IOMMU DMA hooks */ ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup; ppc_md.tce_build = pnv_tce_build_vm;