From patchwork Tue Feb 19 19:06:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 1044869 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 443rfj1040z9s21 for ; Wed, 20 Feb 2019 06:39:57 +1100 (AEDT) Received: from localhost ([127.0.0.1]:53860 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gwAtU-0008FN-PR for incoming@patchwork.ozlabs.org; Tue, 19 Feb 2019 14:17:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33808) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gwAss-0008Cz-Kz for qemu-devel@nongnu.org; Tue, 19 Feb 2019 14:16:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gwAsq-0000zz-Nd for qemu-devel@nongnu.org; Tue, 19 Feb 2019 14:16:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36212) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gwAsp-0000zT-PF for qemu-devel@nongnu.org; Tue, 19 Feb 2019 14:16:48 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E0E66C718A; Tue, 19 Feb 2019 19:06:54 +0000 (UTC) Received: from gimli.home (ovpn-116-24.phx2.redhat.com [10.3.116.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id 35AD25D970; Tue, 19 Feb 2019 19:06:43 +0000 (UTC) From: Alex Williamson To: qemu-devel@nongnu.org Date: Tue, 19 Feb 2019 12:06:43 -0700 Message-ID: <155060310248.19547.14979269067689441201.stgit@gimli.home> User-Agent: StGit/0.19-dirty MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 19 Feb 2019 19:06:54 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH] pci: Sanity test minimum downstream LNKSTA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jens Freimann , mst@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The entire link status register for SR-IOV VFs is defined as RsvdZ, reads simply return zero. Usually this is nothing more than lspci reporting inconsequentially broken values: LnkSta: Speed unknown, Width x0, ... However, now that we're using the downstream endpoint link status to fill in the value at the parent downstream port, invalid values become a problem. In particular, the PCIe hotplug driver in Linux looks for a valid negotiated link width and will fail to enumerate hot-added downstream endpoints without non-zero value here, ex: pciehp 0000:00:02.0:pcie004: Slot(0): Attention button pressed pciehp 0000:00:02.0:pcie004: Slot(0) Powering on due to button press pciehp 0000:00:02.0:pcie004: Slot(0): Card present pciehp 0000:00:02.0:pcie004: Slot(0): Link Up pciehp 0000:00:02.0:pcie004: link training error: status 0x2000 pciehp 0000:00:02.0:pcie004: Failed to check link status Resolve by using minimum width and speed values for the downstream port link status when the endpoint fails to provide valid values. Long term, we may want to implement emulation in the vfio-pci host driver to suppliment this field with the PF value as the SR-IOV spec seems to allow, but the solution here is compatible should that be implemented later. Fixes: 727b48661f75 ("pci: Sync PCIe downstream port LNKSTA on read") Reported-by: Jens Freimann Signed-off-by: Alex Williamson Tested-by: Jens Freimann Reviewed-by: Marcel Apfelbaum --- hw/pci/pcie.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 3f7c36609313..3618d6ab2e1a 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -834,9 +834,12 @@ void pcie_add_capability(PCIDevice *dev, /* * Sync the PCIe Link Status negotiated speed and width of a bridge with the * downstream device. If downstream device is not present, re-write with the - * Link Capability fields. Limit width and speed to bridge capabilities for - * compatibility. Use config_read to access the downstream device since it - * could be an assigned device with volatile link information. + * Link Capability fields. If downstream device reports invalid width or + * speed, replace with minimum values (LnkSta fields are RsvdZ on VFs but such + * values interfere with PCIe native hotplug detecting new devices). Limit + * width and speed to bridge capabilities for compatibility. Use config_read + * to access the downstream device since it could be an assigned device with + * volatile link information. */ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) { @@ -856,11 +859,15 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) { lnksta &= ~PCI_EXP_LNKSTA_NLW; lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW; + } else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { + lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); } if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) { lnksta &= ~PCI_EXP_LNKSTA_CLS; lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS; + } else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { + lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); } }