From patchwork Tue Nov 7 21:47:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Hasemeyer X-Patchwork-Id: 162734 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:aa0b:0:b0:403:3b70:6f57 with SMTP id k11csp534645vqo; Tue, 7 Nov 2023 13:48:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IGuC8fgnxgd1TKipDPWNh2GYgzsJ7TwLg64k/OzjNIcU++7vJfzcwHRX9tdPxNto96TON9K X-Received: by 2002:a05:6870:a996:b0:1eb:e8b:7206 with SMTP id ep22-20020a056870a99600b001eb0e8b7206mr5215018oab.14.1699393692871; Tue, 07 Nov 2023 13:48:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699393692; cv=none; d=google.com; s=arc-20160816; b=zoyjwuCFw7cHG1zDEuTwTptKvZ7+YgaQg2iMJKTNV0m8nix5rn0XWqZU3vTfMJ/KLi 1WXHanQ6Y+bAno98B+dez0EYliDAcC216H9qG3fXgcNjR2yuT4OL2F0glU4GzhKIl3Zc BgsTfPGwZIHLyCU6DVmJmkdyZo2pey1Z0W6KI9YGVUp53gEi+2E0SbQtu3MEjEJRd2A2 NkEdb+bxjyeNR/P53FkrdG36rrbYzUOxbXFteHwG3xnN0ao0p51MMqz41kKowcPq5mjE yyTfbAHM2+sF6VLYG0BT/c69UzOLQOZzvEuxYimO4rPMq1roeS6CLq1iNPrDvynOpmR2 IdXA== 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=s08RBoZSpHbsDlBdpZDIYrmoRYe1Os4Jlgu75g52b+A=; fh=nJH2JPsgSboWNMeIpurih/NfS9kISKLd4ZN26ZpSsV4=; b=o6eQqtN6+j2bzmIW0Yx/pmkuuduC6A1fanWP1/ERLt1kh5WXSzqpKF1tTPMXSlM07v 6X6XozQOuhh+MEbrz1nmWSFkFIcbDxjr927IDo0CWilu0N+m1n99o4h8xE7yZVzlFXbn QSAyMimZLrP1R+015H9utaSLYpQCcMc1ZVCbbaHY9e9Q3LYZoNV2/i8xwCHs6NDQRyQ3 VcFXCzPEFXsHrEoyWw7ccYki9aCf/uCspKmmeEn/12sHZkozeP9nhpB/dpl6ysylbtd2 gRdd3skQPo1hEPWZQNsu9pOFrd/5PiUCWCuuUaguLD1cdcW28yBCWNHWOJYgh2LKxf89 vIzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=as2UIWGO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id ch2-20020a056a0208c200b005b96f683c66si3381053pgb.354.2023.11.07.13.48.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Nov 2023 13:48:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=as2UIWGO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id AA82182C92EF; Tue, 7 Nov 2023 13:48:11 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343777AbjKGVsL (ORCPT + 32 others); Tue, 7 Nov 2023 16:48:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234954AbjKGVsK (ORCPT ); Tue, 7 Nov 2023 16:48:10 -0500 Received: from mail-il1-x132.google.com (mail-il1-x132.google.com [IPv6:2607:f8b0:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FDD110CF for ; Tue, 7 Nov 2023 13:48:08 -0800 (PST) Received: by mail-il1-x132.google.com with SMTP id e9e14a558f8ab-359343e399fso21026795ab.0 for ; Tue, 07 Nov 2023 13:48:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1699393687; x=1699998487; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=s08RBoZSpHbsDlBdpZDIYrmoRYe1Os4Jlgu75g52b+A=; b=as2UIWGOz3L39ymOa4CeOga1gFYC3tdHuxoIU/rRKRus8baoxZQQNznmQYFbwl2rI9 YMeaoA/sn8ozW9XYN5z+scyhxmBaF+M+PZ9JFWN4RS8UrZnP10IWn4PJfcQMmMLBf2xT LB8RJ0MpJ7di7v7bm60CTjGyKGSgboOw8Q9/A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699393687; x=1699998487; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=s08RBoZSpHbsDlBdpZDIYrmoRYe1Os4Jlgu75g52b+A=; b=mAlfWSwxCbpIsteuEFoG2kfF0HOWSezmRNKQM5+yOrXyEOcQaj1qKewlEqiLXoXpyi SzpAeVJXHb2Po8nONxQDntWyfdqnPoKNEVT5dk+jp3r5S3VmWFVROz7UspooDdWqVs3v VhneAJLcyhr0VazqjGm0KlNYt43z5R9ekmExhXJJon/7T/wjoFdkHk1EonHMR72fSaP3 02AE5AwHdR79EbQPbgnHb4PnbLHhYLMN8x/YLuQ5llV21L5IgMx2+5C817lXZ5tpUE9j VXZEJ1OZo65r0ZfrZDrBVxz+3gCCkybb9QGdBFz2MxNY57cNFaovHCBYroKpDc+R7Gur SRkQ== X-Gm-Message-State: AOJu0YybX+LSx4HY8KXi6AjmS01Q/vmA72yy51vBtUqU2do0SyiRSuqT ezAXUWgAoyEKDnjIXPnSNOh2vfh+UrkamJTme/Q= X-Received: by 2002:a92:cd82:0:b0:359:4287:28fc with SMTP id r2-20020a92cd82000000b00359428728fcmr147662ilb.7.1699393687330; Tue, 07 Nov 2023 13:48:07 -0800 (PST) Received: from markhas1.corp.google.com ([100.107.108.162]) by smtp.gmail.com with ESMTPSA id l2-20020a056e020e4200b0035161817c37sm3389024ilk.1.2023.11.07.13.48.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Nov 2023 13:48:07 -0800 (PST) From: Mark Hasemeyer To: LKML Cc: Mark Hasemeyer , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH v1] spi: Fix null dereference on suspend Date: Tue, 7 Nov 2023 14:47:43 -0700 Message-ID: <20231107144743.v1.1.I7987f05f61901f567f7661763646cb7d7919b528@changeid> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 07 Nov 2023 13:48:11 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781943440719375239 X-GMAIL-MSGID: 1781943440719375239 A race condition exists where a synchronous (noqueue) transfer can be active during a system suspend. This can cause a null pointer dereference exception to occur when the system resumes. Example order of events leading to the exception: 1. spi_sync() calls __spi_transfer_message_noqueue() which sets ctlr->cur_msg 2. Spi transfer begins via spi_transfer_one_message() 3. System is suspended interrupting the transfer context 4. System is resumed 6. spi_controller_resume() calls spi_start_queue() which resets cur_msg to NULL 7. Spi transfer context resumes and spi_finalize_current_message() is called which dereferences cur_msg (which is now NULL) Wait for synchronous transfers to complete before suspending by acquiring the bus mutex and setting/checking a suspend flag. Signed-off-by: Mark Hasemeyer --- drivers/spi/spi.c | 56 ++++++++++++++++++++++++++++------------- include/linux/spi/spi.h | 1 + 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 791df0e69105..8ead7acb99f3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3317,33 +3317,52 @@ void spi_unregister_controller(struct spi_controller *ctlr) } EXPORT_SYMBOL_GPL(spi_unregister_controller); +static inline int __spi_check_suspended(const struct spi_controller *ctlr) +{ + return ctlr->flags & SPI_CONTROLLER_SUSPENDED ? -ESHUTDOWN : 0; +} + +static inline void __spi_mark_suspended(struct spi_controller *ctlr) +{ + mutex_lock(&ctlr->bus_lock_mutex); + ctlr->flags |= SPI_CONTROLLER_SUSPENDED; + mutex_unlock(&ctlr->bus_lock_mutex); +} + +static inline void __spi_mark_resumed(struct spi_controller *ctlr) +{ + mutex_lock(&ctlr->bus_lock_mutex); + ctlr->flags &= ~SPI_CONTROLLER_SUSPENDED; + mutex_unlock(&ctlr->bus_lock_mutex); +} + int spi_controller_suspend(struct spi_controller *ctlr) { - int ret; + int ret = 0; /* Basically no-ops for non-queued controllers */ - if (!ctlr->queued) - return 0; - - ret = spi_stop_queue(ctlr); - if (ret) - dev_err(&ctlr->dev, "queue stop failed\n"); + if (ctlr->queued) { + ret = spi_stop_queue(ctlr); + if (ret) + dev_err(&ctlr->dev, "queue stop failed\n"); + } + __spi_mark_suspended(ctlr); return ret; } EXPORT_SYMBOL_GPL(spi_controller_suspend); int spi_controller_resume(struct spi_controller *ctlr) { - int ret; - - if (!ctlr->queued) - return 0; + int ret = 0; - ret = spi_start_queue(ctlr); - if (ret) - dev_err(&ctlr->dev, "queue restart failed\n"); + __spi_mark_resumed(ctlr); + if (ctlr->queued) { + ret = spi_start_queue(ctlr); + if (ret) + dev_err(&ctlr->dev, "queue restart failed\n"); + } return ret; } EXPORT_SYMBOL_GPL(spi_controller_resume); @@ -4147,8 +4166,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s ctlr->cur_msg = msg; ret = __spi_pump_transfer_message(ctlr, msg, was_busy); if (ret) - goto out; - + dev_err(&ctlr->dev, "noqueue transfer failed\n"); ctlr->cur_msg = NULL; ctlr->fallback = false; @@ -4164,7 +4182,6 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s spi_idle_runtime_pm(ctlr); } -out: mutex_unlock(&ctlr->io_mutex); } @@ -4187,6 +4204,11 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) int status; struct spi_controller *ctlr = spi->controller; + if (__spi_check_suspended(ctlr)) { + dev_warn_once(&spi->dev, "Attempted to sync while suspend\n"); + return -ESHUTDOWN; + } + status = __spi_validate(spi, message); if (status != 0) return status; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 86825c88b576..255a0562aea5 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -566,6 +566,7 @@ struct spi_controller { #define SPI_CONTROLLER_MUST_RX BIT(3) /* Requires rx */ #define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */ #define SPI_CONTROLLER_GPIO_SS BIT(5) /* GPIO CS must select slave */ +#define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */ /* Flag indicating if the allocation of this struct is devres-managed */ bool devm_allocated;