Skip to content

Commit 4793dae

Browse files
committed
Merge tag 'driver-core-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core updates from Danilo Krummrich: "debugfs: - Fix NULL pointer dereference in debugfs_create_str() - Fix misplaced EXPORT_SYMBOL_GPL for debugfs_create_str() - Fix soundwire debugfs NULL pointer dereference from uninitialized firmware_file device property: - Make fwnode flags modifications thread safe; widen the field to unsigned long and use set_bit() / clear_bit() based accessors - Document how to check for the property presence devres: - Separate struct devres_node from its "subclasses" (struct devres, struct devres_group); give struct devres_node its own release and free callbacks for per-type dispatch - Introduce struct devres_action for devres actions, avoiding the ARCH_DMA_MINALIGN alignment overhead of struct devres - Export struct devres_node and its init/add/remove/dbginfo primitives for use by Rust Devres<T> - Fix missing node debug info in devm_krealloc() - Use guard(spinlock_irqsave) where applicable; consolidate unlock paths in devres_release_group() driver_override: - Convert PCI, WMI, vdpa, s390/cio, s390/ap, and fsl-mc to the generic driver_override infrastructure, replacing per-bus driver_override strings, sysfs attributes, and match logic; fixes a potential UAF from unsynchronized access to driver_override in bus match() callbacks - Simplify __device_set_driver_override() logic kernfs: - Send IN_DELETE_SELF and IN_IGNORED inotify events on kernfs file and directory removal - Add corresponding selftests for memcg platform: - Allow attaching software nodes when creating platform devices via a new 'swnode' field in struct platform_device_info - Add kerneldoc for struct platform_device_info software node: - Move software node initialization from postcore_initcall() to driver_init(), making it available early in the boot process - Move kernel_kobj initialization (ksysfs_init) earlier to support the above - Remove software_node_exit(); dead code in a built-in unit SoC: - Introduce of_machine_read_compatible() and of_machine_read_model() OF helpers and export soc_attr_read_machine() to replace direct accesses to of_root from SoC drivers; also enables CONFIG_COMPILE_TEST coverage for these drivers sysfs: - Constify attribute group array pointers to 'const struct attribute_group *const *' in sysfs functions, device_add_groups() / device_remove_groups(), and struct class Rust: - Devres: - Embed struct devres_node directly in Devres<T> instead of going through devm_add_action(), avoiding the extra allocation and the unnecessary ARCH_DMA_MINALIGN alignment - I/O: - Turn IoCapable from a marker trait into a functional trait carrying the raw I/O accessor implementation (io_read / io_write), providing working defaults for the per-type Io methods - Add RelaxedMmio wrapper type, making relaxed accessors usable in code generic over the Io trait - Remove overloaded per-type Io methods and per-backend macros from Mmio and PCI ConfigSpace - I/O (Register): - Add IoLoc trait and generic read/write/update methods to the Io trait, making I/O operations parameterizable by typed locations - Add register! macro for defining hardware register types with typed bitfield accessors backed by Bounded values; supports direct, relative, and array register addressing - Add write_reg() / try_write_reg() and LocatedRegister trait - Update PCI sample driver to demonstrate the register! macro Example: ``` register! { /// UART control register. CTRL(u32) @ 0x18 { /// Receiver enable. 19:19 rx_enable => bool; /// Parity configuration. 14:13 parity ?=> Parity; } /// FIFO watermark and counter register. WATER(u32) @ 0x2c { /// Number of datawords in the receive FIFO. 26:24 rx_count; /// RX interrupt threshold. 17:16 rx_water; } } impl WATER { fn rx_above_watermark(&self) -> bool { self.rx_count() > self.rx_water() } } fn init(bar: &pci::Bar<BAR0_SIZE>) { let water = WATER::zeroed() .with_const_rx_water::<1>(); // > 3 would not compile bar.write_reg(water); let ctrl = CTRL::zeroed() .with_parity(Parity::Even) .with_rx_enable(true); bar.write_reg(ctrl); } fn handle_rx(bar: &pci::Bar<BAR0_SIZE>) { if bar.read(WATER).rx_above_watermark() { // drain the FIFO } } fn set_parity(bar: &pci::Bar<BAR0_SIZE>, parity: Parity) { bar.update(CTRL, |r| r.with_parity(parity)); } ``` - IRQ: - Move 'static bounds from where clauses to trait declarations for IRQ handler traits - Misc: - Enable the generic_arg_infer Rust feature - Extend Bounded with shift operations, single-bit bool conversion, and const get() Misc: - Make deferred_probe_timeout default a Kconfig option - Drop auxiliary_dev_pm_ops; the PM core falls back to driver PM callbacks when no bus type PM ops are set - Add conditional guard support for device_lock() - Add ksysfs.c to the DRIVER CORE MAINTAINERS entry - Fix kernel-doc warnings in base.h - Fix stale reference to memory_block_add_nid() in documentation" * tag 'driver-core-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: (67 commits) bus: fsl-mc: use generic driver_override infrastructure s390/ap: use generic driver_override infrastructure s390/cio: use generic driver_override infrastructure vdpa: use generic driver_override infrastructure platform/wmi: use generic driver_override infrastructure PCI: use generic driver_override infrastructure driver core: make software nodes available earlier software node: remove software_node_exit() kernel: ksysfs: initialize kernel_kobj earlier MAINTAINERS: add ksysfs.c to the DRIVER CORE entry drivers/base/memory: fix stale reference to memory_block_add_nid() device property: Document how to check for the property presence soundwire: debugfs: initialize firmware_file to empty string debugfs: fix placement of EXPORT_SYMBOL_GPL for debugfs_create_str() debugfs: check for NULL pointer in debugfs_create_str() driver core: Make deferred_probe_timeout default a Kconfig option driver core: simplify __device_set_driver_override() clearing logic driver core: auxiliary bus: Drop auxiliary_dev_pm_ops device property: Make modifications of fwnode "flags" thread safe rust: devres: embed struct devres_node directly ...
2 parents d568788 + 6c8dfb0 commit 4793dae

