From patchwork Sat Mar 25 16:18:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Semwal X-Patchwork-Id: 95996 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp532301qgd; Sat, 25 Mar 2017 09:19:56 -0700 (PDT) X-Received: by 10.84.238.198 with SMTP id l6mr2024060pln.180.1490458796031; Sat, 25 Mar 2017 09:19:56 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r3si6723034pli.62.2017.03.25.09.19.55; Sat, 25 Mar 2017 09:19:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-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=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751369AbdCYQT4 (ORCPT + 5 others); Sat, 25 Mar 2017 12:19:56 -0400 Received: from mail-pg0-f51.google.com ([74.125.83.51]:33863 "EHLO mail-pg0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751309AbdCYQTz (ORCPT ); Sat, 25 Mar 2017 12:19:55 -0400 Received: by mail-pg0-f51.google.com with SMTP id 21so9216782pgg.1 for ; Sat, 25 Mar 2017 09:19:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hJPf7RJxau8VbD3E7u+sG2cCpRhrCdqE2BZU50yPUsE=; b=gRXAQWMgUTd9haZ5pM91LZXnKvpyhfX6H6xWvEFOOXqVndXSoTtv02yKk0dhHO29Kq q04kTJbS5opyJs9scXvYj3gP093DCLrJ3l+UlBCeTB7zEmBil7MDJls/oyYpXSvIEwsx ISSnIKtJ6F0IG6cEpBqpP0PiXZaigHVgGflZc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hJPf7RJxau8VbD3E7u+sG2cCpRhrCdqE2BZU50yPUsE=; b=lF556mwhJQVXCd4JLZQkEHpJrJjtJMRwGLwZEdzfnT0nF4oqlpVaGpQobEFUsNCLVf 8JkRlRQR/D9+llmKH6hHhW6DWABi3c9K26arGPehhkijtFKLiFcb2hEkXZNjol+lihsm qqJx5T1G0G1rDTfqydGXsvBARI+KUep6cwV6PQg6DjiCv8IuqtUGfZziXd3dvAsw3LaB MUsemBmpMIttem2u+0Cms0KvstQRwIz3ysNB7pS9BF5JvyQC0fXPfwQ2ihXo3gU79viR owmJmlz6gzmmkiA/eeB4y+Q8PAC59huysfZhWW1p9dgVeR2G/51BcB9UlNK2raQL1Tl9 Szvg== X-Gm-Message-State: AFeK/H2AbeTbzY/2cQtSibeQSWpYO71IE9GEgTBvFmuq4EHU0KYVXkl0VZ+3IRo46a7g6zbM X-Received: by 10.99.61.201 with SMTP id k192mr15489127pga.68.1490458793914; Sat, 25 Mar 2017 09:19:53 -0700 (PDT) Received: from phantom.lan ([106.51.225.38]) by smtp.gmail.com with ESMTPSA id q194sm11469541pfq.43.2017.03.25.09.19.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 25 Mar 2017 09:19:52 -0700 (PDT) From: Sumit Semwal To: stable@vger.kernel.org Cc: Gabriel Krisman Bertazi , Greg Kroah-Hartman , Sasha Levin , Sumit Semwal Subject: [PATCH for-4.4 19/19] serial: 8250_pci: Detach low-level driver during PCI error recovery Date: Sat, 25 Mar 2017 21:48:19 +0530 Message-Id: <1490458699-24484-20-git-send-email-sumit.semwal@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> References: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Gabriel Krisman Bertazi [ Upstream commit f209fa03fc9d131b3108c2e4936181eabab87416 ] During a PCI error recovery, like the ones provoked by EEH in the ppc64 platform, all IO to the device must be blocked while the recovery is completed. Current 8250_pci implementation only suspends the port instead of detaching it, which doesn't prevent incoming accesses like TIOCMGET and TIOCMSET calls from reaching the device. Those end up racing with the EEH recovery, crashing it. Similar races were also observed when opening the device and when shutting it down during recovery. This patch implements a more robust IO blockage for the 8250_pci recovery by unregistering the port at the beginning of the procedure and re-adding it afterwards. Since the port is detached from the uart layer, we can be sure that no request will make through to the device during recovery. This is similar to the solution used by the JSM serial driver. I thank Peter Hurley for valuable input on this one over one year ago. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sumit Semwal --- drivers/tty/serial/8250/8250_pci.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) -- 2.7.4 diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 5b24ffd..83ff172 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -57,6 +57,7 @@ struct serial_private { unsigned int nr; void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; struct pci_serial_quirk *quirk; + const struct pciserial_board *board; int line[0]; }; @@ -4058,6 +4059,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) } } priv->nr = i; + priv->board = board; return priv; err_deinit: @@ -4068,7 +4070,7 @@ err_out: } EXPORT_SYMBOL_GPL(pciserial_init_ports); -void pciserial_remove_ports(struct serial_private *priv) +void pciserial_detach_ports(struct serial_private *priv) { struct pci_serial_quirk *quirk; int i; @@ -4088,7 +4090,11 @@ void pciserial_remove_ports(struct serial_private *priv) quirk = find_quirk(priv->dev); if (quirk->exit) quirk->exit(priv->dev); +} +void pciserial_remove_ports(struct serial_private *priv) +{ + pciserial_detach_ports(priv); kfree(priv); } EXPORT_SYMBOL_GPL(pciserial_remove_ports); @@ -5819,7 +5825,7 @@ static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev, return PCI_ERS_RESULT_DISCONNECT; if (priv) - pciserial_suspend_ports(priv); + pciserial_detach_ports(priv); pci_disable_device(dev); @@ -5844,9 +5850,18 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) static void serial8250_io_resume(struct pci_dev *dev) { struct serial_private *priv = pci_get_drvdata(dev); + const struct pciserial_board *board; - if (priv) - pciserial_resume_ports(priv); + if (!priv) + return; + + board = priv->board; + kfree(priv); + priv = pciserial_init_ports(dev, board); + + if (!IS_ERR(priv)) { + pci_set_drvdata(dev, priv); + } } static const struct pci_error_handlers serial8250_err_handler = {