Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1233770pxb; Thu, 21 Oct 2021 19:03:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwdfvRs3cOD/E2dbLKu6pj78QMLYJEJsz0VxvPMIEFfShOfYCyM244+M6oxShytjob4lWb+ X-Received: by 2002:a17:907:da4:: with SMTP id go36mr11657981ejc.481.1634868219574; Thu, 21 Oct 2021 19:03:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634868219; cv=none; d=google.com; s=arc-20160816; b=nft60AFBVUYhZrid3FXIOsWCJG8lbzBR7KZxj12H44IhdIvZ/X4MxDPaESPOBjWAKF 8F1lbTbBD/aECRqfSoSsCfDyRAhRMM9VuNh4/TOJycYeKclv24xe2reTdiffv/SJX/B/ DbTMVTQ9WMaB1SOyURJIKvxKu6kLSZOlDnNihXEAKrWFvVAfA/9CNdt10h3Mhb0J+SjV BAp5crM9YEVV1cEChP9KsnmfHrGi+DwUZBXhGOOGSgWtGqUXfNRQUPh+0/ILMaelqwOM 3H/Pznrkd7ppXGimnP8YT1+Bp2Nmg5vlU9BOdccC7LkptZCeJmm16na1thuoGDTfodff ijDg== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7bg47D2PUr63KTjRLOr3QPGPVQLLJR5F+XwJqWsUVxg=; b=ZaWLRu0/hP5//05uF24pbEFrCxGEmtMiqu1D4udY7GlHEPG6UTa5xTft/NJA0tFshb vQi04uJUWHD5fYcWQTwD3bXHYY//+V+sgUiF7pzhMjwFFodTGzva9glXS5B/3oEYB2WI 6fLAo7U0XfKJQwpTtKYbK02eoCHY8HT186cqYhKbt1Tg8IzcV1+sM06YsY/59qGwOBgn +5wiISl4AdISst4fCFYeYdPCyUkFqoWaGmoBUOcl7efEVdzEWMY86YZtyaVpFcU8Jird 7LEDVvyycENsHxMXoRgOAC75XVJzuy2rSSu4g6zFbyQZwlQgbYibf6Wd1Ld7u6927JhO CGQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bewilderbeest.net header.s=thorn header.b=d32Nc7aV; 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=bewilderbeest.net Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g3si13617441ejt.525.2021.10.21.19.03.03; Thu, 21 Oct 2021 19:03:39 -0700 (PDT) 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=@bewilderbeest.net header.s=thorn header.b=d32Nc7aV; 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=bewilderbeest.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232201AbhJVCDK (ORCPT + 99 others); Thu, 21 Oct 2021 22:03:10 -0400 Received: from thorn.bewilderbeest.net ([71.19.156.171]:52303 "EHLO thorn.bewilderbeest.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231997AbhJVCDF (ORCPT ); Thu, 21 Oct 2021 22:03:05 -0400 Received: from hatter.bewilderbeest.net (71-212-29-146.tukw.qwest.net [71.212.29.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: zev) by thorn.bewilderbeest.net (Postfix) with ESMTPSA id AC68DB49; Thu, 21 Oct 2021 19:00:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bewilderbeest.net; s=thorn; t=1634868048; bh=7bg47D2PUr63KTjRLOr3QPGPVQLLJR5F+XwJqWsUVxg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d32Nc7aVCto4w6Kfipr6ZiL8YdmnB5OWrXB2lhs04vNQPWK+6EyeHSmMros6UlQlu 3k3pSDbEuMoaMFI/V5OYe4FmeEtp3HfKObSMowHvvQjJ69rKZdSeBuAH9jlxfoxGYg mnUgrPoj2bSp1jM/i2Ypqq2xmph608ytcAVaee8w= From: Zev Weiss To: Frank Rowand , Greg Kroah-Hartman , Rob Herring Cc: openbmc@lists.ozlabs.org, Jeremy Kerr , Joel Stanley , Andrew Jeffery , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Zev Weiss , "Rafael J. Wysocki" , Dave Jiang , Vinod Koul , Kirti Wankhede , Alex Williamson , Cornelia Huck , Saravana Kannan , Konrad Rzeszutek Wilk , Thomas Gleixner , Bhaskar Chowdhury , Jianxiong Gao , Mauro Carvalho Chehab , Rajat Jain , Andy Shevchenko , dmaengine@vger.kernel.org, kvm@vger.kernel.org Subject: [PATCH 4/5] driver core: inhibit automatic driver binding on reserved devices Date: Thu, 21 Oct 2021 19:00:31 -0700 Message-Id: <20211022020032.26980-5-zev@bewilderbeest.net> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211022020032.26980-1-zev@bewilderbeest.net> References: <20211022020032.26980-1-zev@bewilderbeest.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Devices whose fwnodes are marked as reserved are instantiated, but will not have a driver bound to them unless userspace explicitly requests it by writing to a 'bind' sysfs file. This is to enable devices that may require special (userspace-mediated) preparation before a driver can safely probe them. Signed-off-by: Zev Weiss --- drivers/base/bus.c | 2 +- drivers/base/dd.c | 13 ++++++++----- drivers/dma/idxd/compat.c | 3 +-- drivers/vfio/mdev/mdev_core.c | 2 +- include/linux/device.h | 14 +++++++++++++- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index bdc98c5713d5..8a30f9a02de0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -211,7 +211,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, dev = bus_find_device_by_name(bus, NULL, buf); if (dev && driver_match_device(drv, dev)) { - err = device_driver_attach(drv, dev); + err = device_driver_attach(drv, dev, DRV_BIND_EXPLICIT); if (!err) { /* success */ err = count; diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 68ea1f949daa..ee64740a63d9 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -727,13 +728,14 @@ void wait_for_device_probe(void) } EXPORT_SYMBOL_GPL(wait_for_device_probe); -static int __driver_probe_device(struct device_driver *drv, struct device *dev) +static int __driver_probe_device(struct device_driver *drv, struct device *dev, u32 flags) { int ret = 0; if (dev->p->dead || !device_is_registered(dev)) return -ENODEV; - if (dev->driver) + if (dev->driver || + (fwnode_device_is_reserved(dev->fwnode) && !(flags & DRV_BIND_EXPLICIT))) return -EBUSY; dev->can_match = true; @@ -778,7 +780,7 @@ static int driver_probe_device(struct device_driver *drv, struct device *dev) int ret; atomic_inc(&probe_count); - ret = __driver_probe_device(drv, dev); + ret = __driver_probe_device(drv, dev, DRV_BIND_DEFAULT); if (ret == -EPROBE_DEFER || ret == EPROBE_DEFER) { driver_deferred_probe_add(dev); @@ -1052,16 +1054,17 @@ static void __device_driver_unlock(struct device *dev, struct device *parent) * device_driver_attach - attach a specific driver to a specific device * @drv: Driver to attach * @dev: Device to attach it to + * @flags: Bitmask of DRV_BIND_* flags * * Manually attach driver to a device. Will acquire both @dev lock and * @dev->parent lock if needed. Returns 0 on success, -ERR on failure. */ -int device_driver_attach(struct device_driver *drv, struct device *dev) +int device_driver_attach(struct device_driver *drv, struct device *dev, u32 flags) { int ret; __device_driver_lock(dev, dev->parent); - ret = __driver_probe_device(drv, dev); + ret = __driver_probe_device(drv, dev, flags); __device_driver_unlock(dev, dev->parent); /* also return probe errors as normal negative errnos */ diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index 3df21615f888..51df38dea15a 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -7,7 +7,6 @@ #include #include "idxd.h" -extern int device_driver_attach(struct device_driver *drv, struct device *dev); extern void device_driver_detach(struct device *dev); #define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ @@ -56,7 +55,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou if (!alt_drv) return -ENODEV; - rc = device_driver_attach(alt_drv, dev); + rc = device_driver_attach(alt_drv, dev, DRV_BIND_EXPLICIT); if (rc < 0) return rc; diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index b314101237fe..f42c6ec543c8 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -309,7 +309,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid) if (!drv) drv = &vfio_mdev_driver; - ret = device_driver_attach(&drv->driver, &mdev->dev); + ret = device_driver_attach(&drv->driver, &mdev->dev, DRV_BIND_DEFAULT); if (ret) goto out_del; diff --git a/include/linux/device.h b/include/linux/device.h index e270cb740b9e..1ada1093799b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -876,12 +876,24 @@ static inline void *dev_get_platdata(const struct device *dev) return dev->platform_data; } +/* + * Driver-binding flags (for passing to device_driver_attach()) + * + * DRV_BIND_DEFAULT: a default, automatic bind, e.g. as a result of a device + * being added for which we already have a driver, or vice + * versa. + * DRV_BIND_EXPLICIT: an explicit, userspace-requested driver bind, e.g. as a + * result of a write to /sys/bus/.../drivers/.../bind + */ +#define DRV_BIND_DEFAULT 0 +#define DRV_BIND_EXPLICIT BIT(0) + /* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ int __must_check device_driver_attach(struct device_driver *drv, - struct device *dev); + struct device *dev, u32 flags); int __must_check device_bind_driver(struct device *dev); void device_release_driver(struct device *dev); int __must_check device_attach(struct device *dev); -- 2.33.1