From patchwork Tue Jul 21 16:25:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jarod Wilson X-Patchwork-Id: 6837111 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 24770C05AC for ; Tue, 21 Jul 2015 16:26:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4FE7E206CE for ; Tue, 21 Jul 2015 16:26:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5F3D3206CB for ; Tue, 21 Jul 2015 16:26:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933193AbbGUQZw (ORCPT ); Tue, 21 Jul 2015 12:25:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52502 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933056AbbGUQZt (ORCPT ); Tue, 21 Jul 2015 12:25:49 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id B9070BF9E6; Tue, 21 Jul 2015 16:25:49 +0000 (UTC) Received: from hp-dl360pgen8-07.khw.lab.eng.bos.redhat.com (hp-dl360pgen8-07.khw.lab.eng.bos.redhat.com [10.16.184.47]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6LGPmTC001218; Tue, 21 Jul 2015 12:25:49 -0400 From: Jarod Wilson To: linux-kernel@vger.kernel.org Cc: Jarod Wilson , Bjorn Helgaas , "Rafael J. Wysocki" , linux-pci@vger.kernel.org Subject: [PATCH] pci/pciehp: bail on bogus pcie reads from removed devices Date: Tue, 21 Jul 2015 12:25:30 -0400 Message-Id: <1437495930-7723-1-git-send-email-jarod@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP https://bugzilla.kernel.org/show_bug.cgi?id=99841 Seems like a read of all 1's from a register of a device that has gone away should be taken as a sign that the device has gone away. Section 6.2.10 of the PCIE spec (v4.0, rev 0.3, Feb 19, 2014) suggests as much with this snippet: |IMPLEMENTATION NOTE |Data Value of All 1’s |Many platforms, including those supporting RP Extensions for DPC, can |return a data value of all 1’s to software when an error is associated |with a PCI Express Configuration, I/O, or Memory Read Request. During DPC, |the Downstream Port discards Requests destined for the Link and completes |them with an error (i.e., either with an Unsupported Request (UR) or |Completer Abort (CA) Completion Status). By ending a series of MMIO or |configuration space operations with a read to an address with a known |data value not equal to all 1’s, software may determine if a Completer |has been removed or DPC has been triggered. I'm not sure the above is directly relevant to this case, but the same principle (reading all 1's means the device is probably gone) seems to hold. This is based on part of a debugging patch Bjorn posted in the referenced bugzilla, and its required to make the HP ZBook G2 I've got here not barf when disconnecting a thunderbolt ethernet adapter and corrupt memory. Suggested-by: Bjorn Helgaas CC: Bjorn Helgaas CC: Rafael J. Wysocki CC: linux-pci@vger.kernel.org Signed-off-by: Jarod Wilson --- drivers/pci/hotplug/pciehp_hpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index bb1d0de..c397851 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -547,6 +547,11 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) do { pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected); + if (detected == (u16) ~0) { + ctrl_info(ctrl, "Device has gone away\n"); + return IRQ_HANDLED; + } + detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);