On 28 September 2026 17:46:04 BST, "Uwe Kleine-König" <[email protected]> wrote: >Driver overriding is useful only in a very limited set of situations >and then only with very few drivers that are designed to support that. > >Disallow matching via driver_override unless the driver explicitly >allows it or the safe guard is disabled using the >"allow_driver_override" kernel parameter. > >Implementation detail: device_match_driver_override() isn't a static >inline any more. It grew a certain complexity (e.g. a pr_info()) and so >was made a regular exported function. > >Signed-off-by: Uwe Kleine-König <[email protected]> >--- > drivers/base/bus.c | 43 +++++++++++++++++++++++++++++++++++ > include/linux/device.h | 26 ++------------------- > include/linux/device/driver.h | 2 ++ > 3 files changed, 47 insertions(+), 24 deletions(-) > >diff --git a/drivers/base/bus.c b/drivers/base/bus.c >index c51ad96d4de4..d294c198ab0c 100644 >--- a/drivers/base/bus.c >+++ b/drivers/base/bus.c >@@ -606,6 +606,49 @@ int bus_add_device(struct device *dev) > return error; > } > >+static int __read_mostly allow_driver_override; >+ >+static int __init allow_driver_override_setup(char *str) >+{ >+ allow_driver_override = 1; >+ >+ return 1; >+} >+__setup("allow_driver_override", allow_driver_override_setup); >+ >+/** >+ * device_match_driver_override() - Match a driver against the device's >driver_override. >+ * @dev: device to check >+ * @drv: driver to match against >+ * >+ * Returns > 0 if a driver override is set and matches the given driver, 0 if >a >+ * driver override is set but does not match, or < 0 if a driver override is >not >+ * set at all. >+ */
Nice! Reviewed-by: Bradley Morgan <[email protected]> I mean, others may provide nits, but I'm rarely a nit guy >+int device_match_driver_override(struct device *dev, >+ const struct device_driver *drv) >+{ >+ guard(spinlock)(&dev->driver_override.lock); >+ if (dev->driver_override.name) { >+ int ret = !strcmp(dev->driver_override.name, drv->name); >+ >+ if (ret > 0) { >+ if (!allow_driver_override && >!drv->support_driver_override) { >+ pr_info("Suppress driver override binding. >Allow %ps to do overriding or boot with allow_driver_override on cmdline\n", >+ drv); >+ return -1; >+ } >+ >+ add_taint_module(drv->owner, >+ TAINT_DRIVER_OVERRIDE, >LOCKDEP_STILL_OK); >+ } >+ >+ return ret; >+ } >+ return -1; >+} >+EXPORT_SYMBOL_GPL(device_match_driver_override); >+ > /** > * bus_probe_device - probe drivers for a new device > * @dev: device to probe >diff --git a/include/linux/device.h b/include/linux/device.h >index 4dac5e09b74c..a142bf384f1e 100644 >--- a/include/linux/device.h >+++ b/include/linux/device.h >@@ -892,30 +892,8 @@ static inline bool device_has_driver_override(struct >device *dev) > return !!dev->driver_override.name; > } > >-/** >- * device_match_driver_override() - Match a driver against the device's >driver_override. >- * @dev: device to check >- * @drv: driver to match against >- * >- * Returns > 0 if a driver override is set and matches the given driver, 0 if >a >- * driver override is set but does not match, or < 0 if a driver override is >not >- * set at all. >- */ >-static inline int device_match_driver_override(struct device *dev, >- const struct device_driver *drv) >-{ >- guard(spinlock)(&dev->driver_override.lock); >- if (dev->driver_override.name) { >- int ret = !strcmp(dev->driver_override.name, drv->name); >- >- if (ret > 0) >- add_taint_module(drv->owner, >- TAINT_DRIVER_OVERRIDE, >LOCKDEP_STILL_OK); >- >- return ret; >- } >- return -1; >-} >+int device_match_driver_override(struct device *dev, >+ const struct device_driver *drv); > > /** > * device_iommu_mapped - Returns true when the device DMA is translated >diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h >index 29fbc01ef06f..0153cfcbe1b9 100644 >--- a/include/linux/device/driver.h >+++ b/include/linux/device/driver.h >@@ -56,6 +56,7 @@ enum probe_type { > * @bus: The bus which the device of this driver belongs to. > * @owner: The module owner. > * @mod_name: Used for built-in modules. >+ * @support_driver_override: driver_override only works if this is true. > * @suppress_bind_attrs: Disables bind/unbind via sysfs. > * @probe_type: Type of the probe (synchronous or asynchronous) to use. > * @of_match_table: The open firmware table. >@@ -104,6 +105,7 @@ struct device_driver { > struct module *owner; > const char *mod_name; /* used for built-in modules */ > >+ bool support_driver_override; > bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ > enum probe_type probe_type; > > --- Thanks! "I'm not a very positive person" - Linus torvalds
