Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp4728204imm; Wed, 30 May 2018 10:46:20 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIWsNQWnBMUx+3GJHLLMM6zXrnVMR1r3Dp6SPMMyLaZB3aVLRKEY7OZ696n6g6j98U+zyv2 X-Received: by 2002:a17:902:9b8a:: with SMTP id y10-v6mr3788798plp.124.1527702380205; Wed, 30 May 2018 10:46:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527702380; cv=none; d=google.com; s=arc-20160816; b=tflyuJF0HxCPuyk/8PFPstm++Jqrp2WMeDJAE5bWWSDLnfzrBQ2NI0pbIcMZBOvaUE JQJmf9n0T73qukGnHA2ughJGhrlReAVCUYUOhLYmr93UgXjzyixuqUO488r3hePh5AHp PztZybukF+gyYii2oRNQ6fRdIFFSOfIqKoXPIp9qljR8fp4gDyWT8473ome8BFETa1Dg 30TiN6ReaGAE9nf4IwP8vU1R1d1itiSGvLutK19J57Qh5uo5cE/GXENwfQWvDEzzavzW iDadQSEwCRN6Ax++7tsoa0dfbXY1uPMdPWNGYoWPtN+oy7BZNLChKTIZjA28L4ovHLZ2 zd5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=nDAvjra4jSu8eUOJ4H40bRNY8QbbgmBm4Ab2+tYvnXk=; b=l4aW3Ksa/cxh10uO+3YVVIxhhQyJGD5+52x/v8V73uhXE+ykTIwsXLoUgTCw7MS61b Qqeq5OR2ZPKknDumYMWKry4gjU2CaQOtTgxLcLh81fon+7322TpDgU31Ni29pNeE394J w7CvY8guIzZR7wQeX9f1Y3rwkfmy7Yh1pL1j4V4MoWoM0gXvgFNVtNNApBYZEObdWUoC eleFBTN64Mn0Yry9dswD7gY0OCN9FQ2keF3RFdPEgRdEG0Q8JfKyrH69ZKtH1iHLMgr5 kE3CPvI4NvnMvGEmi+eJET8ldtyq+5lUunNcVpCcaMl5CFTgn65qK0IlSg86pPrM5gfj Z3cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=S3XTv1Os; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o12-v6si35255064plg.463.2018.05.30.10.46.06; Wed, 30 May 2018 10:46:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=S3XTv1Os; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753770AbeE3RoM (ORCPT + 99 others); Wed, 30 May 2018 13:44:12 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:40994 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932162AbeE3RoE (ORCPT ); Wed, 30 May 2018 13:44:04 -0400 Received: by mail-qk0-f196.google.com with SMTP id d125-v6so15008021qkb.8 for ; Wed, 30 May 2018 10:44:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=nDAvjra4jSu8eUOJ4H40bRNY8QbbgmBm4Ab2+tYvnXk=; b=S3XTv1OsLWBabxzE4Xf8H1fcuvHQSiP9883+/1t9q3tCkRgCE1cUD4xmkl7YEgPBWK /MDXANGmBmEsEwkrn+wONWH89AV/8yMwoXnexwUP1tp4zoDl9lxeUTbHW4Mzq+LK43F/ WDRqZVsEr/fDIH0XAtoduU1b1iTUV+BDdsHkI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=nDAvjra4jSu8eUOJ4H40bRNY8QbbgmBm4Ab2+tYvnXk=; b=OBYQPg6o5pBSr3emp8WKl5ti+Ogy1FTBfv8YR3+shxSL6rOjoee0gPYLJJ9amaZGg5 8eNR1cSeqjlhkECkWy5kFpr6RBVbHOYoAws1vfiQsY+Fg6cy8rem0MVwCaL3PAXrMVnR Jq4IVVAHw0GGjN+UNEfQSEtQsG5opxXXvLonpItL85B/cSO0oFpELRM6oGheLm8+A7xO XbNWRxIxZETg2zDGysxnPnl6INGXbx+GtrhRV+aPoEe5njSjE0pdjwD1+F6KC8U+KqOf px0qlshplyzrBmLIbslSXmuoiw1dfozvGAn3oJKSDO3Hoo4kQzb4CM8pdth+KWf2xg66 3f9Q== X-Gm-Message-State: APt69E2wLdC3WsDMLkC4Goeks4n39V4QO88dEu5cjndBbolfMLkL8S3l n0+qk9aG+uciwtQXDHkvr+9L+wVnEe0= X-Received: by 2002:a37:ab04:: with SMTP id u4-v6mr3216818qke.92.1527702243211; Wed, 30 May 2018 10:44:03 -0700 (PDT) Received: from [10.136.8.248] ([192.19.228.250]) by smtp.gmail.com with ESMTPSA id i52-v6sm14119132qtc.26.2018.05.30.10.44.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 May 2018 10:44:02 -0700 (PDT) Subject: Re: [PATCH INTERNAL 2/3] PCI: iproc: Fix up corrupted PAXC root complex config registers To: Bjorn Helgaas Cc: Bjorn Helgaas , Lorenzo Pieralisi , linux-kernel@vger.kernel.org, bcm-kernel-feedback-list@broadcom.com, linux-pci@vger.kernel.org, Ray Jui References: <1526577692-21104-1-git-send-email-ray.jui@broadcom.com> <1526577692-21104-3-git-send-email-ray.jui@broadcom.com> <20180530172733.GN39853@bhelgaas-glaptop.roam.corp.google.com> From: Ray Jui Message-ID: <715d8746-1b68-4342-6258-7d9c1b5035bc@broadcom.com> Date: Wed, 30 May 2018 10:43:59 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: <20180530172733.GN39853@bhelgaas-glaptop.roam.corp.google.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Bjorn, On 5/30/2018 10:27 AM, Bjorn Helgaas wrote: > On Thu, May 17, 2018 at 10:21:31AM -0700, Ray Jui wrote: >> On certain versions of Broadcom PAXC based root complexes, certain >> regions of the configuration space are corrupted. As a result, it >> prevents the Linux PCIe stack from traversing the linked list of the >> capability registers completely and therefore the root complex is >> not advertised as "PCIe capable". This prevents the correct PCIe RID >> from being parsed in the kernel PCIe stack. A correct RID is required >> for mapping to a stream ID from the SMMU or the device ID from the >> GICv3 ITS >> >> This patch fixes up the issue by manually populating the related >> PCIe capabilities based on readings from the PCIe capability structure >> >> Signed-off-by: Ray Jui >> Reviewed-by: Anup Patel >> Reviewed-by: Scott Branden >> --- >> drivers/pci/quirks.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 95 insertions(+) >> >> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c >> index 47dfea0..0cdbd0a 100644 >> --- a/drivers/pci/quirks.c >> +++ b/drivers/pci/quirks.c >> @@ -2198,6 +2198,101 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); >> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge); >> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge); >> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge); >> + >> +/* >> + * The PCI capabilities list for certain revisions of Broadcom PAXC root >> + * complexes is incorrectly terminated due to corrupted configuration space >> + * registers in the range of 0x50 - 0x5f >> + * >> + * As a result, the capability list becomes broken and prevent standard PCI >> + * stack from being able to traverse to the PCIe capability structure >> + */ >> +static void quirk_paxc_pcie_capability(struct pci_dev *pdev) >> +{ >> + int pos, i = 0; >> + u8 next_cap; >> + u16 reg16, *cap; >> + struct pci_cap_saved_state *state; >> + >> + /* bail out if PCIe capability can be found */ >> + if (pdev->pcie_cap || pci_find_capability(pdev, PCI_CAP_ID_EXP)) >> + return; >> + >> + /* locate the power management capability */ >> + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); >> + if (!pos) >> + return; >> + >> + /* bail out if the next capability pointer is not 0x50/0x58 */ >> + pci_read_config_byte(pdev, pos + 1, &next_cap); >> + if (next_cap != 0x50 && next_cap != 0x58) >> + return; >> + >> + /* bail out if we do not terminate at 0x50/0x58 */ >> + pos = next_cap; >> + pci_read_config_byte(pdev, pos + 1, &next_cap); >> + if (next_cap != 0x00) >> + return; >> + >> + /* >> + * On these buggy HW, PCIe capability structure is expected to be at >> + * 0xac and should terminate the list >> + * >> + * Borrow the similar logic from theIntel DH895xCC VFs fixup to save >> + * the PCIe capability list >> + */ >> + pos = 0xac; >> + pci_read_config_word(pdev, pos, ®16); >> + if (reg16 == (0x0000 | PCI_CAP_ID_EXP)) { >> + u32 status; >> + >> +#ifndef PCI_EXP_SAVE_REGS >> +#define PCI_EXP_SAVE_REGS 7 >> +#endif >> + int size = PCI_EXP_SAVE_REGS * sizeof(u16); >> + >> + pdev->pcie_cap = pos; >> + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); >> + pdev->pcie_flags_reg = reg16; >> + pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); >> + pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; > > Is there any way you can fix this in iproc_pcie_config_read() instead, > by making it notice when we're reading a corrupted part of config > space, and then returning the correct data instead? Is it just the > next capability pointer that's corrupted? Let me look into that and I'll get back. Thanks, Ray > > If you could fix it in the config accessor, lspci would automatically > show all the correct data (I think lspci will still show the wrong > data with this patch). > > The quirk seems like a maintenance issue because anything that calls > > pci_find_capability(pdev, PCI_CAP_ID_EXP) > > will get the wrong answer. > >> + >> + pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE; >> + if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) != >> + PCIBIOS_SUCCESSFUL || (status == 0xffffffff)) >> + pdev->cfg_size = PCI_CFG_SPACE_SIZE; >> + >> + if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP)) >> + return; >> + >> + state = kzalloc(sizeof(*state) + size, GFP_KERNEL); >> + if (!state) >> + return; >> + >> + state->cap.cap_nr = PCI_CAP_ID_EXP; >> + state->cap.cap_extended = 0; >> + state->cap.size = size; >> + cap = (u16 *)&state->cap.data[0]; >> + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_RTCTL, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL2, &cap[i++]); >> + pcie_capability_read_word(pdev, PCI_EXP_SLTCTL2, &cap[i++]); >> + hlist_add_head(&state->next, &pdev->saved_cap_space); >> + } >> +} >> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57810, >> + quirk_paxc_pcie_capability); >> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, >> + quirk_paxc_pcie_capability); >> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, >> + quirk_paxc_pcie_capability); >> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, >> + quirk_paxc_pcie_capability); >> +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, >> + quirk_paxc_pcie_capability); >> #endif >> >> /* Originally in EDAC sources for i82875P: >> -- >> 2.1.4 >>