Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9212118pxu; Mon, 28 Dec 2020 09:24:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJyxuRwRtiVdDwOfOMGS1NSWUoT0wRAb9j1mttb1A661suh7jv5HDKiP8JsnyhJ52kASaObk X-Received: by 2002:a05:6402:c95:: with SMTP id cm21mr43321021edb.294.1609176262027; Mon, 28 Dec 2020 09:24:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609176262; cv=none; d=google.com; s=arc-20160816; b=NhDC0EAg6rJApMpDEO4oLYqTYktQ2rw+KlqbCWS4QlrRM2eXgYy5WGZaWj7vq0u6M+ DK0LbFl5P3ctG0ex0YRC7rx3eo1Neta0I35EdFUgAjCy/u/Sq50HvFOKNHHoAt/sP3I9 T8HQkM62btKYSBnMvVGxsNKxiDPINQx4cNaOxHGn3PSeYvwBU7F5qZ6TZJSjD1jMzP/j rB6+qKEUr9MnE90I+Ies4ewC4n6oDbYBawJEADLvw4fztchuwUbNC0yZ8HefLh6u/3po 9p+b0xspQrAEjXPgCovDWAqqzyXh2gRuqzR9xE5n6DDnEKpVLvX6fomvlDjDzhm1d1/T m8iA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=5QiYabjGVT2VFu40GiNI1sIF/33Ps1SqhfV8bdhLA3Q=; b=jH2Vc5oCSctJxlcJrkPIX4HvT+o0utcUgDhHVejmYfgaiJf9uYj1f3d/EIDMk3Epw2 SZeDJidbrlp+oCfaENO1I4ap4Qgc3IRko4FEM9UnvSog91gVpDWYpUU1JQ3Fxrf+JP9w Qwd4zHSUMhPJsL8Ne3jWmrfrbOR+5BMih4D73psgb2bHlrl/r3uLOrTn2DvZs+EX68sL cFXtO3xUgkJaj9Z8oaxTD0099mS2qJ/52TkN0bgvusOCDFryBMX+pbYdFERhOpQz9lTD aVi5VuPZD8AQnBKme31HQt5bhDaZDy+gtgS3zLo7G8Pfeoc4ofXV2vjkI3bi0IQic4p/ 5jEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="0RBWjr/f"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gk1si3532256ejc.288.2020.12.28.09.24.00; Mon, 28 Dec 2020 09:24:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="0RBWjr/f"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728114AbgL1M7V (ORCPT + 99 others); Mon, 28 Dec 2020 07:59:21 -0500 Received: from mail.kernel.org ([198.145.29.99]:55584 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726606AbgL1M7T (ORCPT ); Mon, 28 Dec 2020 07:59:19 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 68D2422573; Mon, 28 Dec 2020 12:58:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609160319; bh=Qd6aj9x/qUTjM3GHQ853OvkN2U3bcXzD0Z2BxUwS9uY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0RBWjr/fMjz60uE1JHvvow3Za7fPKWnM6kpsxt8NQ0dS9NlOy5zF0h0K+XVaYFui4 N8rUNOHVHd+yTKXkadSzZnCTSCo8VYSJqfkB74hpq/kZQU1bzYdLDtkE6RtISCPqjr GKjUJL2Vvr4cV+ZN/8iiDqvdkFdEcOnhrwQFv/lY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lukas Wunner , Geert Uytterhoeven , Octavian Purdila , Pantelis Antoniou , Mark Brown , Sudip Mukherjee Subject: [PATCH 4.9 011/175] spi: Prevent adding devices below an unregistering controller Date: Mon, 28 Dec 2020 13:47:44 +0100 Message-Id: <20201228124853.801123776@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228124853.216621466@linuxfoundation.org> References: <20201228124853.216621466@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lukas Wunner commit ddf75be47ca748f8b12d28ac64d624354fddf189 upstream CONFIG_OF_DYNAMIC and CONFIG_ACPI allow adding SPI devices at runtime using a DeviceTree overlay or DSDT patch. CONFIG_SPI_SLAVE allows the same via sysfs. But there are no precautions to prevent adding a device below a controller that's being removed. Such a device is unusable and may not even be able to unbind cleanly as it becomes inaccessible once the controller has been torn down. E.g. it is then impossible to quiesce the device's interrupt. of_spi_notify() and acpi_spi_notify() do hold a ref on the controller, but otherwise run lockless against spi_unregister_controller(). Fix by holding the spi_add_lock in spi_unregister_controller() and bailing out of spi_add_device() if the controller has been unregistered concurrently. Fixes: ce79d54ae447 ("spi/of: Add OF notifier handler") Signed-off-by: Lukas Wunner Cc: stable@vger.kernel.org # v3.19+ Cc: Geert Uytterhoeven Cc: Octavian Purdila Cc: Pantelis Antoniou Link: https://lore.kernel.org/r/a8c3205088a969dc8410eec1eba9aface60f36af.1596451035.git.lukas@wunner.de Signed-off-by: Mark Brown [sudip: adjust context] Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/spi/Kconfig | 3 +++ drivers/spi/spi.c | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -763,4 +763,7 @@ endif # SPI_MASTER # (slave support would go here) +config SPI_DYNAMIC + def_bool ACPI || OF_DYNAMIC || SPI_SLAVE + endif # SPI --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -422,6 +422,12 @@ static LIST_HEAD(spi_master_list); */ static DEFINE_MUTEX(board_lock); +/* + * Prevents addition of devices with same chip select and + * addition of devices below an unregistering controller. + */ +static DEFINE_MUTEX(spi_add_lock); + /** * spi_alloc_device - Allocate a new SPI device * @master: Controller to which device is connected @@ -500,7 +506,6 @@ static int spi_dev_check(struct device * */ int spi_add_device(struct spi_device *spi) { - static DEFINE_MUTEX(spi_add_lock); struct spi_master *master = spi->master; struct device *dev = master->dev.parent; int status; @@ -529,6 +534,13 @@ int spi_add_device(struct spi_device *sp goto done; } + /* Controller may unregister concurrently */ + if (IS_ENABLED(CONFIG_SPI_DYNAMIC) && + !device_is_registered(&master->dev)) { + status = -ENODEV; + goto done; + } + if (master->cs_gpios) spi->cs_gpio = master->cs_gpios[spi->chip_select]; @@ -2070,6 +2082,10 @@ static int __unregister(struct device *d */ void spi_unregister_master(struct spi_master *master) { + /* Prevent addition of new devices, unregister existing ones */ + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) + mutex_lock(&spi_add_lock); + device_for_each_child(&master->dev, NULL, __unregister); if (master->queued) { @@ -2089,6 +2105,9 @@ void spi_unregister_master(struct spi_ma if (!devres_find(master->dev.parent, devm_spi_release_master, devm_spi_match_master, master)) put_device(&master->dev); + + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) + mutex_unlock(&spi_add_lock); } EXPORT_SYMBOL_GPL(spi_unregister_master);