68 files changed

Lines changed: 2839 additions & 1014 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7807,8 +7807,10 @@ F: include/linux/debugfs.h
78077807
F: include/linux/device.h
78087808
F: include/linux/fwnode.h
78097809
F: include/linux/kobj*
7810+
F: include/linux/ksysfs.h
78107811
F: include/linux/property.h
78117812
F: include/linux/sysfs.h
7813+
F: kernel/ksysfs.c
78127814
F: lib/kobj*
78137815
F: rust/kernel/debugfs.rs
78147816
F: rust/kernel/debugfs/

drivers/base/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ config DEVTMPFS_SAFE
7373
with the PROT_EXEC flag. This can break, for example, non-KMS
7474
video drivers.
7575

76+
config DRIVER_DEFERRED_PROBE_TIMEOUT
77+
int "Default value for deferred_probe_timeout"
78+
default 0 if !MODULES
79+
default 10 if MODULES
80+
help
81+
Set the default value for the deferred_probe_timeout kernel parameter.
82+
See Documentation/admin-guide/kernel-parameters.txt for a description
83+
of the deferred_probe_timeout kernel parameter.
84+
7685
config STANDALONE
7786
bool "Select only drivers that don't need compile-time external firmware"
7887
default y

drivers/base/auxiliary.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,6 @@ static int auxiliary_uevent(const struct device *dev, struct kobj_uevent_env *en
207207
(int)(p - name), name);
208208
}
209209

