From patchwork Thu Jul 12 05:18:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 1186591 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 3ECDA40B20 for ; Thu, 12 Jul 2012 05:19:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752539Ab2GLFSs (ORCPT ); Thu, 12 Jul 2012 01:18:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48148 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752253Ab2GLFSr (ORCPT ); Thu, 12 Jul 2012 01:18:47 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q6C5Ihup020509 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 12 Jul 2012 01:18:43 -0400 Received: from bling.home (ovpn-113-63.phx2.redhat.com [10.3.113.63]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q6C5Ifdb003075; Thu, 12 Jul 2012 01:18:42 -0400 From: Alex Williamson Subject: [PATCH RFC] pci: ACS quirk for AMD southbridge To: linux-pci@vger.kernel.org, Joerg.Roedel@amd.com Cc: andihartmann@01019freenet.de, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Date: Wed, 11 Jul 2012 23:18:41 -0600 Message-ID: <20120712050653.20439.11009.stgit@bling.home> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org We've confirmed that peer-to-peer between these devices is not possible. We can therefore claim that they support a subset of ACS. Signed-off-by: Alex Williamson Cc: Joerg Roedel Tested-by: Andreas Hartmann --- Two things about this patch make me a little nervous. The first is that I'd really like to have a pci_is_pcie() test in pci_mf_no_p2p_acs_enabled(), but these devices don't have a PCIe capability. That means that if there was a topology where these devices sit on a legacy PCI bus, we incorrectly return that we're ACS safe here. That leads to my second problem, pciids seems to suggest that some of these functions have been around for a while. Is it just this package that's peer-to-peer safe, or is it safe to assume that any previous assembly of these functions is also p2p safe. Maybe we need to factor in device revs if that uniquely identifies this package? Looks like another useful device to potentially quirk would be: 00:15.0 PCI bridge: Advanced Micro Devices [AMD] nee ATI SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0) 00:15.1 PCI bridge: Advanced Micro Devices [AMD] nee ATI SB700/SB800/SB900 PCI to PCI bridge (PCIE port 1) 00:15.2 PCI bridge: Advanced Micro Devices [AMD] nee ATI SB900 PCI to PCI bridge (PCIE port 2) 00:15.3 PCI bridge: Advanced Micro Devices [AMD] nee ATI SB900 PCI to PCI bridge (PCIE port 3) 00:15.0 0604: 1002:43a0 00:15.1 0604: 1002:43a1 00:15.2 0604: 1002:43a2 00:15.3 0604: 1002:43a3 drivers/pci/quirks.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 4ebc865..2c84961 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3271,11 +3271,40 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev) return pci_dev_get(dev); } +/* + * Multifunction devices that do not support peer-to-peer between + * functions can claim to support a subset of ACS. Such devices + * effectively enable request redirect (RR) and completion redirect (CR) + * since all transactions are redirected to the upstream root complex. + */ +static int pci_mf_no_p2p_acs_enabled(struct pci_dev *dev, u16 acs_flags) +{ + if (!dev->multifunction) + return -ENODEV; + + /* Filter out flags not applicable to multifunction */ + acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT); + + return acs_flags & ~(PCI_ACS_RR | PCI_ACS_CR) ? 0 : 1; +} + static const struct pci_dev_acs_enabled { u16 vendor; u16 device; int (*acs_enabled)(struct pci_dev *dev, u16 acs_flags); } pci_dev_acs_enabled[] = { + /* + * AMD/ATI multifunction southbridge devices. AMD has confirmed + * that peer-to-peer between these devices is not possible, so + * they do support a subset of ACS even though the capability is + * not exposed in config space. + */ + { PCI_VENDOR_ID_ATI, 0x4385, pci_mf_no_p2p_acs_enabled }, + { PCI_VENDOR_ID_ATI, 0x439c, pci_mf_no_p2p_acs_enabled }, + { PCI_VENDOR_ID_ATI, 0x4383, pci_mf_no_p2p_acs_enabled }, + { PCI_VENDOR_ID_ATI, 0x439d, pci_mf_no_p2p_acs_enabled }, + { PCI_VENDOR_ID_ATI, 0x4384, pci_mf_no_p2p_acs_enabled }, + { PCI_VENDOR_ID_ATI, 0x4399, pci_mf_no_p2p_acs_enabled }, { 0 } };