From patchwork Thu Aug 8 13:57:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFkaW0gS3LEjW3DocWZ?= X-Patchwork-Id: 2841168 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F4028BF546 for ; Thu, 8 Aug 2013 13:57:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CBB42204C7 for ; Thu, 8 Aug 2013 13:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A18C1204AD for ; Thu, 8 Aug 2013 13:57:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965109Ab3HHN5W (ORCPT ); Thu, 8 Aug 2013 09:57:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51600 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965097Ab3HHN5U (ORCPT ); Thu, 8 Aug 2013 09:57:20 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r78Dv8Dw024069 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 8 Aug 2013 09:57:08 -0400 Received: from dhcp-26-241.brq.redhat.com (dhcp-1-106.brq.redhat.com [10.34.1.106]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r78Dv73J013603; Thu, 8 Aug 2013 09:57:07 -0400 Received: by dhcp-26-241.brq.redhat.com (Postfix, from userid 0) id 1216AE8EF8; Thu, 8 Aug 2013 15:57:07 +0200 (CEST) From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org Cc: Bjorn Helgaas , "Michael S. Tsirkin" , Alex Williamson , Myron Stowe , Joe Lawrence , Kenji Kaneshige , Isaku Yamahata Subject: [PATCH] PCI: avoid NULL deref in alloc_pcie_link_state Date: Thu, 8 Aug 2013 15:57:07 +0200 Message-Id: <1375970227-14794-1-git-send-email-rkrcmar@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-5.9 required=5.0 tests=BAYES_00,HK_RANDOM_FROM, 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 PCIe switch can be connected directly to the PCIe root complex in QEMU; ASPM does not expect this topology and dereferences NULL pointer when initializing. Downstream port can be also connected to the root complex without upstream one, so code checks for both, otherwise they dereference NULL on line drivers/pci/pcie/aspm.c:530 (alloc_pcie_link_state+13): parent = pdev->bus->parent->self->link_state; "pdev->bus->parent->self == NULL" if upstream port is connected directly to the root bus and "pdev->bus->parent == NULL" in the second case. v1 -> v2: (https://lkml.org/lkml/2013/6/19/753) - Initialization is aborted in pcie_aspm_init_link_state, where other special cases are being handled - pci_is_root_bus is used - Warning is printed Reproducer for "downstream -- root" and "downstream -- upstream -- root" (used qemu-kvm 1.5, q35 machine type might be missing on older ones) for parent in pcie.0 upstream; do qemu-kvm -m 128 -M q35 -nographic -no-reboot \ -device x3130-upstream,bus=pcie.0,id=upstream \ -device xio3130-downstream,bus=$parent,id=downstream,chassis=1 \ -device virtio-blk-pci,bus=downstream,id=virtio-zero,drive=zero \ -drive file=/dev/zero,id=zero,format=raw \ -kernel bzImage -append "console=ttyS0 panic=3" # pcie_aspm=off done ASPM in QEMU works if we connect upstream through root port -device ioh3420,bus=pcie.0,id=root.0 \ -device x3130-upstream,bus=root.0,id=upstream Signed-off-by: Radim Kr?má? --- drivers/pci/pcie/aspm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 403a443..209cd7f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -570,6 +570,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) pdev->bus->self) return; + /* We require at least two ports between downstream and root bus */ + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM && + (pci_is_root_bus(pdev->bus) || + pci_is_root_bus(pdev->bus->parent))) { + dev_warn(&pdev->dev, "ASPM disabled" + " (connected directly to root bus)\n"); + return; + } + down_read(&pci_bus_sem); if (list_empty(&pdev->subordinate->devices)) goto out;