210-
static const struct dev_pm_ops auxiliary_dev_pm_ops = {
211-
SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
212-
SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)
213-
};
214-
215210
static int auxiliary_bus_probe(struct device *dev)
216211
{
217212
const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
@@ -258,7 +253,6 @@ static const struct bus_type auxiliary_bus_type = {
258253
.shutdown = auxiliary_bus_shutdown,
259254
.match = auxiliary_match,
260255
.uevent = auxiliary_uevent,
261-
.pm = &auxiliary_dev_pm_ops,
262256
};
263257

264258
/**

drivers/base/base.h

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,28 @@
1313
#include <linux/notifier.h>
1414

1515
/**
16-
* struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
17-
*
18-
* @subsys - the struct kset that defines this subsystem
19-
* @devices_kset - the subsystem's 'devices' directory
20-
* @interfaces - list of subsystem interfaces associated
21-
* @mutex - protect the devices, and interfaces lists.
22-
*
23-
* @drivers_kset - the list of drivers associated
24-
* @klist_devices - the klist to iterate over the @devices_kset
25-
* @klist_drivers - the klist to iterate over the @drivers_kset
26-
* @bus_notifier - the bus notifier list for anything that cares about things
27-
* on this bus.
28-
* @bus - pointer back to the struct bus_type that this structure is associated
29-
* with.
16+
* struct subsys_private - structure to hold the private to the driver core
17+
* portions of the bus_type/class structure.
18+
* @subsys: the struct kset that defines this subsystem
19+
* @devices_kset: the subsystem's 'devices' directory
20+
* @interfaces: list of subsystem interfaces associated
21+
* @mutex: protect the devices, and interfaces lists.
22+
* @drivers_kset: the list of drivers associated
23+
* @klist_devices: the klist to iterate over the @devices_kset
24+
* @klist_drivers: the klist to iterate over the @drivers_kset
25+
* @bus_notifier: the bus notifier list for anything that cares about things
26+
* on this bus.
27+
* @drivers_autoprobe: gate whether new devices are automatically attached to
28+
* registered drivers, or new drivers automatically attach
29+
* to existing devices.
30+
* @bus: pointer back to the struct bus_type that this structure is associated
31+
* with.
3032
* @dev_root: Default device to use as the parent.
31-
*
32-
* @glue_dirs - "glue" directory to put in-between the parent device to
33-
* avoid namespace conflicts
34-
* @class - pointer back to the struct class that this structure is associated
35-
* with.
36-
* @lock_key: Lock class key for use by the lock validator
33+
* @glue_dirs: "glue" directory to put in-between the parent device to
34+
* avoid namespace conflicts
35+
* @class: pointer back to the struct class that this structure is associated
36+
* with.
37+
* @lock_key: Lock class key for use by the lock validator
3738
*
3839
* This structure is the one that is the actual kobject allowing struct
3940
* bus_type/class to be statically allocated safely. Nothing outside of the
@@ -98,24 +99,26 @@ struct driver_type {
9899
#endif
99100

100101
/**
101-
* struct device_private - structure to hold the private to the driver core portions of the device structure.
102-
*
103-
* @klist_children - klist containing all children of this device
104-
* @knode_parent - node in sibling list
105-
* @knode_driver - node in driver list
106-
* @knode_bus - node in bus list
107-
* @knode_class - node in class list
108-
* @deferred_probe - entry in deferred_probe_list which is used to retry the
109-
* binding of drivers which were unable to get all the resources needed by
110-
* the device; typically because it depends on another driver getting
111-
* probed first.
112-
* @async_driver - pointer to device driver awaiting probe via async_probe
113-
* @device - pointer back to the struct device that this structure is
114-
* associated with.
115-
* @driver_type - The type of the bound Rust driver.
116-
* @dead - This device is currently either in the process of or has been
117-
* removed from the system. Any asynchronous events scheduled for this
118-
* device should exit without taking any action.
102+
* struct device_private - structure to hold the private to the driver core
103+
* portions of the device structure.
104+
* @klist_children: klist containing all children of this device
105+
* @knode_parent: node in sibling list
106+
* @knode_driver: node in driver list
107+
* @knode_bus: node in bus list
108+
* @knode_class: node in class list
109+
* @deferred_probe: entry in deferred_probe_list which is used to retry the
110+
* binding of drivers which were unable to get all the
111+
* resources needed by the device; typically because it depends
112+
* on another driver getting probed first.
113+
* @async_driver: pointer to device driver awaiting probe via async_probe
114+
* @deferred_probe_reason: capture the -EPROBE_DEFER message emitted with
115+
* dev_err_probe() for later retrieval via debugfs
116+
* @device: pointer back to the struct device that this structure is
117+
* associated with.
118+
* @driver_type: The type of the bound Rust driver.
119+
* @dead: This device is currently either in the process of or has been
120+
* removed from the system. Any asynchronous events scheduled for this
121+
* device should exit without taking any action.
119122
*
120123
* Nothing outside of the driver core should ever touch these fields.
121124
*/
@@ -213,6 +216,24 @@ static inline void device_set_driver(struct device *dev, const struct device_dri
213216
WRITE_ONCE(dev->driver, (struct device_driver *)drv);
214217
}
215218

219+
struct devres_node;
220+
typedef void (*dr_node_release_t)(struct device *dev, struct devres_node *node);
221+
typedef void (*dr_node_free_t)(struct devres_node *node);
222+
223+
struct devres_node {
224+
struct list_head entry;
225+
dr_node_release_t release;
226+
dr_node_free_t free_node;
227+
const char *name;
228+
size_t size;
229+
};
230+
231+
void devres_node_init(struct devres_node *node, dr_node_release_t release,
232+
dr_node_free_t free_node);
233+
void devres_node_add(struct device *dev, struct devres_node *node);
234+
bool devres_node_remove(struct device *dev, struct devres_node *node);
235+
void devres_set_node_dbginfo(struct devres_node *node, const char *name,
236+
size_t size);
216237
void devres_for_each_res(struct device *dev, dr_release_t release,
217238
dr_match_t match, void *match_data,
218239
void (*fn)(struct device *, void *, void *),
@@ -291,6 +312,7 @@ static inline int devtmpfs_create_node(struct device *dev) { return 0; }
291312
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
292313
#endif
293314

315+
void software_node_init(void);
294316
void software_node_notify(struct device *dev);
295317
void software_node_notify_remove(struct device *dev);
296318

drivers/base/core.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode)
182182
if (fwnode->dev)
183183
return;
184184

185-
fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
185+
fwnode_set_flag(fwnode, FWNODE_FLAG_NOT_DEVICE);
186186
fwnode_links_purge_consumers(fwnode);
187187

188188
fwnode_for_each_available_child_node(fwnode, child)
@@ -228,7 +228,7 @@ static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode,
228228
if (fwnode->dev && fwnode->dev->bus)
229229
return;
230230

231-
fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
231+
fwnode_set_flag(fwnode, FWNODE_FLAG_NOT_DEVICE);
232232
__fwnode_links_move_consumers(fwnode, new_sup);
233233

234234
fwnode_for_each_available_child_node(fwnode, child)
@@ -1012,7 +1012,7 @@ static void device_links_missing_supplier(struct device *dev)
10121012
static bool dev_is_best_effort(struct device *dev)
10131013
{
10141014
return (fw_devlink_best_effort && dev->can_match) ||
1015-
(dev->fwnode && (dev->fwnode->flags & FWNODE_FLAG_BEST_EFFORT));
1015+
(dev->fwnode && fwnode_test_flag(dev->fwnode, FWNODE_FLAG_BEST_EFFORT));
10161016
}
10171017

10181018
static struct fwnode_handle *fwnode_links_check_suppliers(
@@ -1723,11 +1723,11 @@ bool fw_devlink_is_strict(void)
17231723

17241724
static void fw_devlink_parse_fwnode(struct fwnode_handle *fwnode)
17251725
{
1726-
if (fwnode->flags & FWNODE_FLAG_LINKS_ADDED)
1726+
if (fwnode_test_flag(fwnode, FWNODE_FLAG_LINKS_ADDED))
17271727
return;
17281728

17291729
fwnode_call_int_op(fwnode, add_links);
1730-
fwnode->flags |= FWNODE_FLAG_LINKS_ADDED;
1730+
fwnode_set_flag(fwnode, FWNODE_FLAG_LINKS_ADDED);
17311731
}
17321732

17331733
static void fw_devlink_parse_fwtree(struct fwnode_handle *fwnode)
@@ -1885,7 +1885,7 @@ static bool fwnode_init_without_drv(struct fwnode_handle *fwnode)
18851885
struct device *dev;
18861886
bool ret;
18871887

1888-
if (!(fwnode->flags & FWNODE_FLAG_INITIALIZED))
1888+
if (!fwnode_test_flag(fwnode, FWNODE_FLAG_INITIALIZED))
18891889
return false;
18901890

18911891
dev = get_dev_from_fwnode(fwnode);
@@ -2001,10 +2001,10 @@ static bool __fw_devlink_relax_cycles(struct fwnode_handle *con_handle,
20012001
* We aren't trying to find all cycles. Just a cycle between con and
20022002
* sup_handle.
20032003
*/
2004-
if (sup_handle->flags & FWNODE_FLAG_VISITED)
2004+
if (fwnode_test_flag(sup_handle, FWNODE_FLAG_VISITED))
20052005
return false;
20062006

2007-
sup_handle->flags |= FWNODE_FLAG_VISITED;
2007+
fwnode_set_flag(sup_handle, FWNODE_FLAG_VISITED);
20082008

20092009
/* Termination condition. */
20102010
if (sup_handle == con_handle) {
@@ -2074,7 +2074,7 @@ static bool __fw_devlink_relax_cycles(struct fwnode_handle *con_handle,
20742074
}
20752075

20762076
out:
2077-
sup_handle->flags &= ~FWNODE_FLAG_VISITED;
2077+
fwnode_clear_flag(sup_handle, FWNODE_FLAG_VISITED);
20782078
put_device(sup_dev);
20792079
put_device(con_dev);
20802080
put_device(par_dev);
@@ -2127,7 +2127,7 @@ static int fw_devlink_create_devlink(struct device *con,
21272127
* When such a flag is set, we can't create device links where P is the
21282128
* supplier of C as that would delay the probe of C.
21292129
*/
2130-
if (sup_handle->flags & FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD &&
2130+
if (fwnode_test_flag(sup_handle, FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD) &&
21312131
fwnode_is_ancestor_of(sup_handle, con->fwnode))
21322132
return -EINVAL;
21332133

@@ -2150,7 +2150,7 @@ static int fw_devlink_create_devlink(struct device *con,
21502150
else
21512151
flags = FW_DEVLINK_FLAGS_PERMISSIVE;
21522152

2153-
if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE)
2153+
if (fwnode_test_flag(sup_handle, FWNODE_FLAG_NOT_DEVICE))
21542154
sup_dev = fwnode_get_next_parent_dev(sup_handle);
21552155
else
21562156
sup_dev = get_dev_from_fwnode(sup_handle);
@@ -2162,7 +2162,7 @@ static int fw_devlink_create_devlink(struct device *con,
21622162
* supplier device indefinitely.
21632163
*/
21642164
if (sup_dev->links.status == DL_DEV_NO_DRIVER &&
2165-
sup_handle->flags & FWNODE_FLAG_INITIALIZED) {
2165+
fwnode_test_flag(sup_handle, FWNODE_FLAG_INITIALIZED)) {
21662166
dev_dbg(con,
21672167
"Not linking %pfwf - dev might never probe\n",
21682168
sup_handle);
@@ -2831,14 +2831,15 @@ static ssize_t removable_show(struct device *dev, struct device_attribute *attr,
28312831
}
28322832
static DEVICE_ATTR_RO(removable);
28332833

2834-
int device_add_groups(struct device *dev, const struct attribute_group **groups)
2834+
int device_add_groups(struct device *dev,
2835+
const struct attribute_group *const *groups)
28352836
{
28362837
return sysfs_create_groups(&dev->kobj, groups);
28372838
}
28382839
EXPORT_SYMBOL_GPL(device_add_groups);
28392840

28402841
void device_remove_groups(struct device *dev,
2841-
const struct attribute_group **groups)
2842+
const struct attribute_group *const *groups)
28422843
{
28432844
sysfs_remove_groups(&dev->kobj, groups);
28442845
}

drivers/base/dd.c

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,7 @@ static int deferred_devs_show(struct seq_file *s, void *data)
257257
}
258258
DEFINE_SHOW_ATTRIBUTE(deferred_devs);
259259

260-
#ifdef CONFIG_MODULES
261-
static int driver_deferred_probe_timeout = 10;
262-
#else
263-
static int driver_deferred_probe_timeout;
264-
#endif
260+
static int driver_deferred_probe_timeout = CONFIG_DRIVER_DEFERRED_PROBE_TIMEOUT;
265261

266262
static int __init deferred_probe_timeout_setup(char *str)
267263
{
@@ -383,8 +379,7 @@ __exitcall(deferred_probe_exit);
383379

384380
int __device_set_driver_override(struct device *dev, const char *s, size_t len)
385381
{
386-
const char *new, *old;
387-
char *cp;
382+
const char *new = NULL, *old;
388383

389384
if (!s)
390385
return -EINVAL;
@@ -404,37 +399,30 @@ int __device_set_driver_override(struct device *dev, const char *s, size_t len)
404399
*/
405400
len = strlen(s);
406401

407-
if (!len) {
408-
/* Empty string passed - clear override */
409-
spin_lock(&dev->driver_override.lock);
410-
old = dev->driver_override.name;
411-
dev->driver_override.name = NULL;
412-
spin_unlock(&dev->driver_override.lock);
413-
kfree(old);
402+
/* Handle trailing newline */
403+
if (len) {
404+
char *cp;
414405

415-
return 0;
406+
cp = strnchr(s, len, '\n');
407+
if (cp)
408+
len = cp - s;
416409
}
417410

418-
cp = strnchr(s, len, '\n');
419-
if (cp)
420-
len = cp - s;
421-
422-
new = kstrndup(s, len, GFP_KERNEL);
423-
if (!new)
424-
return -ENOMEM;
411+
/*
412+
* If empty string or "\n" passed, new remains NULL, clearing
413+
* the driver_override.name.
414+
*/
415+
if (len) {
416+
new = kstrndup(s, len, GFP_KERNEL);
417+
if (!new)
418+
return -ENOMEM;
419+
}
425420

426-
spin_lock(&dev->driver_override.lock);
427-
old = dev->driver_override.name;
428-
if (cp != s) {
421+
scoped_guard(spinlock, &dev->driver_override.lock) {
422+
old = dev->driver_override.name;
429423
dev->driver_override.name = new;
430-
spin_unlock(&dev->driver_override.lock);
431-
} else {
432-
/* "\n" passed - clear override */
433-
dev->driver_override.name = NULL;
434-
spin_unlock(&dev->driver_override.lock);
435-
436-
kfree(new);
437424
}
425+
438426
kfree(old);
439427

440428
return 0;

0 commit comments

Comments
 (0)