Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp691212rwd; Thu, 15 Jun 2023 00:13:16 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7UU1XvdbNsAl/I5PR2TaahgdGl6IVyXpSD9br2vsG36S1WaXiLaoXA2jWmDppM8jKrRie9 X-Received: by 2002:aa7:8893:0:b0:666:617a:c3b5 with SMTP id z19-20020aa78893000000b00666617ac3b5mr3720479pfe.21.1686813196559; Thu, 15 Jun 2023 00:13:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686813196; cv=none; d=google.com; s=arc-20160816; b=HkVsGAXSN+4bjfNoQ+V+9ggiJTCdbJnsjCiMBuRgcsjCesJaeWIMwIWgFs7bX8xB9Z hwP+mqoxPg4pzXuTexQAsHOzBUh5rqW+sySMHeLkogBxrRAALobp5JijI27BIEJcFSrJ k6+YA9EQ3tWOu0ZdoyNOWSlu7SAYX4iGAbsI/45RJ9og9cKRBAtW3VWHWjD3ADYtCPGZ Cu3mylQc8lFOzq++ucMIRTqmIvfdIBEqvsXYhdD/IxUNEr9aXGtRDfCmhA0lOEBgiOsm DS7uybUmPOYAA5pwIaSmVyjtn6dq0s3ZUiDS1gz4ocpWd/BsrjBtDox9PQQw2zopxq2F smNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=ZtguwqtGAwKhEjHws0zviElIJiuMMHsOfAOidNicXOI=; b=aDIK/X/2WfJrqcMnlu+Gg97c6+7Eam16YI7cOpGdA3l4RfwRqLxBn4v+sxCq6CQkAI jI6nBOM6CGnM1RNxwX6kw4oGdFXjHqdZG6vQWmIzl0PpQHEXgKuRcNe8zzX8pABx1Mv9 U2SziHXxQohlBTPHeeY/FFHUz68PalbUveGZZZ3SO9V4VT574uXafWc8yfF3M8O/zhJR thBuQ8nvaGi+Z3vgYwCcI2aPmWcL+TnxAdesWhzknCx5j/bUkX5r0uAHl1hYGy/61YQA 3cdfUFAm6Gvf8aKfX14MeQIhVaEHhFzGlrJisNy7Lc5QbshuAFsywMDIw3eDv3h41qb1 ZgAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=msjafntM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g23-20020aa796b7000000b006293f8330fcsi8543584pfk.322.2023.06.15.00.13.04; Thu, 15 Jun 2023 00:13:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=msjafntM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243732AbjFOG0P (ORCPT + 99 others); Thu, 15 Jun 2023 02:26:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237795AbjFOG0J (ORCPT ); Thu, 15 Jun 2023 02:26:09 -0400 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6607A26AF; Wed, 14 Jun 2023 23:26:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686810362; x=1718346362; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=2iuy8KyO3OHv0vuu9wEkAYWlBpQgmQ6Sr/z3577fngY=; b=msjafntMeg2VN/WtOYKToZMnuVtSIzA6r6Dg2BeiUQ83HNeTenyyHcOS YkwZC+Z7I8a2Kf0MleV6pwWYqvOARb9TTLYG0DXm668kS9tz07kk0l1Yo bmEMKCCQmySVnzW//tPyDJ0NJjR/01lIrBUtX9XdiuUEJpFlBd54VpAeR hl8vZ8AK8fjs1VDsZ2Esm+SQh1J6OpCkm5ng+HUnbZNsdFLSfKleJ/RpY f5TPG4zamtPIfY3msJWXgG6VhFwWQc9ijxMAvEkbW44HHuo3FK9fTTqo1 1V5R37gA5/AduPR2sU+906PB7+3/hw5OcImAX4PMJRrn1xeC1xdPbZs9u A==; X-IronPort-AV: E=McAfee;i="6600,9927,10741"; a="361303658" X-IronPort-AV: E=Sophos;i="6.00,244,1681196400"; d="scan'208";a="361303658" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jun 2023 23:26:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10741"; a="742121918" X-IronPort-AV: E=Sophos;i="6.00,244,1681196400"; d="scan'208";a="742121918" Received: from akcopko-mobl2.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.220.19]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jun 2023 23:26:01 -0700 From: Kuppuswamy Sathyanarayanan To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Kuppuswamy Sathyanarayanan Subject: [PATCH v1] PCI: pciehp: Make sure DPC trigger status is reset in PDC handler Date: Wed, 14 Jun 2023 23:25:59 -0700 Message-Id: <20230615062559.1268404-1-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org During the EDR-based DPC recovery process, for devices with persistent issues, the firmware may choose not to handle the DPC error and leave the port in DPC triggered state. In such scenarios, if the user replaces the faulty device with a new one, the OS is expected to clear the DPC trigger status in the hotplug error handler to enable the new device enumeration. More details about this issue can be found in PCIe firmware specification, r3.3, sec titled "DPC Event Handling" Implementation note. Similar issue might also happen if the DPC or EDR recovery handler exits before clearing the trigger status. To fix this issue, clear the DPC trigger status in PDC interrupt handler. Signed-off-by: Kuppuswamy Sathyanarayanan Reported-by: Thatchanamurthy Satish --- drivers/pci/hotplug/pciehp_hpc.c | 6 +++++ drivers/pci/pci.h | 4 ++++ drivers/pci/pcie/dpc.c | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index f8c70115b691..03f8f18a6cf5 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -735,6 +735,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) PCI_EXP_SLTCTL_ATTN_IND_ON); } + /* Clear DPC trigger status */ + if ((events & PCI_EXP_SLTSTA_PDC) && pci_dpc_is_triggered(pdev)) { + ctrl_dbg(ctrl, "Slot(%s): Clear DPC trigger\n", slot_name(ctrl)); + pci_dpc_reset_trigger(pdev); + } + /* * Ignore Link Down/Up events caused by Downstream Port Containment * if recovery from the error succeeded. diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 2475098f6518..bbe70e9ab747 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -426,11 +426,15 @@ void pci_dpc_init(struct pci_dev *pdev); void dpc_process_error(struct pci_dev *pdev); pci_ers_result_t dpc_reset_link(struct pci_dev *pdev); bool pci_dpc_recovered(struct pci_dev *pdev); +bool pci_dpc_is_triggered(struct pci_dev *pdev); +void pci_dpc_reset_trigger(struct pci_dev *pdev); #else static inline void pci_save_dpc_state(struct pci_dev *dev) {} static inline void pci_restore_dpc_state(struct pci_dev *dev) {} static inline void pci_dpc_init(struct pci_dev *pdev) {} static inline bool pci_dpc_recovered(struct pci_dev *pdev) { return false; } +static inline bool pci_dpc_is_triggered(struct pci_dev *pdev) { return false; } +static inline void pci_dpc_reset_trigger(struct pci_dev *pdev) {} #endif #ifdef CONFIG_PCIEPORTBUS diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index 3ceed8e3de41..ccdc90d37f6d 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -88,6 +88,46 @@ static bool dpc_completed(struct pci_dev *pdev) return true; } +/** + * pci_dpc_is_triggered - Check for DPC trigger status + * @pdev: PCI device + * + * It is called from the PCIe hotplug driver to check for DPC + * trigger status. + * + * Return True if DPC is triggered or false for other cases. + */ +bool pci_dpc_is_triggered(struct pci_dev *pdev) +{ + u16 status; + + if (!pdev->dpc_cap) + return false; + + pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_STATUS, &status); + + if ((!PCI_POSSIBLE_ERROR(status)) && (status & PCI_EXP_DPC_STATUS_TRIGGER)) + return true; + + return false; +} + +/** + * pci_reset_trigger - Clear DPC trigger status + * @pdev: PCI device + * + * It is called from the PCIe hotplug driver to clean the DPC + * trigger status in the PDC interrupt handler. + */ +void pci_dpc_reset_trigger(struct pci_dev *pdev) +{ + if (!pdev->dpc_cap) + return; + + pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_STATUS, + PCI_EXP_DPC_STATUS_TRIGGER); +} + /** * pci_dpc_recovered - whether DPC triggered and has recovered successfully * @pdev: PCI device -- 2.34.1