diff --git a/kernel-modules/intel-ice/centos/ice-kmod.spec b/kernel-modules/intel-ice/centos/ice-kmod.spec index abe5ca02..98df313d 100644 --- a/kernel-modules/intel-ice/centos/ice-kmod.spec +++ b/kernel-modules/intel-ice/centos/ice-kmod.spec @@ -69,8 +69,6 @@ source scl_source enable devtoolset-8 || : %endif %{__install} -d %{buildroot}/lib/modules/%{kversion}/extra/%{kmod_name}/ %{__install} src/%{kmod_name}.ko %{buildroot}/lib/modules/%{kversion}/extra/%{kmod_name}/ -# The auxiliary bus was introduced in kernel 5.11. Older kernels need the backported module of it. -%{__install} src/auxiliary.ko %{buildroot}/lib/modules/%{kversion}/extra/%{kmod_name}/ %{__install} -d %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/ %{__install} COPYING %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/ %{__install} pci.updates %{buildroot}%{_defaultdocdir}/kmod-%{kmod_name}-%{version}/ diff --git a/kernel-rt/centos/kernel-rt.spec b/kernel-rt/centos/kernel-rt.spec index a2231d09..88e0b50c 100644 --- a/kernel-rt/centos/kernel-rt.spec +++ b/kernel-rt/centos/kernel-rt.spec @@ -795,6 +795,15 @@ Patch15: 0016-Revert-commit-f049cf1a7b.patch Patch16: 0017-genirq-Export-affinity-setter-for-modules.patch Patch17: 0018-genirq-Provide-new-interfaces-for-affinity-hints.patch Patch18: 0019-ixgbe-Use-irq_update_affinity_hint.patch +Patch19: 0020-Add-auxiliary-bus-support.patch +Patch20: 0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch +Patch21: 0022-driver-core-auxiliary-bus-make-remove-function-retur.patch +Patch22: 0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch +Patch23: 0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch +Patch24: 0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch +Patch25: 0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch +Patch26: 0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch +Patch27: 0028-driver-core-auxiliary-bus-Enable-by-default.patch # END OF PATCH DEFINITIONS %endif diff --git a/kernel-rt/centos/patches/0020-Add-auxiliary-bus-support.patch b/kernel-rt/centos/patches/0020-Add-auxiliary-bus-support.patch new file mode 100644 index 00000000..f781be1c --- /dev/null +++ b/kernel-rt/centos/patches/0020-Add-auxiliary-bus-support.patch @@ -0,0 +1,743 @@ +From f7fadaaf14372fcc39555b1e3a1a0efa62472dfd Mon Sep 17 00:00:00 2001 +From: Dave Ertman +Date: Wed, 2 Dec 2020 16:54:24 -0800 +Subject: [PATCH] Add auxiliary bus support + +Add support for the Auxiliary Bus, auxiliary_device and auxiliary_driver. +It enables drivers to create an auxiliary_device and bind an +auxiliary_driver to it. + +The bus supports probe/remove shutdown and suspend/resume callbacks. +Each auxiliary_device has a unique string based id; driver binds to +an auxiliary_device based on this id through the bus. + +Co-developed-by: Kiran Patil +Co-developed-by: Ranjani Sridharan +Co-developed-by: Fred Oh +Co-developed-by: Leon Romanovsky +Signed-off-by: Kiran Patil +Signed-off-by: Ranjani Sridharan +Signed-off-by: Fred Oh +Signed-off-by: Leon Romanovsky +Signed-off-by: Dave Ertman +Reviewed-by: Pierre-Louis Bossart +Reviewed-by: Shiraz Saleem +Reviewed-by: Parav Pandit +Reviewed-by: Dan Williams +Reviewed-by: Martin Habets +Link: https://lore.kernel.org/r/20201113161859.1775473-2-david.m.ertman@intel.com +Signed-off-by: Dan Williams +Link: https://lore.kernel.org/r/160695681289.505290.8978295443574440604.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7de3697e9cbd4bd3d62bafa249d57990e1b8f294) +Signed-off-by: M. Vefa Bicakci +--- + Documentation/driver-api/auxiliary_bus.rst | 234 ++++++++++++++++++ + Documentation/driver-api/index.rst | 1 + + drivers/base/Kconfig | 3 + + drivers/base/Makefile | 1 + + drivers/base/auxiliary.c | 268 +++++++++++++++++++++ + include/linux/auxiliary_bus.h | 78 ++++++ + include/linux/mod_devicetable.h | 8 + + scripts/mod/devicetable-offsets.c | 3 + + scripts/mod/file2alias.c | 8 + + 9 files changed, 604 insertions(+) + create mode 100644 Documentation/driver-api/auxiliary_bus.rst + create mode 100644 drivers/base/auxiliary.c + create mode 100644 include/linux/auxiliary_bus.h + +diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst +new file mode 100644 +index 000000000000..5dd7804631ef +--- /dev/null ++++ b/Documentation/driver-api/auxiliary_bus.rst +@@ -0,0 +1,234 @@ ++.. SPDX-License-Identifier: GPL-2.0-only ++ ++============= ++Auxiliary Bus ++============= ++ ++In some subsystems, the functionality of the core device (PCI/ACPI/other) is ++too complex for a single device to be managed by a monolithic driver ++(e.g. Sound Open Firmware), multiple devices might implement a common ++intersection of functionality (e.g. NICs + RDMA), or a driver may want to ++export an interface for another subsystem to drive (e.g. SIOV Physical Function ++export Virtual Function management). A split of the functinoality into child- ++devices representing sub-domains of functionality makes it possible to ++compartmentalize, layer, and distribute domain-specific concerns via a Linux ++device-driver model. ++ ++An example for this kind of requirement is the audio subsystem where a single ++IP is handling multiple entities such as HDMI, Soundwire, local devices such as ++mics/speakers etc. The split for the core's functionality can be arbitrary or ++be defined by the DSP firmware topology and include hooks for test/debug. This ++allows for the audio core device to be minimal and focused on hardware-specific ++control and communication. ++ ++Each auxiliary_device represents a part of its parent functionality. The ++generic behavior can be extended and specialized as needed by encapsulating an ++auxiliary_device within other domain-specific structures and the use of .ops ++callbacks. Devices on the auxiliary bus do not share any structures and the use ++of a communication channel with the parent is domain-specific. ++ ++Note that ops are intended as a way to augment instance behavior within a class ++of auxiliary devices, it is not the mechanism for exporting common ++infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey ++infrastructure from the parent module to the auxiliary module(s). ++ ++ ++When Should the Auxiliary Bus Be Used ++===================================== ++ ++The auxiliary bus is to be used when a driver and one or more kernel modules, ++who share a common header file with the driver, need a mechanism to connect and ++provide access to a shared object allocated by the auxiliary_device's ++registering driver. The registering driver for the auxiliary_device(s) and the ++kernel module(s) registering auxiliary_drivers can be from the same subsystem, ++or from multiple subsystems. ++ ++The emphasis here is on a common generic interface that keeps subsystem ++customization out of the bus infrastructure. ++ ++One example is a PCI network device that is RDMA-capable and exports a child ++device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI ++driver allocates and registers an auxiliary_device for each physical ++function on the NIC. The RDMA driver registers an auxiliary_driver that claims ++each of these auxiliary_devices. This conveys data/ops published by the parent ++PCI device/driver to the RDMA auxiliary_driver. ++ ++Another use case is for the PCI device to be split out into multiple sub ++functions. For each sub function an auxiliary_device is created. A PCI sub ++function driver binds to such devices that creates its own one or more class ++devices. A PCI sub function auxiliary device is likely to be contained in a ++struct with additional attributes such as user defined sub function number and ++optional attributes such as resources and a link to the parent device. These ++attributes could be used by systemd/udev; and hence should be initialized ++before a driver binds to an auxiliary_device. ++ ++A key requirement for utilizing the auxiliary bus is that there is no ++dependency on a physical bus, device, register accesses or regmap support. ++These individual devices split from the core cannot live on the platform bus as ++they are not physical devices that are controlled by DT/ACPI. The same ++argument applies for not using MFD in this scenario as MFD relies on individual ++function devices being physical devices. ++ ++Auxiliary Device ++================ ++ ++An auxiliary_device represents a part of its parent device's functionality. It ++is given a name that, combined with the registering drivers KBUILD_MODNAME, ++creates a match_name that is used for driver binding, and an id that combined ++with the match_name provide a unique name to register with the bus subsystem. ++ ++Registering an auxiliary_device is a two-step process. First call ++auxiliary_device_init(), which checks several aspects of the auxiliary_device ++struct and performs a device_initialize(). After this step completes, any ++error state must have a call to auxiliary_device_uninit() in its resolution path. ++The second step in registering an auxiliary_device is to perform a call to ++auxiliary_device_add(), which sets the name of the device and add the device to ++the bus. ++ ++Unregistering an auxiliary_device is also a two-step process to mirror the ++register process. First call auxiliary_device_delete(), then call ++auxiliary_device_uninit(). ++ ++.. code-block:: c ++ ++ struct auxiliary_device { ++ struct device dev; ++ const char *name; ++ u32 id; ++ }; ++ ++If two auxiliary_devices both with a match_name "mod.foo" are registered onto ++the bus, they must have unique id values (e.g. "x" and "y") so that the ++registered devices names are "mod.foo.x" and "mod.foo.y". If match_name + id ++are not unique, then the device_add fails and generates an error message. ++ ++The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be ++populated with a non-NULL pointer to successfully register the auxiliary_device. ++ ++The auxiliary_device.dev.parent must also be populated. ++ ++Auxiliary Device Memory Model and Lifespan ++------------------------------------------ ++ ++The registering driver is the entity that allocates memory for the ++auxiliary_device and register it on the auxiliary bus. It is important to note ++that, as opposed to the platform bus, the registering driver is wholly ++responsible for the management for the memory used for the driver object. ++ ++A parent object, defined in the shared header file, contains the ++auxiliary_device. It also contains a pointer to the shared object(s), which ++also is defined in the shared header. Both the parent object and the shared ++object(s) are allocated by the registering driver. This layout allows the ++auxiliary_driver's registering module to perform a container_of() call to go ++from the pointer to the auxiliary_device, that is passed during the call to the ++auxiliary_driver's probe function, up to the parent object, and then have ++access to the shared object(s). ++ ++The memory for the auxiliary_device is freed only in its release() callback ++flow as defined by its registering driver. ++ ++The memory for the shared object(s) must have a lifespan equal to, or greater ++than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver ++should only consider that this shared object is valid as long as the ++auxiliary_device is still registered on the auxiliary bus. It is up to the ++registering driver to manage (e.g. free or keep available) the memory for the ++shared object beyond the life of the auxiliary_device. ++ ++The registering driver must unregister all auxiliary devices before its own ++driver.remove() is completed. ++ ++Auxiliary Drivers ++================= ++ ++Auxiliary drivers follow the standard driver model convention, where ++discovery/enumeration is handled by the core, and drivers ++provide probe() and remove() methods. They support power management ++and shutdown notifications using the standard conventions. ++ ++.. code-block:: c ++ ++ struct auxiliary_driver { ++ int (*probe)(struct auxiliary_device *, ++ const struct auxiliary_device_id *id); ++ int (*remove)(struct auxiliary_device *); ++ void (*shutdown)(struct auxiliary_device *); ++ int (*suspend)(struct auxiliary_device *, pm_message_t); ++ int (*resume)(struct auxiliary_device *); ++ struct device_driver driver; ++ const struct auxiliary_device_id *id_table; ++ }; ++ ++Auxiliary drivers register themselves with the bus by calling ++auxiliary_driver_register(). The id_table contains the match_names of auxiliary ++devices that a driver can bind with. ++ ++Example Usage ++============= ++ ++Auxiliary devices are created and registered by a subsystem-level core device ++that needs to break up its functionality into smaller fragments. One way to ++extend the scope of an auxiliary_device is to encapsulate it within a domain- ++pecific structure defined by the parent device. This structure contains the ++auxiliary_device and any associated shared data/callbacks needed to establish ++the connection with the parent. ++ ++An example is: ++ ++.. code-block:: c ++ ++ struct foo { ++ struct auxiliary_device auxdev; ++ void (*connect)(struct auxiliary_device *auxdev); ++ void (*disconnect)(struct auxiliary_device *auxdev); ++ void *data; ++ }; ++ ++The parent device then registers the auxiliary_device by calling ++auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to ++the auxdev member of the above structure. The parent provides a name for the ++auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a ++match_name that is be used for matching and binding with a driver. ++ ++Whenever an auxiliary_driver is registered, based on the match_name, the ++auxiliary_driver's probe() is invoked for the matching devices. The ++auxiliary_driver can also be encapsulated inside custom drivers that make the ++core device's functionality extensible by adding additional domain-specific ops ++as follows: ++ ++.. code-block:: c ++ ++ struct my_ops { ++ void (*send)(struct auxiliary_device *auxdev); ++ void (*receive)(struct auxiliary_device *auxdev); ++ }; ++ ++ ++ struct my_driver { ++ struct auxiliary_driver auxiliary_drv; ++ const struct my_ops ops; ++ }; ++ ++An example of this type of usage is: ++ ++.. code-block:: c ++ ++ const struct auxiliary_device_id my_auxiliary_id_table[] = { ++ { .name = "foo_mod.foo_dev" }, ++ { }, ++ }; ++ ++ const struct my_ops my_custom_ops = { ++ .send = my_tx, ++ .receive = my_rx, ++ }; ++ ++ const struct my_driver my_drv = { ++ .auxiliary_drv = { ++ .name = "myauxiliarydrv", ++ .id_table = my_auxiliary_id_table, ++ .probe = my_probe, ++ .remove = my_remove, ++ .shutdown = my_shutdown, ++ }, ++ .ops = my_custom_ops, ++ }; +diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst +index f357f3eb400c..86759a74b7f1 100644 +--- a/Documentation/driver-api/index.rst ++++ b/Documentation/driver-api/index.rst +@@ -72,6 +72,7 @@ available subsections can be seen below. + thermal/index + fpga/index + acpi/index ++ auxiliary_bus + backlight/lp855x-driver.rst + connector + console +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 8d7001712062..040be48ce046 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -1,6 +1,9 @@ + # SPDX-License-Identifier: GPL-2.0 + menu "Generic Driver Options" + ++config AUXILIARY_BUS ++ bool ++ + config UEVENT_HELPER + bool "Support for uevent helper" + help +diff --git a/drivers/base/Makefile b/drivers/base/Makefile +index 41369fc7004f..5e7bf9669a81 100644 +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -7,6 +7,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ + attribute_container.o transport_class.o \ + topology.o container.o property.o cacheinfo.o \ + swnode.o ++obj-$(CONFIG_AUXILIARY_BUS) += auxiliary.o + obj-$(CONFIG_DEVTMPFS) += devtmpfs.o + obj-y += power/ + obj-$(CONFIG_ISA_BUS_API) += isa.o +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +new file mode 100644 +index 000000000000..ef2af417438b +--- /dev/null ++++ b/drivers/base/auxiliary.c +@@ -0,0 +1,268 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2019-2020 Intel Corporation ++ * ++ * Please see Documentation/driver-api/auxiliary_bus.rst for more information. ++ */ ++ ++#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, ++ const struct auxiliary_device *auxdev) ++{ ++ for (; id->name[0]; id++) { ++ const char *p = strrchr(dev_name(&auxdev->dev), '.'); ++ int match_size; ++ ++ if (!p) ++ continue; ++ match_size = p - dev_name(&auxdev->dev); ++ ++ /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ ++ if (strlen(id->name) == match_size && ++ !strncmp(dev_name(&auxdev->dev), id->name, match_size)) ++ return id; ++ } ++ return NULL; ++} ++ ++static int auxiliary_match(struct device *dev, struct device_driver *drv) ++{ ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); ++ ++ return !!auxiliary_match_id(auxdrv->id_table, auxdev); ++} ++ ++static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) ++{ ++ const char *name, *p; ++ ++ name = dev_name(dev); ++ p = strrchr(name, '.'); ++ ++ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name), ++ name); ++} ++ ++static const struct dev_pm_ops auxiliary_dev_pm_ops = { ++ SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) ++ SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) ++}; ++ ++static int auxiliary_bus_probe(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ int ret; ++ ++ ret = dev_pm_domain_attach(dev, true); ++ if (ret) { ++ dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret); ++ return ret; ++ } ++ ++ ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev)); ++ if (ret) ++ dev_pm_domain_detach(dev, true); ++ ++ return ret; ++} ++ ++static int auxiliary_bus_remove(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ int ret = 0; ++ ++ if (auxdrv->remove) ++ ret = auxdrv->remove(auxdev); ++ dev_pm_domain_detach(dev, true); ++ ++ return ret; ++} ++ ++static void auxiliary_bus_shutdown(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ ++ if (auxdrv->shutdown) ++ auxdrv->shutdown(auxdev); ++} ++ ++static struct bus_type auxiliary_bus_type = { ++ .name = "auxiliary", ++ .probe = auxiliary_bus_probe, ++ .remove = auxiliary_bus_remove, ++ .shutdown = auxiliary_bus_shutdown, ++ .match = auxiliary_match, ++ .uevent = auxiliary_uevent, ++ .pm = &auxiliary_dev_pm_ops, ++}; ++ ++/** ++ * auxiliary_device_init - check auxiliary_device and initialize ++ * @auxdev: auxiliary device struct ++ * ++ * This is the first step in the two-step process to register an auxiliary_device. ++ * ++ * When this function returns an error code, then the device_initialize will *not* have ++ * been performed, and the caller will be responsible to free any memory allocated for the ++ * auxiliary_device in the error path directly. ++ * ++ * It returns 0 on success. On success, the device_initialize has been performed. After this ++ * point any error unwinding will need to include a call to auxiliary_device_uninit(). ++ * In this post-initialize error scenario, a call to the device's .release callback will be ++ * triggered, and all memory clean-up is expected to be handled there. ++ */ ++int auxiliary_device_init(struct auxiliary_device *auxdev) ++{ ++ struct device *dev = &auxdev->dev; ++ ++ if (!dev->parent) { ++ pr_err("auxiliary_device has a NULL dev->parent\n"); ++ return -EINVAL; ++ } ++ ++ if (!auxdev->name) { ++ pr_err("auxiliary_device has a NULL name\n"); ++ return -EINVAL; ++ } ++ ++ dev->bus = &auxiliary_bus_type; ++ device_initialize(&auxdev->dev); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(auxiliary_device_init); ++ ++/** ++ * __auxiliary_device_add - add an auxiliary bus device ++ * @auxdev: auxiliary bus device to add to the bus ++ * @modname: name of the parent device's driver module ++ * ++ * This is the second step in the two-step process to register an auxiliary_device. ++ * ++ * This function must be called after a successful call to auxiliary_device_init(), which ++ * will perform the device_initialize. This means that if this returns an error code, then a ++ * call to auxiliary_device_uninit() must be performed so that the .release callback will ++ * be triggered to free the memory associated with the auxiliary_device. ++ * ++ * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's ++ * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires ++ * a custom name would this version be called directly. ++ */ ++int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) ++{ ++ struct device *dev = &auxdev->dev; ++ int ret; ++ ++ if (!modname) { ++ pr_err("auxiliary device modname is NULL\n"); ++ return -EINVAL; ++ } ++ ++ ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); ++ if (ret) { ++ pr_err("auxiliary device dev_set_name failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = device_add(dev); ++ if (ret) ++ dev_err(dev, "adding auxiliary device failed!: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(__auxiliary_device_add); ++ ++/** ++ * auxiliary_find_device - auxiliary device iterator for locating a particular device. ++ * @start: Device to begin with ++ * @data: Data to pass to match function ++ * @match: Callback function to check device ++ * ++ * This function returns a reference to a device that is 'found' ++ * for later use, as determined by the @match callback. ++ * ++ * The callback should return 0 if the device doesn't match and non-zero ++ * if it does. If the callback returns non-zero, this function will ++ * return to the caller and not iterate over any more devices. ++ */ ++struct auxiliary_device * ++auxiliary_find_device(struct device *start, const void *data, ++ int (*match)(struct device *dev, const void *data)) ++{ ++ struct device *dev; ++ ++ dev = bus_find_device(&auxiliary_bus_type, start, data, match); ++ if (!dev) ++ return NULL; ++ ++ return to_auxiliary_dev(dev); ++} ++EXPORT_SYMBOL_GPL(auxiliary_find_device); ++ ++/** ++ * __auxiliary_driver_register - register a driver for auxiliary bus devices ++ * @auxdrv: auxiliary_driver structure ++ * @owner: owning module/driver ++ * @modname: KBUILD_MODNAME for parent driver ++ */ ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, ++ const char *modname) ++{ ++ if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) ++ return -EINVAL; ++ ++ if (auxdrv->name) ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name); ++ else ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); ++ if (!auxdrv->driver.name) ++ return -ENOMEM; ++ ++ auxdrv->driver.owner = owner; ++ auxdrv->driver.bus = &auxiliary_bus_type; ++ auxdrv->driver.mod_name = modname; ++ ++ return driver_register(&auxdrv->driver); ++} ++EXPORT_SYMBOL_GPL(__auxiliary_driver_register); ++ ++/** ++ * auxiliary_driver_unregister - unregister a driver ++ * @auxdrv: auxiliary_driver structure ++ */ ++void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) ++{ ++ driver_unregister(&auxdrv->driver); ++ kfree(auxdrv->driver.name); ++} ++EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); ++ ++static int __init auxiliary_bus_init(void) ++{ ++ return bus_register(&auxiliary_bus_type); ++} ++ ++static void __exit auxiliary_bus_exit(void) ++{ ++ bus_unregister(&auxiliary_bus_type); ++} ++ ++module_init(auxiliary_bus_init); ++module_exit(auxiliary_bus_exit); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Auxiliary Bus"); ++MODULE_AUTHOR("David Ertman "); ++MODULE_AUTHOR("Kiran Patil "); +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +new file mode 100644 +index 000000000000..282fbf7bf9af +--- /dev/null ++++ b/include/linux/auxiliary_bus.h +@@ -0,0 +1,78 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2019-2020 Intel Corporation ++ * ++ * Please see Documentation/driver-api/auxiliary_bus.rst for more information. ++ */ ++ ++#ifndef _AUXILIARY_BUS_H_ ++#define _AUXILIARY_BUS_H_ ++ ++#include ++#include ++#include ++ ++struct auxiliary_device { ++ struct device dev; ++ const char *name; ++ u32 id; ++}; ++ ++struct auxiliary_driver { ++ int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); ++ int (*remove)(struct auxiliary_device *auxdev); ++ void (*shutdown)(struct auxiliary_device *auxdev); ++ int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); ++ int (*resume)(struct auxiliary_device *auxdev); ++ const char *name; ++ struct device_driver driver; ++ const struct auxiliary_device_id *id_table; ++}; ++ ++static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev) ++{ ++ return container_of(dev, struct auxiliary_device, dev); ++} ++ ++static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv) ++{ ++ return container_of(drv, struct auxiliary_driver, driver); ++} ++ ++int auxiliary_device_init(struct auxiliary_device *auxdev); ++int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname); ++#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME) ++ ++static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev) ++{ ++ put_device(&auxdev->dev); ++} ++ ++static inline void auxiliary_device_delete(struct auxiliary_device *auxdev) ++{ ++ device_del(&auxdev->dev); ++} ++ ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, ++ const char *modname); ++#define auxiliary_driver_register(auxdrv) \ ++ __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME) ++ ++void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); ++ ++/** ++ * module_auxiliary_driver() - Helper macro for registering an auxiliary driver ++ * @__auxiliary_driver: auxiliary driver struct ++ * ++ * Helper macro for auxiliary drivers which do not do anything special in ++ * module init/exit. This eliminates a lot of boilerplate. Each module may only ++ * use this macro once, and calling it replaces module_init() and module_exit() ++ */ ++#define module_auxiliary_driver(__auxiliary_driver) \ ++ module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) ++ ++struct auxiliary_device * ++auxiliary_find_device(struct device *start, const void *data, ++ int (*match)(struct device *dev, const void *data)); ++ ++#endif /* _AUXILIARY_BUS_H_ */ +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index 5b08a473cdba..c425290b21e2 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -838,4 +838,12 @@ struct mhi_device_id { + kernel_ulong_t driver_data; + }; + ++#define AUXILIARY_NAME_SIZE 32 ++#define AUXILIARY_MODULE_PREFIX "auxiliary:" ++ ++struct auxiliary_device_id { ++ char name[AUXILIARY_NAME_SIZE]; ++ kernel_ulong_t driver_data; ++}; ++ + #endif /* LINUX_MOD_DEVICETABLE_H */ +diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c +index 27007c18e754..e377f52dbfa3 100644 +--- a/scripts/mod/devicetable-offsets.c ++++ b/scripts/mod/devicetable-offsets.c +@@ -243,5 +243,8 @@ int main(void) + DEVID(mhi_device_id); + DEVID_FIELD(mhi_device_id, chan); + ++ DEVID(auxiliary_device_id); ++ DEVID_FIELD(auxiliary_device_id, name); ++ + return 0; + } +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 2417dd1dee33..fb4827027536 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -1364,6 +1364,13 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) + { + DEF_FIELD_ADDR(symval, mhi_device_id, chan); + sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); ++ return 1; ++} ++ ++static int do_auxiliary_entry(const char *filename, void *symval, char *alias) ++{ ++ DEF_FIELD_ADDR(symval, auxiliary_device_id, name); ++ sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); + + return 1; + } +@@ -1442,6 +1449,7 @@ static const struct devtable devtable[] = { + {"tee", SIZE_tee_client_device_id, do_tee_entry}, + {"wmi", SIZE_wmi_device_id, do_wmi_entry}, + {"mhi", SIZE_mhi_device_id, do_mhi_entry}, ++ {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, + }; + + /* Create MODULE_ALIAS() statements. +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch b/kernel-rt/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch new file mode 100644 index 00000000..3f65f9e7 --- /dev/null +++ b/kernel-rt/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch @@ -0,0 +1,54 @@ +From e691ecf482fc75f7ed09aac3fa58436b56d5393b Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:43:47 +0100 +Subject: [PATCH] driver core: auxiliary bus: move slab.h from include file + +No need to include slab.h in include/linux/auxiliary_bus.h, as it is not +needed there. Move it to drivers/base/auxiliary.c instead. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8og8xi3WkoYXet9@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7bbb79ff5f7499e0c5d65987458410e8099207d8) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 1 + + include/linux/auxiliary_bus.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index ef2af417438b..eca36d6284d0 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index 282fbf7bf9af..3580743d0e8d 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -10,7 +10,6 @@ + + #include + #include +-#include + + struct auxiliary_device { + struct device dev; +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch b/kernel-rt/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch new file mode 100644 index 00000000..d5ba51d4 --- /dev/null +++ b/kernel-rt/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch @@ -0,0 +1,79 @@ +From 3dd9d97b9329c10548b0376307bdda8e23310fa9 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:44:07 +0100 +Subject: [PATCH] driver core: auxiliary bus: make remove function return void + +There's an effort to move the remove() callback in the driver core to +not return an int, as nothing can be done if this function fails. To +make that effort easier, make the aux bus remove function void to start +with so that no users have to be changed sometime in the future. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8ohB1ks1NK7kPop@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 8142a46c50d2dd8160c42284e1044eed3bec0d18) +Signed-off-by: M. Vefa Bicakci +--- + Documentation/driver-api/auxiliary_bus.rst | 2 +- + drivers/base/auxiliary.c | 5 ++--- + include/linux/auxiliary_bus.h | 2 +- + 3 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst +index 5dd7804631ef..2312506b0674 100644 +--- a/Documentation/driver-api/auxiliary_bus.rst ++++ b/Documentation/driver-api/auxiliary_bus.rst +@@ -150,7 +150,7 @@ and shutdown notifications using the standard conventions. + struct auxiliary_driver { + int (*probe)(struct auxiliary_device *, + const struct auxiliary_device_id *id); +- int (*remove)(struct auxiliary_device *); ++ void (*remove)(struct auxiliary_device *); + void (*shutdown)(struct auxiliary_device *); + int (*suspend)(struct auxiliary_device *, pm_message_t); + int (*resume)(struct auxiliary_device *); +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index eca36d6284d0..c44e85802b43 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -82,13 +82,12 @@ static int auxiliary_bus_remove(struct device *dev) + { + struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); +- int ret = 0; + + if (auxdrv->remove) +- ret = auxdrv->remove(auxdev); ++ auxdrv->remove(auxdev); + dev_pm_domain_detach(dev, true); + +- return ret; ++ return 0; + } + + static void auxiliary_bus_shutdown(struct device *dev) +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index 3580743d0e8d..d67b17606210 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -19,7 +19,7 @@ struct auxiliary_device { + + struct auxiliary_driver { + int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); +- int (*remove)(struct auxiliary_device *auxdev); ++ void (*remove)(struct auxiliary_device *auxdev); + void (*shutdown)(struct auxiliary_device *auxdev); + int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); + int (*resume)(struct auxiliary_device *auxdev); +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch b/kernel-rt/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch new file mode 100644 index 00000000..8a6dc27c --- /dev/null +++ b/kernel-rt/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch @@ -0,0 +1,166 @@ +From 140f2cd50e9a10afcf10e76719d2810c6f8354a2 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:49:28 +0100 +Subject: [PATCH] driver core: auxiliary bus: minor coding style tweaks + +For some reason, the original aux bus patch had some really long lines +in a few places, probably due to it being a very long-lived patch in +development by many different people. Fix that up so that the two files +all have the same length lines and function formatting styles. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8oiSFTpYHw1xE/o@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 0d2bf11a6b3e275a526b8d42d8d4a3a6067cf953) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 58 +++++++++++++++++++---------------- + include/linux/auxiliary_bus.h | 6 ++-- + 2 files changed, 35 insertions(+), 29 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index c44e85802b43..f303daadf843 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -50,8 +50,8 @@ static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) + name = dev_name(dev); + p = strrchr(name, '.'); + +- return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name), +- name); ++ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, ++ (int)(p - name), name); + } + + static const struct dev_pm_ops auxiliary_dev_pm_ops = { +@@ -113,16 +113,18 @@ static struct bus_type auxiliary_bus_type = { + * auxiliary_device_init - check auxiliary_device and initialize + * @auxdev: auxiliary device struct + * +- * This is the first step in the two-step process to register an auxiliary_device. ++ * This is the first step in the two-step process to register an ++ * auxiliary_device. + * +- * When this function returns an error code, then the device_initialize will *not* have +- * been performed, and the caller will be responsible to free any memory allocated for the +- * auxiliary_device in the error path directly. ++ * When this function returns an error code, then the device_initialize will ++ * *not* have been performed, and the caller will be responsible to free any ++ * memory allocated for the auxiliary_device in the error path directly. + * +- * It returns 0 on success. On success, the device_initialize has been performed. After this +- * point any error unwinding will need to include a call to auxiliary_device_uninit(). +- * In this post-initialize error scenario, a call to the device's .release callback will be +- * triggered, and all memory clean-up is expected to be handled there. ++ * It returns 0 on success. On success, the device_initialize has been ++ * performed. After this point any error unwinding will need to include a call ++ * to auxiliary_device_uninit(). In this post-initialize error scenario, a call ++ * to the device's .release callback will be triggered, and all memory clean-up ++ * is expected to be handled there. + */ + int auxiliary_device_init(struct auxiliary_device *auxdev) + { +@@ -149,16 +151,19 @@ EXPORT_SYMBOL_GPL(auxiliary_device_init); + * @auxdev: auxiliary bus device to add to the bus + * @modname: name of the parent device's driver module + * +- * This is the second step in the two-step process to register an auxiliary_device. ++ * This is the second step in the two-step process to register an ++ * auxiliary_device. + * +- * This function must be called after a successful call to auxiliary_device_init(), which +- * will perform the device_initialize. This means that if this returns an error code, then a +- * call to auxiliary_device_uninit() must be performed so that the .release callback will +- * be triggered to free the memory associated with the auxiliary_device. ++ * This function must be called after a successful call to ++ * auxiliary_device_init(), which will perform the device_initialize. This ++ * means that if this returns an error code, then a call to ++ * auxiliary_device_uninit() must be performed so that the .release callback ++ * will be triggered to free the memory associated with the auxiliary_device. + * +- * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's +- * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires +- * a custom name would this version be called directly. ++ * The expectation is that users will call the "auxiliary_device_add" macro so ++ * that the caller's KBUILD_MODNAME is automatically inserted for the modname ++ * parameter. Only if a user requires a custom name would this version be ++ * called directly. + */ + int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) + { +@@ -166,13 +171,13 @@ int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) + int ret; + + if (!modname) { +- pr_err("auxiliary device modname is NULL\n"); ++ dev_err(dev, "auxiliary device modname is NULL\n"); + return -EINVAL; + } + + ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); + if (ret) { +- pr_err("auxiliary device dev_set_name failed: %d\n", ret); ++ dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret); + return ret; + } + +@@ -197,9 +202,9 @@ EXPORT_SYMBOL_GPL(__auxiliary_device_add); + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +-struct auxiliary_device * +-auxiliary_find_device(struct device *start, const void *data, +- int (*match)(struct device *dev, const void *data)) ++struct auxiliary_device *auxiliary_find_device(struct device *start, ++ const void *data, ++ int (*match)(struct device *dev, const void *data)) + { + struct device *dev; + +@@ -217,14 +222,15 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); + * @owner: owning module/driver + * @modname: KBUILD_MODNAME for parent driver + */ +-int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, +- const char *modname) ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, ++ struct module *owner, const char *modname) + { + if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) + return -EINVAL; + + if (auxdrv->name) +- auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name); ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, ++ auxdrv->name); + else + auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); + if (!auxdrv->driver.name) +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index d67b17606210..fc51d45f106b 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -70,8 +70,8 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); + #define module_auxiliary_driver(__auxiliary_driver) \ + module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) + +-struct auxiliary_device * +-auxiliary_find_device(struct device *start, const void *data, +- int (*match)(struct device *dev, const void *data)); ++struct auxiliary_device *auxiliary_find_device(struct device *start, ++ const void *data, ++ int (*match)(struct device *dev, const void *data)); + + #endif /* _AUXILIARY_BUS_H_ */ +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch b/kernel-rt/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch new file mode 100644 index 00000000..dbf5502f --- /dev/null +++ b/kernel-rt/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch @@ -0,0 +1,49 @@ +From fb056562367fc8e65b4b7c7a2e0fabf4543c3533 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Fri, 4 Dec 2020 09:46:49 -0700 +Subject: [PATCH] driver core: auxiliary bus: Fix auxiliary bus shutdown null + auxdrv ptr + +If the probe of the auxdrv failed, the device->driver is set to NULL. +During kernel shutdown, the bus shutdown will call auxdrv->shutdown and +cause an invalid ptr dereference. Add check to make sure device->driver is +not NULL before we proceed. + +Fixes: 7de3697e9cbd ("Add auxiliary bus support") +Cc: Dave Ertman +Signed-off-by: Dave Jiang +Reviewed-by: Dan Williams +Link: https://lore.kernel.org/r/160710040926.1889434.8840329810698403478.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 784b2c48ac12dcee27db001fb1a3c58c39380cb6) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index f303daadf843..8336535f1e11 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -92,10 +92,15 @@ static int auxiliary_bus_remove(struct device *dev) + + static void auxiliary_bus_shutdown(struct device *dev) + { +- struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); +- struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ struct auxiliary_driver *auxdrv = NULL; ++ struct auxiliary_device *auxdev; ++ ++ if (dev->driver) { ++ auxdrv = to_auxiliary_drv(dev->driver); ++ auxdev = to_auxiliary_dev(dev); ++ } + +- if (auxdrv->shutdown) ++ if (auxdrv && auxdrv->shutdown) + auxdrv->shutdown(auxdev); + } + +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch b/kernel-rt/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch new file mode 100644 index 00000000..5f32835a --- /dev/null +++ b/kernel-rt/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch @@ -0,0 +1,146 @@ +From 4e403070ed6ea6de90ef8e645dec23751018f504 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Wed, 10 Feb 2021 13:16:11 -0700 +Subject: [PATCH] driver core: auxiliary bus: Fix calling stage for auxiliary + bus init + +When the auxiliary device code is built into the kernel, it can be executed +before the auxiliary bus is registered. This causes bus->p to be not +allocated and triggers a NULL pointer dereference when the auxiliary bus +device gets added with bus_add_device(). Call the auxiliary_bus_init() +under driver_init() so the bus is initialized before devices. + +Below is the kernel splat for the bug: +[ 1.948215] BUG: kernel NULL pointer dereference, address: 0000000000000060 +[ 1.950670] #PF: supervisor read access in kernel mode +[ 1.950670] #PF: error_code(0x0000) - not-present page +[ 1.950670] PGD 0 +[ 1.950670] Oops: 0000 1 SMP NOPTI +[ 1.950670] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.0-intel-nextsvmtest+ #2205 +[ 1.950670] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 +[ 1.950670] RIP: 0010:bus_add_device+0x64/0x140 +[ 1.950670] Code: 00 49 8b 75 20 48 89 df e8 59 a1 ff ff 41 89 c4 85 c0 75 7b 48 8b 53 50 48 85 d2 75 03 48 8b 13 49 8b 85 a0 00 00 00 48 89 de <48> 8 +78 60 48 83 c7 18 e8 ef d9 a9 ff 41 89 c4 85 c0 75 45 48 8b +[ 1.950670] RSP: 0000:ff46032ac001baf8 EFLAGS: 00010246 +[ 1.950670] RAX: 0000000000000000 RBX: ff4597f7414aa680 RCX: 0000000000000000 +[ 1.950670] RDX: ff4597f74142bbc0 RSI: ff4597f7414aa680 RDI: ff4597f7414aa680 +[ 1.950670] RBP: ff46032ac001bb10 R08: 0000000000000044 R09: 0000000000000228 +[ 1.950670] R10: ff4597f741141b30 R11: ff4597f740182a90 R12: 0000000000000000 +[ 1.950670] R13: ffffffffa5e936c0 R14: 0000000000000000 R15: 0000000000000000 +[ 1.950670] FS: 0000000000000000(0000) GS:ff4597f7bba00000(0000) knlGS:0000000000000000 +[ 1.950670] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1.950670] CR2: 0000000000000060 CR3: 000000002140c001 CR4: 0000000000f71ef0 +[ 1.950670] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 1.950670] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +[ 1.950670] PKRU: 55555554 +[ 1.950670] Call Trace: +[ 1.950670] device_add+0x3ee/0x850 +[ 1.950670] __auxiliary_device_add+0x47/0x60 +[ 1.950670] idxd_pci_probe+0xf77/0x1180 +[ 1.950670] local_pci_probe+0x4a/0x90 +[ 1.950670] pci_device_probe+0xff/0x1b0 +[ 1.950670] really_probe+0x1cf/0x440 +[ 1.950670] ? rdinit_setup+0x31/0x31 +[ 1.950670] driver_probe_device+0xe8/0x150 +[ 1.950670] device_driver_attach+0x58/0x60 +[ 1.950670] __driver_attach+0x8f/0x150 +[ 1.950670] ? device_driver_attach+0x60/0x60 +[ 1.950670] ? device_driver_attach+0x60/0x60 +[ 1.950670] bus_for_each_dev+0x79/0xc0 +[ 1.950670] ? kmem_cache_alloc_trace+0x323/0x430 +[ 1.950670] driver_attach+0x1e/0x20 +[ 1.950670] bus_add_driver+0x154/0x1f0 +[ 1.950670] driver_register+0x70/0xc0 +[ 1.950670] __pci_register_driver+0x54/0x60 +[ 1.950670] idxd_init_module+0xe2/0xfc +[ 1.950670] ? idma64_platform_driver_init+0x19/0x19 +[ 1.950670] do_one_initcall+0x4a/0x1e0 +[ 1.950670] kernel_init_freeable+0x1fc/0x25c +[ 1.950670] ? rest_init+0xba/0xba +[ 1.950670] kernel_init+0xe/0x116 +[ 1.950670] ret_from_fork+0x1f/0x30 +[ 1.950670] Modules linked in: +[ 1.950670] CR2: 0000000000000060 +[ 1.950670] --[ end trace cd7d1b226d3ca901 ]-- + +Fixes: 7de3697e9cbd ("Add auxiliary bus support") +Reported-by: Jacob Pan +Reviewed-by: Dan Williams +Acked-by: Dave Ertman +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/20210210201611.1611074-1-dave.jiang@intel.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 471b12c43f376d5203dbff0e91316eea11f6f4df) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 13 +++---------- + drivers/base/base.h | 5 +++++ + drivers/base/init.c | 1 + + 3 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index 8336535f1e11..d8b314e7d0fd 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include "base.h" + + static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, + const struct auxiliary_device *auxdev) +@@ -260,19 +261,11 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) + } + EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); + +-static int __init auxiliary_bus_init(void) ++void __init auxiliary_bus_init(void) + { +- return bus_register(&auxiliary_bus_type); ++ WARN_ON(bus_register(&auxiliary_bus_type)); + } + +-static void __exit auxiliary_bus_exit(void) +-{ +- bus_unregister(&auxiliary_bus_type); +-} +- +-module_init(auxiliary_bus_init); +-module_exit(auxiliary_bus_exit); +- + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("Auxiliary Bus"); + MODULE_AUTHOR("David Ertman "); +diff --git a/drivers/base/base.h b/drivers/base/base.h +index 91cfb8405abd..7d97447460fa 100644 +--- a/drivers/base/base.h ++++ b/drivers/base/base.h +@@ -119,6 +119,11 @@ static inline int hypervisor_init(void) { return 0; } + extern int platform_bus_init(void); + extern void cpu_dev_init(void); + extern void container_dev_init(void); ++#ifdef CONFIG_AUXILIARY_BUS ++extern void auxiliary_bus_init(void); ++#else ++static inline void auxiliary_bus_init(void) { } ++#endif + + struct kobject *virtual_device_parent(struct device *dev); + +diff --git a/drivers/base/init.c b/drivers/base/init.c +index 908e6520e804..a9f57c22fb9e 100644 +--- a/drivers/base/init.c ++++ b/drivers/base/init.c +@@ -32,6 +32,7 @@ void __init driver_init(void) + */ + of_core_init(); + platform_bus_init(); ++ auxiliary_bus_init(); + cpu_dev_init(); + memory_dev_init(); + container_dev_init(); +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch b/kernel-rt/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch new file mode 100644 index 00000000..5d62f4d7 --- /dev/null +++ b/kernel-rt/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch @@ -0,0 +1,35 @@ +From 7739d61db7ae6d01e06f8fbc0feb089cebe84ebe Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Thu, 11 Feb 2021 13:21:29 -0700 +Subject: [PATCH] driver core: auxiliary bus: Remove unneeded module bits + +Remove module bits in the auxiliary bus code since the auxiliary bus +cannot be built as a module and the relevant code is not needed. + +Cc: Dave Ertman +Suggested-by: Greg Kroah-Hartman +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/161307488980.1896017.15627190714413338196.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit bbf44abeeabfe05a124535e6c3a9fd7d682d42bf) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index d8b314e7d0fd..adc199dfba3c 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -265,8 +265,3 @@ void __init auxiliary_bus_init(void) + { + WARN_ON(bus_register(&auxiliary_bus_type)); + } +- +-MODULE_LICENSE("GPL v2"); +-MODULE_DESCRIPTION("Auxiliary Bus"); +-MODULE_AUTHOR("David Ertman "); +-MODULE_AUTHOR("Kiran Patil "); +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch b/kernel-rt/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch new file mode 100644 index 00000000..58e76715 --- /dev/null +++ b/kernel-rt/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch @@ -0,0 +1,51 @@ +From e4a05ae5a0d7fdaf8cfe7080640ce4a6057277c4 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +Date: Tue, 13 Jul 2021 12:34:38 +0300 +Subject: [PATCH] driver core: auxiliary bus: Fix memory leak when + driver_register() fail + +If driver_register() returns with error we need to free the memory +allocated for auxdrv->driver.name before returning from +__auxiliary_driver_register() + +Fixes: 7de3697e9cbd4 ("Add auxiliary bus support") +Reviewed-by: Dan Williams +Cc: stable +Signed-off-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20210713093438.3173-1-peter.ujfalusi@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 4afa0c22eed33cfe0c590742387f0d16f32412f3) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index adc199dfba3c..6a30264ab2ba 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); + int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, + struct module *owner, const char *modname) + { ++ int ret; ++ + if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) + return -EINVAL; + +@@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, + auxdrv->driver.bus = &auxiliary_bus_type; + auxdrv->driver.mod_name = modname; + +- return driver_register(&auxdrv->driver); ++ ret = driver_register(&auxdrv->driver); ++ if (ret) ++ kfree(auxdrv->driver.name); ++ ++ return ret; + } + EXPORT_SYMBOL_GPL(__auxiliary_driver_register); + +-- +2.29.2 + diff --git a/kernel-rt/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch b/kernel-rt/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch new file mode 100644 index 00000000..48f603a1 --- /dev/null +++ b/kernel-rt/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch @@ -0,0 +1,38 @@ +From ccf9728c267d16dedb1b5d0ecd4518cac435fd02 Mon Sep 17 00:00:00 2001 +From: "M. Vefa Bicakci" +Date: Thu, 17 Feb 2022 14:17:58 -0500 +Subject: [PATCH] driver core: auxiliary bus: Enable by default + +This commit enables CONFIG_AUXILIARY_BUS by default. This is necessary, +because StarlingX does not enable any kernel modules that 'select' +CONFIG_AUXILIARY_BUS, which causes the kernel's build system to +automatically disable this option. + +However, StarlingX has out-of-tree users of this functionality (such as +the 'ice' and 'mlnx-ofa_kernel' out-of-tree kernel driver packages), +hence the need for this change. Prior to this commit, the aforementioned +out-of-tree kernel drivers would use their embedded/bundled copy of the +same functionality, which would cause kernel symbol conflicts at +run-time when users attempted to load both ice and mlnx-ofa_kernel +drivers. + +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 040be48ce046..a18ec49b9dac 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -3,6 +3,7 @@ menu "Generic Driver Options" + + config AUXILIARY_BUS + bool ++ default y + + config UEVENT_HELPER + bool "Support for uevent helper" +-- +2.29.2 + diff --git a/kernel-std/centos/kernel.spec b/kernel-std/centos/kernel.spec index b0412ec5..ce27c42b 100644 --- a/kernel-std/centos/kernel.spec +++ b/kernel-std/centos/kernel.spec @@ -828,6 +828,15 @@ Patch15: 0016-Revert-commit-f049cf1a7b.patch Patch16: 0017-genirq-Export-affinity-setter-for-modules.patch Patch17: 0018-genirq-Provide-new-interfaces-for-affinity-hints.patch Patch18: 0019-ixgbe-Use-irq_update_affinity_hint.patch +Patch19: 0020-Add-auxiliary-bus-support.patch +Patch20: 0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch +Patch21: 0022-driver-core-auxiliary-bus-make-remove-function-retur.patch +Patch22: 0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch +Patch23: 0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch +Patch24: 0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch +Patch25: 0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch +Patch26: 0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch +Patch27: 0028-driver-core-auxiliary-bus-Enable-by-default.patch # END OF PATCH DEFINITIONS %endif diff --git a/kernel-std/centos/patches/0020-Add-auxiliary-bus-support.patch b/kernel-std/centos/patches/0020-Add-auxiliary-bus-support.patch new file mode 100644 index 00000000..b4a182e0 --- /dev/null +++ b/kernel-std/centos/patches/0020-Add-auxiliary-bus-support.patch @@ -0,0 +1,743 @@ +From a6492f505f12f830372636043098ad9dab3607d6 Mon Sep 17 00:00:00 2001 +From: Dave Ertman +Date: Wed, 2 Dec 2020 16:54:24 -0800 +Subject: [PATCH] Add auxiliary bus support + +Add support for the Auxiliary Bus, auxiliary_device and auxiliary_driver. +It enables drivers to create an auxiliary_device and bind an +auxiliary_driver to it. + +The bus supports probe/remove shutdown and suspend/resume callbacks. +Each auxiliary_device has a unique string based id; driver binds to +an auxiliary_device based on this id through the bus. + +Co-developed-by: Kiran Patil +Co-developed-by: Ranjani Sridharan +Co-developed-by: Fred Oh +Co-developed-by: Leon Romanovsky +Signed-off-by: Kiran Patil +Signed-off-by: Ranjani Sridharan +Signed-off-by: Fred Oh +Signed-off-by: Leon Romanovsky +Signed-off-by: Dave Ertman +Reviewed-by: Pierre-Louis Bossart +Reviewed-by: Shiraz Saleem +Reviewed-by: Parav Pandit +Reviewed-by: Dan Williams +Reviewed-by: Martin Habets +Link: https://lore.kernel.org/r/20201113161859.1775473-2-david.m.ertman@intel.com +Signed-off-by: Dan Williams +Link: https://lore.kernel.org/r/160695681289.505290.8978295443574440604.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7de3697e9cbd4bd3d62bafa249d57990e1b8f294) +Signed-off-by: M. Vefa Bicakci +--- + Documentation/driver-api/auxiliary_bus.rst | 234 ++++++++++++++++++ + Documentation/driver-api/index.rst | 1 + + drivers/base/Kconfig | 3 + + drivers/base/Makefile | 1 + + drivers/base/auxiliary.c | 268 +++++++++++++++++++++ + include/linux/auxiliary_bus.h | 78 ++++++ + include/linux/mod_devicetable.h | 8 + + scripts/mod/devicetable-offsets.c | 3 + + scripts/mod/file2alias.c | 8 + + 9 files changed, 604 insertions(+) + create mode 100644 Documentation/driver-api/auxiliary_bus.rst + create mode 100644 drivers/base/auxiliary.c + create mode 100644 include/linux/auxiliary_bus.h + +diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst +new file mode 100644 +index 000000000000..5dd7804631ef +--- /dev/null ++++ b/Documentation/driver-api/auxiliary_bus.rst +@@ -0,0 +1,234 @@ ++.. SPDX-License-Identifier: GPL-2.0-only ++ ++============= ++Auxiliary Bus ++============= ++ ++In some subsystems, the functionality of the core device (PCI/ACPI/other) is ++too complex for a single device to be managed by a monolithic driver ++(e.g. Sound Open Firmware), multiple devices might implement a common ++intersection of functionality (e.g. NICs + RDMA), or a driver may want to ++export an interface for another subsystem to drive (e.g. SIOV Physical Function ++export Virtual Function management). A split of the functinoality into child- ++devices representing sub-domains of functionality makes it possible to ++compartmentalize, layer, and distribute domain-specific concerns via a Linux ++device-driver model. ++ ++An example for this kind of requirement is the audio subsystem where a single ++IP is handling multiple entities such as HDMI, Soundwire, local devices such as ++mics/speakers etc. The split for the core's functionality can be arbitrary or ++be defined by the DSP firmware topology and include hooks for test/debug. This ++allows for the audio core device to be minimal and focused on hardware-specific ++control and communication. ++ ++Each auxiliary_device represents a part of its parent functionality. The ++generic behavior can be extended and specialized as needed by encapsulating an ++auxiliary_device within other domain-specific structures and the use of .ops ++callbacks. Devices on the auxiliary bus do not share any structures and the use ++of a communication channel with the parent is domain-specific. ++ ++Note that ops are intended as a way to augment instance behavior within a class ++of auxiliary devices, it is not the mechanism for exporting common ++infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey ++infrastructure from the parent module to the auxiliary module(s). ++ ++ ++When Should the Auxiliary Bus Be Used ++===================================== ++ ++The auxiliary bus is to be used when a driver and one or more kernel modules, ++who share a common header file with the driver, need a mechanism to connect and ++provide access to a shared object allocated by the auxiliary_device's ++registering driver. The registering driver for the auxiliary_device(s) and the ++kernel module(s) registering auxiliary_drivers can be from the same subsystem, ++or from multiple subsystems. ++ ++The emphasis here is on a common generic interface that keeps subsystem ++customization out of the bus infrastructure. ++ ++One example is a PCI network device that is RDMA-capable and exports a child ++device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI ++driver allocates and registers an auxiliary_device for each physical ++function on the NIC. The RDMA driver registers an auxiliary_driver that claims ++each of these auxiliary_devices. This conveys data/ops published by the parent ++PCI device/driver to the RDMA auxiliary_driver. ++ ++Another use case is for the PCI device to be split out into multiple sub ++functions. For each sub function an auxiliary_device is created. A PCI sub ++function driver binds to such devices that creates its own one or more class ++devices. A PCI sub function auxiliary device is likely to be contained in a ++struct with additional attributes such as user defined sub function number and ++optional attributes such as resources and a link to the parent device. These ++attributes could be used by systemd/udev; and hence should be initialized ++before a driver binds to an auxiliary_device. ++ ++A key requirement for utilizing the auxiliary bus is that there is no ++dependency on a physical bus, device, register accesses or regmap support. ++These individual devices split from the core cannot live on the platform bus as ++they are not physical devices that are controlled by DT/ACPI. The same ++argument applies for not using MFD in this scenario as MFD relies on individual ++function devices being physical devices. ++ ++Auxiliary Device ++================ ++ ++An auxiliary_device represents a part of its parent device's functionality. It ++is given a name that, combined with the registering drivers KBUILD_MODNAME, ++creates a match_name that is used for driver binding, and an id that combined ++with the match_name provide a unique name to register with the bus subsystem. ++ ++Registering an auxiliary_device is a two-step process. First call ++auxiliary_device_init(), which checks several aspects of the auxiliary_device ++struct and performs a device_initialize(). After this step completes, any ++error state must have a call to auxiliary_device_uninit() in its resolution path. ++The second step in registering an auxiliary_device is to perform a call to ++auxiliary_device_add(), which sets the name of the device and add the device to ++the bus. ++ ++Unregistering an auxiliary_device is also a two-step process to mirror the ++register process. First call auxiliary_device_delete(), then call ++auxiliary_device_uninit(). ++ ++.. code-block:: c ++ ++ struct auxiliary_device { ++ struct device dev; ++ const char *name; ++ u32 id; ++ }; ++ ++If two auxiliary_devices both with a match_name "mod.foo" are registered onto ++the bus, they must have unique id values (e.g. "x" and "y") so that the ++registered devices names are "mod.foo.x" and "mod.foo.y". If match_name + id ++are not unique, then the device_add fails and generates an error message. ++ ++The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be ++populated with a non-NULL pointer to successfully register the auxiliary_device. ++ ++The auxiliary_device.dev.parent must also be populated. ++ ++Auxiliary Device Memory Model and Lifespan ++------------------------------------------ ++ ++The registering driver is the entity that allocates memory for the ++auxiliary_device and register it on the auxiliary bus. It is important to note ++that, as opposed to the platform bus, the registering driver is wholly ++responsible for the management for the memory used for the driver object. ++ ++A parent object, defined in the shared header file, contains the ++auxiliary_device. It also contains a pointer to the shared object(s), which ++also is defined in the shared header. Both the parent object and the shared ++object(s) are allocated by the registering driver. This layout allows the ++auxiliary_driver's registering module to perform a container_of() call to go ++from the pointer to the auxiliary_device, that is passed during the call to the ++auxiliary_driver's probe function, up to the parent object, and then have ++access to the shared object(s). ++ ++The memory for the auxiliary_device is freed only in its release() callback ++flow as defined by its registering driver. ++ ++The memory for the shared object(s) must have a lifespan equal to, or greater ++than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver ++should only consider that this shared object is valid as long as the ++auxiliary_device is still registered on the auxiliary bus. It is up to the ++registering driver to manage (e.g. free or keep available) the memory for the ++shared object beyond the life of the auxiliary_device. ++ ++The registering driver must unregister all auxiliary devices before its own ++driver.remove() is completed. ++ ++Auxiliary Drivers ++================= ++ ++Auxiliary drivers follow the standard driver model convention, where ++discovery/enumeration is handled by the core, and drivers ++provide probe() and remove() methods. They support power management ++and shutdown notifications using the standard conventions. ++ ++.. code-block:: c ++ ++ struct auxiliary_driver { ++ int (*probe)(struct auxiliary_device *, ++ const struct auxiliary_device_id *id); ++ int (*remove)(struct auxiliary_device *); ++ void (*shutdown)(struct auxiliary_device *); ++ int (*suspend)(struct auxiliary_device *, pm_message_t); ++ int (*resume)(struct auxiliary_device *); ++ struct device_driver driver; ++ const struct auxiliary_device_id *id_table; ++ }; ++ ++Auxiliary drivers register themselves with the bus by calling ++auxiliary_driver_register(). The id_table contains the match_names of auxiliary ++devices that a driver can bind with. ++ ++Example Usage ++============= ++ ++Auxiliary devices are created and registered by a subsystem-level core device ++that needs to break up its functionality into smaller fragments. One way to ++extend the scope of an auxiliary_device is to encapsulate it within a domain- ++pecific structure defined by the parent device. This structure contains the ++auxiliary_device and any associated shared data/callbacks needed to establish ++the connection with the parent. ++ ++An example is: ++ ++.. code-block:: c ++ ++ struct foo { ++ struct auxiliary_device auxdev; ++ void (*connect)(struct auxiliary_device *auxdev); ++ void (*disconnect)(struct auxiliary_device *auxdev); ++ void *data; ++ }; ++ ++The parent device then registers the auxiliary_device by calling ++auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to ++the auxdev member of the above structure. The parent provides a name for the ++auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a ++match_name that is be used for matching and binding with a driver. ++ ++Whenever an auxiliary_driver is registered, based on the match_name, the ++auxiliary_driver's probe() is invoked for the matching devices. The ++auxiliary_driver can also be encapsulated inside custom drivers that make the ++core device's functionality extensible by adding additional domain-specific ops ++as follows: ++ ++.. code-block:: c ++ ++ struct my_ops { ++ void (*send)(struct auxiliary_device *auxdev); ++ void (*receive)(struct auxiliary_device *auxdev); ++ }; ++ ++ ++ struct my_driver { ++ struct auxiliary_driver auxiliary_drv; ++ const struct my_ops ops; ++ }; ++ ++An example of this type of usage is: ++ ++.. code-block:: c ++ ++ const struct auxiliary_device_id my_auxiliary_id_table[] = { ++ { .name = "foo_mod.foo_dev" }, ++ { }, ++ }; ++ ++ const struct my_ops my_custom_ops = { ++ .send = my_tx, ++ .receive = my_rx, ++ }; ++ ++ const struct my_driver my_drv = { ++ .auxiliary_drv = { ++ .name = "myauxiliarydrv", ++ .id_table = my_auxiliary_id_table, ++ .probe = my_probe, ++ .remove = my_remove, ++ .shutdown = my_shutdown, ++ }, ++ .ops = my_custom_ops, ++ }; +diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst +index f357f3eb400c..86759a74b7f1 100644 +--- a/Documentation/driver-api/index.rst ++++ b/Documentation/driver-api/index.rst +@@ -72,6 +72,7 @@ available subsections can be seen below. + thermal/index + fpga/index + acpi/index ++ auxiliary_bus + backlight/lp855x-driver.rst + connector + console +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 8d7001712062..040be48ce046 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -1,6 +1,9 @@ + # SPDX-License-Identifier: GPL-2.0 + menu "Generic Driver Options" + ++config AUXILIARY_BUS ++ bool ++ + config UEVENT_HELPER + bool "Support for uevent helper" + help +diff --git a/drivers/base/Makefile b/drivers/base/Makefile +index 41369fc7004f..5e7bf9669a81 100644 +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -7,6 +7,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ + attribute_container.o transport_class.o \ + topology.o container.o property.o cacheinfo.o \ + swnode.o ++obj-$(CONFIG_AUXILIARY_BUS) += auxiliary.o + obj-$(CONFIG_DEVTMPFS) += devtmpfs.o + obj-y += power/ + obj-$(CONFIG_ISA_BUS_API) += isa.o +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +new file mode 100644 +index 000000000000..ef2af417438b +--- /dev/null ++++ b/drivers/base/auxiliary.c +@@ -0,0 +1,268 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2019-2020 Intel Corporation ++ * ++ * Please see Documentation/driver-api/auxiliary_bus.rst for more information. ++ */ ++ ++#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, ++ const struct auxiliary_device *auxdev) ++{ ++ for (; id->name[0]; id++) { ++ const char *p = strrchr(dev_name(&auxdev->dev), '.'); ++ int match_size; ++ ++ if (!p) ++ continue; ++ match_size = p - dev_name(&auxdev->dev); ++ ++ /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ ++ if (strlen(id->name) == match_size && ++ !strncmp(dev_name(&auxdev->dev), id->name, match_size)) ++ return id; ++ } ++ return NULL; ++} ++ ++static int auxiliary_match(struct device *dev, struct device_driver *drv) ++{ ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); ++ ++ return !!auxiliary_match_id(auxdrv->id_table, auxdev); ++} ++ ++static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) ++{ ++ const char *name, *p; ++ ++ name = dev_name(dev); ++ p = strrchr(name, '.'); ++ ++ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name), ++ name); ++} ++ ++static const struct dev_pm_ops auxiliary_dev_pm_ops = { ++ SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) ++ SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) ++}; ++ ++static int auxiliary_bus_probe(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ int ret; ++ ++ ret = dev_pm_domain_attach(dev, true); ++ if (ret) { ++ dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret); ++ return ret; ++ } ++ ++ ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev)); ++ if (ret) ++ dev_pm_domain_detach(dev, true); ++ ++ return ret; ++} ++ ++static int auxiliary_bus_remove(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ int ret = 0; ++ ++ if (auxdrv->remove) ++ ret = auxdrv->remove(auxdev); ++ dev_pm_domain_detach(dev, true); ++ ++ return ret; ++} ++ ++static void auxiliary_bus_shutdown(struct device *dev) ++{ ++ struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); ++ struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ ++ if (auxdrv->shutdown) ++ auxdrv->shutdown(auxdev); ++} ++ ++static struct bus_type auxiliary_bus_type = { ++ .name = "auxiliary", ++ .probe = auxiliary_bus_probe, ++ .remove = auxiliary_bus_remove, ++ .shutdown = auxiliary_bus_shutdown, ++ .match = auxiliary_match, ++ .uevent = auxiliary_uevent, ++ .pm = &auxiliary_dev_pm_ops, ++}; ++ ++/** ++ * auxiliary_device_init - check auxiliary_device and initialize ++ * @auxdev: auxiliary device struct ++ * ++ * This is the first step in the two-step process to register an auxiliary_device. ++ * ++ * When this function returns an error code, then the device_initialize will *not* have ++ * been performed, and the caller will be responsible to free any memory allocated for the ++ * auxiliary_device in the error path directly. ++ * ++ * It returns 0 on success. On success, the device_initialize has been performed. After this ++ * point any error unwinding will need to include a call to auxiliary_device_uninit(). ++ * In this post-initialize error scenario, a call to the device's .release callback will be ++ * triggered, and all memory clean-up is expected to be handled there. ++ */ ++int auxiliary_device_init(struct auxiliary_device *auxdev) ++{ ++ struct device *dev = &auxdev->dev; ++ ++ if (!dev->parent) { ++ pr_err("auxiliary_device has a NULL dev->parent\n"); ++ return -EINVAL; ++ } ++ ++ if (!auxdev->name) { ++ pr_err("auxiliary_device has a NULL name\n"); ++ return -EINVAL; ++ } ++ ++ dev->bus = &auxiliary_bus_type; ++ device_initialize(&auxdev->dev); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(auxiliary_device_init); ++ ++/** ++ * __auxiliary_device_add - add an auxiliary bus device ++ * @auxdev: auxiliary bus device to add to the bus ++ * @modname: name of the parent device's driver module ++ * ++ * This is the second step in the two-step process to register an auxiliary_device. ++ * ++ * This function must be called after a successful call to auxiliary_device_init(), which ++ * will perform the device_initialize. This means that if this returns an error code, then a ++ * call to auxiliary_device_uninit() must be performed so that the .release callback will ++ * be triggered to free the memory associated with the auxiliary_device. ++ * ++ * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's ++ * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires ++ * a custom name would this version be called directly. ++ */ ++int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) ++{ ++ struct device *dev = &auxdev->dev; ++ int ret; ++ ++ if (!modname) { ++ pr_err("auxiliary device modname is NULL\n"); ++ return -EINVAL; ++ } ++ ++ ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); ++ if (ret) { ++ pr_err("auxiliary device dev_set_name failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = device_add(dev); ++ if (ret) ++ dev_err(dev, "adding auxiliary device failed!: %d\n", ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(__auxiliary_device_add); ++ ++/** ++ * auxiliary_find_device - auxiliary device iterator for locating a particular device. ++ * @start: Device to begin with ++ * @data: Data to pass to match function ++ * @match: Callback function to check device ++ * ++ * This function returns a reference to a device that is 'found' ++ * for later use, as determined by the @match callback. ++ * ++ * The callback should return 0 if the device doesn't match and non-zero ++ * if it does. If the callback returns non-zero, this function will ++ * return to the caller and not iterate over any more devices. ++ */ ++struct auxiliary_device * ++auxiliary_find_device(struct device *start, const void *data, ++ int (*match)(struct device *dev, const void *data)) ++{ ++ struct device *dev; ++ ++ dev = bus_find_device(&auxiliary_bus_type, start, data, match); ++ if (!dev) ++ return NULL; ++ ++ return to_auxiliary_dev(dev); ++} ++EXPORT_SYMBOL_GPL(auxiliary_find_device); ++ ++/** ++ * __auxiliary_driver_register - register a driver for auxiliary bus devices ++ * @auxdrv: auxiliary_driver structure ++ * @owner: owning module/driver ++ * @modname: KBUILD_MODNAME for parent driver ++ */ ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, ++ const char *modname) ++{ ++ if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) ++ return -EINVAL; ++ ++ if (auxdrv->name) ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name); ++ else ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); ++ if (!auxdrv->driver.name) ++ return -ENOMEM; ++ ++ auxdrv->driver.owner = owner; ++ auxdrv->driver.bus = &auxiliary_bus_type; ++ auxdrv->driver.mod_name = modname; ++ ++ return driver_register(&auxdrv->driver); ++} ++EXPORT_SYMBOL_GPL(__auxiliary_driver_register); ++ ++/** ++ * auxiliary_driver_unregister - unregister a driver ++ * @auxdrv: auxiliary_driver structure ++ */ ++void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) ++{ ++ driver_unregister(&auxdrv->driver); ++ kfree(auxdrv->driver.name); ++} ++EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); ++ ++static int __init auxiliary_bus_init(void) ++{ ++ return bus_register(&auxiliary_bus_type); ++} ++ ++static void __exit auxiliary_bus_exit(void) ++{ ++ bus_unregister(&auxiliary_bus_type); ++} ++ ++module_init(auxiliary_bus_init); ++module_exit(auxiliary_bus_exit); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Auxiliary Bus"); ++MODULE_AUTHOR("David Ertman "); ++MODULE_AUTHOR("Kiran Patil "); +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +new file mode 100644 +index 000000000000..282fbf7bf9af +--- /dev/null ++++ b/include/linux/auxiliary_bus.h +@@ -0,0 +1,78 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2019-2020 Intel Corporation ++ * ++ * Please see Documentation/driver-api/auxiliary_bus.rst for more information. ++ */ ++ ++#ifndef _AUXILIARY_BUS_H_ ++#define _AUXILIARY_BUS_H_ ++ ++#include ++#include ++#include ++ ++struct auxiliary_device { ++ struct device dev; ++ const char *name; ++ u32 id; ++}; ++ ++struct auxiliary_driver { ++ int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); ++ int (*remove)(struct auxiliary_device *auxdev); ++ void (*shutdown)(struct auxiliary_device *auxdev); ++ int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); ++ int (*resume)(struct auxiliary_device *auxdev); ++ const char *name; ++ struct device_driver driver; ++ const struct auxiliary_device_id *id_table; ++}; ++ ++static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev) ++{ ++ return container_of(dev, struct auxiliary_device, dev); ++} ++ ++static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv) ++{ ++ return container_of(drv, struct auxiliary_driver, driver); ++} ++ ++int auxiliary_device_init(struct auxiliary_device *auxdev); ++int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname); ++#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME) ++ ++static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev) ++{ ++ put_device(&auxdev->dev); ++} ++ ++static inline void auxiliary_device_delete(struct auxiliary_device *auxdev) ++{ ++ device_del(&auxdev->dev); ++} ++ ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, ++ const char *modname); ++#define auxiliary_driver_register(auxdrv) \ ++ __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME) ++ ++void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); ++ ++/** ++ * module_auxiliary_driver() - Helper macro for registering an auxiliary driver ++ * @__auxiliary_driver: auxiliary driver struct ++ * ++ * Helper macro for auxiliary drivers which do not do anything special in ++ * module init/exit. This eliminates a lot of boilerplate. Each module may only ++ * use this macro once, and calling it replaces module_init() and module_exit() ++ */ ++#define module_auxiliary_driver(__auxiliary_driver) \ ++ module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) ++ ++struct auxiliary_device * ++auxiliary_find_device(struct device *start, const void *data, ++ int (*match)(struct device *dev, const void *data)); ++ ++#endif /* _AUXILIARY_BUS_H_ */ +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index 5b08a473cdba..c425290b21e2 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -838,4 +838,12 @@ struct mhi_device_id { + kernel_ulong_t driver_data; + }; + ++#define AUXILIARY_NAME_SIZE 32 ++#define AUXILIARY_MODULE_PREFIX "auxiliary:" ++ ++struct auxiliary_device_id { ++ char name[AUXILIARY_NAME_SIZE]; ++ kernel_ulong_t driver_data; ++}; ++ + #endif /* LINUX_MOD_DEVICETABLE_H */ +diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c +index 27007c18e754..e377f52dbfa3 100644 +--- a/scripts/mod/devicetable-offsets.c ++++ b/scripts/mod/devicetable-offsets.c +@@ -243,5 +243,8 @@ int main(void) + DEVID(mhi_device_id); + DEVID_FIELD(mhi_device_id, chan); + ++ DEVID(auxiliary_device_id); ++ DEVID_FIELD(auxiliary_device_id, name); ++ + return 0; + } +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 2417dd1dee33..fb4827027536 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -1364,6 +1364,13 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) + { + DEF_FIELD_ADDR(symval, mhi_device_id, chan); + sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); ++ return 1; ++} ++ ++static int do_auxiliary_entry(const char *filename, void *symval, char *alias) ++{ ++ DEF_FIELD_ADDR(symval, auxiliary_device_id, name); ++ sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); + + return 1; + } +@@ -1442,6 +1449,7 @@ static const struct devtable devtable[] = { + {"tee", SIZE_tee_client_device_id, do_tee_entry}, + {"wmi", SIZE_wmi_device_id, do_wmi_entry}, + {"mhi", SIZE_mhi_device_id, do_mhi_entry}, ++ {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, + }; + + /* Create MODULE_ALIAS() statements. +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch b/kernel-std/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch new file mode 100644 index 00000000..d87eaa2b --- /dev/null +++ b/kernel-std/centos/patches/0021-driver-core-auxiliary-bus-move-slab.h-from-include-f.patch @@ -0,0 +1,54 @@ +From a64e93a757edfad34955b79f1774d10e9dae955e Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:43:47 +0100 +Subject: [PATCH] driver core: auxiliary bus: move slab.h from include file + +No need to include slab.h in include/linux/auxiliary_bus.h, as it is not +needed there. Move it to drivers/base/auxiliary.c instead. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8og8xi3WkoYXet9@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 7bbb79ff5f7499e0c5d65987458410e8099207d8) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 1 + + include/linux/auxiliary_bus.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index ef2af417438b..eca36d6284d0 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index 282fbf7bf9af..3580743d0e8d 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -10,7 +10,6 @@ + + #include + #include +-#include + + struct auxiliary_device { + struct device dev; +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch b/kernel-std/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch new file mode 100644 index 00000000..96992af5 --- /dev/null +++ b/kernel-std/centos/patches/0022-driver-core-auxiliary-bus-make-remove-function-retur.patch @@ -0,0 +1,79 @@ +From 1eef241f79083237468a534e739ae053f2b7cfd5 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:44:07 +0100 +Subject: [PATCH] driver core: auxiliary bus: make remove function return void + +There's an effort to move the remove() callback in the driver core to +not return an int, as nothing can be done if this function fails. To +make that effort easier, make the aux bus remove function void to start +with so that no users have to be changed sometime in the future. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8ohB1ks1NK7kPop@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 8142a46c50d2dd8160c42284e1044eed3bec0d18) +Signed-off-by: M. Vefa Bicakci +--- + Documentation/driver-api/auxiliary_bus.rst | 2 +- + drivers/base/auxiliary.c | 5 ++--- + include/linux/auxiliary_bus.h | 2 +- + 3 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst +index 5dd7804631ef..2312506b0674 100644 +--- a/Documentation/driver-api/auxiliary_bus.rst ++++ b/Documentation/driver-api/auxiliary_bus.rst +@@ -150,7 +150,7 @@ and shutdown notifications using the standard conventions. + struct auxiliary_driver { + int (*probe)(struct auxiliary_device *, + const struct auxiliary_device_id *id); +- int (*remove)(struct auxiliary_device *); ++ void (*remove)(struct auxiliary_device *); + void (*shutdown)(struct auxiliary_device *); + int (*suspend)(struct auxiliary_device *, pm_message_t); + int (*resume)(struct auxiliary_device *); +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index eca36d6284d0..c44e85802b43 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -82,13 +82,12 @@ static int auxiliary_bus_remove(struct device *dev) + { + struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); +- int ret = 0; + + if (auxdrv->remove) +- ret = auxdrv->remove(auxdev); ++ auxdrv->remove(auxdev); + dev_pm_domain_detach(dev, true); + +- return ret; ++ return 0; + } + + static void auxiliary_bus_shutdown(struct device *dev) +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index 3580743d0e8d..d67b17606210 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -19,7 +19,7 @@ struct auxiliary_device { + + struct auxiliary_driver { + int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); +- int (*remove)(struct auxiliary_device *auxdev); ++ void (*remove)(struct auxiliary_device *auxdev); + void (*shutdown)(struct auxiliary_device *auxdev); + int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); + int (*resume)(struct auxiliary_device *auxdev); +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch b/kernel-std/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch new file mode 100644 index 00000000..7145e36b --- /dev/null +++ b/kernel-std/centos/patches/0023-driver-core-auxiliary-bus-minor-coding-style-tweaks.patch @@ -0,0 +1,166 @@ +From 67b5e80aad2083d07dcbe0e36eb15e65217f373b Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 4 Dec 2020 12:49:28 +0100 +Subject: [PATCH] driver core: auxiliary bus: minor coding style tweaks + +For some reason, the original aux bus patch had some really long lines +in a few places, probably due to it being a very long-lived patch in +development by many different people. Fix that up so that the two files +all have the same length lines and function formatting styles. + +Cc: Dan Williams +Cc: Dave Ertman +Cc: Fred Oh +Cc: Kiran Patil +Cc: Leon Romanovsky +Cc: Martin Habets +Cc: Parav Pandit +Cc: Pierre-Louis Bossart +Cc: Ranjani Sridharan +Cc: Shiraz Saleem +Link: https://lore.kernel.org/r/X8oiSFTpYHw1xE/o@kroah.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 0d2bf11a6b3e275a526b8d42d8d4a3a6067cf953) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 58 +++++++++++++++++++---------------- + include/linux/auxiliary_bus.h | 6 ++-- + 2 files changed, 35 insertions(+), 29 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index c44e85802b43..f303daadf843 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -50,8 +50,8 @@ static int auxiliary_uevent(struct device *dev, struct kobj_uevent_env *env) + name = dev_name(dev); + p = strrchr(name, '.'); + +- return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, (int)(p - name), +- name); ++ return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX, ++ (int)(p - name), name); + } + + static const struct dev_pm_ops auxiliary_dev_pm_ops = { +@@ -113,16 +113,18 @@ static struct bus_type auxiliary_bus_type = { + * auxiliary_device_init - check auxiliary_device and initialize + * @auxdev: auxiliary device struct + * +- * This is the first step in the two-step process to register an auxiliary_device. ++ * This is the first step in the two-step process to register an ++ * auxiliary_device. + * +- * When this function returns an error code, then the device_initialize will *not* have +- * been performed, and the caller will be responsible to free any memory allocated for the +- * auxiliary_device in the error path directly. ++ * When this function returns an error code, then the device_initialize will ++ * *not* have been performed, and the caller will be responsible to free any ++ * memory allocated for the auxiliary_device in the error path directly. + * +- * It returns 0 on success. On success, the device_initialize has been performed. After this +- * point any error unwinding will need to include a call to auxiliary_device_uninit(). +- * In this post-initialize error scenario, a call to the device's .release callback will be +- * triggered, and all memory clean-up is expected to be handled there. ++ * It returns 0 on success. On success, the device_initialize has been ++ * performed. After this point any error unwinding will need to include a call ++ * to auxiliary_device_uninit(). In this post-initialize error scenario, a call ++ * to the device's .release callback will be triggered, and all memory clean-up ++ * is expected to be handled there. + */ + int auxiliary_device_init(struct auxiliary_device *auxdev) + { +@@ -149,16 +151,19 @@ EXPORT_SYMBOL_GPL(auxiliary_device_init); + * @auxdev: auxiliary bus device to add to the bus + * @modname: name of the parent device's driver module + * +- * This is the second step in the two-step process to register an auxiliary_device. ++ * This is the second step in the two-step process to register an ++ * auxiliary_device. + * +- * This function must be called after a successful call to auxiliary_device_init(), which +- * will perform the device_initialize. This means that if this returns an error code, then a +- * call to auxiliary_device_uninit() must be performed so that the .release callback will +- * be triggered to free the memory associated with the auxiliary_device. ++ * This function must be called after a successful call to ++ * auxiliary_device_init(), which will perform the device_initialize. This ++ * means that if this returns an error code, then a call to ++ * auxiliary_device_uninit() must be performed so that the .release callback ++ * will be triggered to free the memory associated with the auxiliary_device. + * +- * The expectation is that users will call the "auxiliary_device_add" macro so that the caller's +- * KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires +- * a custom name would this version be called directly. ++ * The expectation is that users will call the "auxiliary_device_add" macro so ++ * that the caller's KBUILD_MODNAME is automatically inserted for the modname ++ * parameter. Only if a user requires a custom name would this version be ++ * called directly. + */ + int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) + { +@@ -166,13 +171,13 @@ int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname) + int ret; + + if (!modname) { +- pr_err("auxiliary device modname is NULL\n"); ++ dev_err(dev, "auxiliary device modname is NULL\n"); + return -EINVAL; + } + + ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); + if (ret) { +- pr_err("auxiliary device dev_set_name failed: %d\n", ret); ++ dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret); + return ret; + } + +@@ -197,9 +202,9 @@ EXPORT_SYMBOL_GPL(__auxiliary_device_add); + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +-struct auxiliary_device * +-auxiliary_find_device(struct device *start, const void *data, +- int (*match)(struct device *dev, const void *data)) ++struct auxiliary_device *auxiliary_find_device(struct device *start, ++ const void *data, ++ int (*match)(struct device *dev, const void *data)) + { + struct device *dev; + +@@ -217,14 +222,15 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); + * @owner: owning module/driver + * @modname: KBUILD_MODNAME for parent driver + */ +-int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, +- const char *modname) ++int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, ++ struct module *owner, const char *modname) + { + if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) + return -EINVAL; + + if (auxdrv->name) +- auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, auxdrv->name); ++ auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, ++ auxdrv->name); + else + auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); + if (!auxdrv->driver.name) +diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h +index d67b17606210..fc51d45f106b 100644 +--- a/include/linux/auxiliary_bus.h ++++ b/include/linux/auxiliary_bus.h +@@ -70,8 +70,8 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); + #define module_auxiliary_driver(__auxiliary_driver) \ + module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) + +-struct auxiliary_device * +-auxiliary_find_device(struct device *start, const void *data, +- int (*match)(struct device *dev, const void *data)); ++struct auxiliary_device *auxiliary_find_device(struct device *start, ++ const void *data, ++ int (*match)(struct device *dev, const void *data)); + + #endif /* _AUXILIARY_BUS_H_ */ +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch b/kernel-std/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch new file mode 100644 index 00000000..7960421f --- /dev/null +++ b/kernel-std/centos/patches/0024-driver-core-auxiliary-bus-Fix-auxiliary-bus-shutdown.patch @@ -0,0 +1,49 @@ +From 7f4d45ef5bfe6dd025b1f7c736d198b9a208cdef Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Fri, 4 Dec 2020 09:46:49 -0700 +Subject: [PATCH] driver core: auxiliary bus: Fix auxiliary bus shutdown null + auxdrv ptr + +If the probe of the auxdrv failed, the device->driver is set to NULL. +During kernel shutdown, the bus shutdown will call auxdrv->shutdown and +cause an invalid ptr dereference. Add check to make sure device->driver is +not NULL before we proceed. + +Fixes: 7de3697e9cbd ("Add auxiliary bus support") +Cc: Dave Ertman +Signed-off-by: Dave Jiang +Reviewed-by: Dan Williams +Link: https://lore.kernel.org/r/160710040926.1889434.8840329810698403478.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 784b2c48ac12dcee27db001fb1a3c58c39380cb6) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index f303daadf843..8336535f1e11 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -92,10 +92,15 @@ static int auxiliary_bus_remove(struct device *dev) + + static void auxiliary_bus_shutdown(struct device *dev) + { +- struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); +- struct auxiliary_device *auxdev = to_auxiliary_dev(dev); ++ struct auxiliary_driver *auxdrv = NULL; ++ struct auxiliary_device *auxdev; ++ ++ if (dev->driver) { ++ auxdrv = to_auxiliary_drv(dev->driver); ++ auxdev = to_auxiliary_dev(dev); ++ } + +- if (auxdrv->shutdown) ++ if (auxdrv && auxdrv->shutdown) + auxdrv->shutdown(auxdev); + } + +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch b/kernel-std/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch new file mode 100644 index 00000000..7d7af988 --- /dev/null +++ b/kernel-std/centos/patches/0025-driver-core-auxiliary-bus-Fix-calling-stage-for-auxi.patch @@ -0,0 +1,146 @@ +From 87f05137d98572c5926bbc6949ecc6616bd90057 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Wed, 10 Feb 2021 13:16:11 -0700 +Subject: [PATCH] driver core: auxiliary bus: Fix calling stage for auxiliary + bus init + +When the auxiliary device code is built into the kernel, it can be executed +before the auxiliary bus is registered. This causes bus->p to be not +allocated and triggers a NULL pointer dereference when the auxiliary bus +device gets added with bus_add_device(). Call the auxiliary_bus_init() +under driver_init() so the bus is initialized before devices. + +Below is the kernel splat for the bug: +[ 1.948215] BUG: kernel NULL pointer dereference, address: 0000000000000060 +[ 1.950670] #PF: supervisor read access in kernel mode +[ 1.950670] #PF: error_code(0x0000) - not-present page +[ 1.950670] PGD 0 +[ 1.950670] Oops: 0000 1 SMP NOPTI +[ 1.950670] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.0-intel-nextsvmtest+ #2205 +[ 1.950670] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 +[ 1.950670] RIP: 0010:bus_add_device+0x64/0x140 +[ 1.950670] Code: 00 49 8b 75 20 48 89 df e8 59 a1 ff ff 41 89 c4 85 c0 75 7b 48 8b 53 50 48 85 d2 75 03 48 8b 13 49 8b 85 a0 00 00 00 48 89 de <48> 8 +78 60 48 83 c7 18 e8 ef d9 a9 ff 41 89 c4 85 c0 75 45 48 8b +[ 1.950670] RSP: 0000:ff46032ac001baf8 EFLAGS: 00010246 +[ 1.950670] RAX: 0000000000000000 RBX: ff4597f7414aa680 RCX: 0000000000000000 +[ 1.950670] RDX: ff4597f74142bbc0 RSI: ff4597f7414aa680 RDI: ff4597f7414aa680 +[ 1.950670] RBP: ff46032ac001bb10 R08: 0000000000000044 R09: 0000000000000228 +[ 1.950670] R10: ff4597f741141b30 R11: ff4597f740182a90 R12: 0000000000000000 +[ 1.950670] R13: ffffffffa5e936c0 R14: 0000000000000000 R15: 0000000000000000 +[ 1.950670] FS: 0000000000000000(0000) GS:ff4597f7bba00000(0000) knlGS:0000000000000000 +[ 1.950670] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1.950670] CR2: 0000000000000060 CR3: 000000002140c001 CR4: 0000000000f71ef0 +[ 1.950670] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 1.950670] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +[ 1.950670] PKRU: 55555554 +[ 1.950670] Call Trace: +[ 1.950670] device_add+0x3ee/0x850 +[ 1.950670] __auxiliary_device_add+0x47/0x60 +[ 1.950670] idxd_pci_probe+0xf77/0x1180 +[ 1.950670] local_pci_probe+0x4a/0x90 +[ 1.950670] pci_device_probe+0xff/0x1b0 +[ 1.950670] really_probe+0x1cf/0x440 +[ 1.950670] ? rdinit_setup+0x31/0x31 +[ 1.950670] driver_probe_device+0xe8/0x150 +[ 1.950670] device_driver_attach+0x58/0x60 +[ 1.950670] __driver_attach+0x8f/0x150 +[ 1.950670] ? device_driver_attach+0x60/0x60 +[ 1.950670] ? device_driver_attach+0x60/0x60 +[ 1.950670] bus_for_each_dev+0x79/0xc0 +[ 1.950670] ? kmem_cache_alloc_trace+0x323/0x430 +[ 1.950670] driver_attach+0x1e/0x20 +[ 1.950670] bus_add_driver+0x154/0x1f0 +[ 1.950670] driver_register+0x70/0xc0 +[ 1.950670] __pci_register_driver+0x54/0x60 +[ 1.950670] idxd_init_module+0xe2/0xfc +[ 1.950670] ? idma64_platform_driver_init+0x19/0x19 +[ 1.950670] do_one_initcall+0x4a/0x1e0 +[ 1.950670] kernel_init_freeable+0x1fc/0x25c +[ 1.950670] ? rest_init+0xba/0xba +[ 1.950670] kernel_init+0xe/0x116 +[ 1.950670] ret_from_fork+0x1f/0x30 +[ 1.950670] Modules linked in: +[ 1.950670] CR2: 0000000000000060 +[ 1.950670] --[ end trace cd7d1b226d3ca901 ]-- + +Fixes: 7de3697e9cbd ("Add auxiliary bus support") +Reported-by: Jacob Pan +Reviewed-by: Dan Williams +Acked-by: Dave Ertman +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/20210210201611.1611074-1-dave.jiang@intel.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 471b12c43f376d5203dbff0e91316eea11f6f4df) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 13 +++---------- + drivers/base/base.h | 5 +++++ + drivers/base/init.c | 1 + + 3 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index 8336535f1e11..d8b314e7d0fd 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include "base.h" + + static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, + const struct auxiliary_device *auxdev) +@@ -260,19 +261,11 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv) + } + EXPORT_SYMBOL_GPL(auxiliary_driver_unregister); + +-static int __init auxiliary_bus_init(void) ++void __init auxiliary_bus_init(void) + { +- return bus_register(&auxiliary_bus_type); ++ WARN_ON(bus_register(&auxiliary_bus_type)); + } + +-static void __exit auxiliary_bus_exit(void) +-{ +- bus_unregister(&auxiliary_bus_type); +-} +- +-module_init(auxiliary_bus_init); +-module_exit(auxiliary_bus_exit); +- + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("Auxiliary Bus"); + MODULE_AUTHOR("David Ertman "); +diff --git a/drivers/base/base.h b/drivers/base/base.h +index 91cfb8405abd..7d97447460fa 100644 +--- a/drivers/base/base.h ++++ b/drivers/base/base.h +@@ -119,6 +119,11 @@ static inline int hypervisor_init(void) { return 0; } + extern int platform_bus_init(void); + extern void cpu_dev_init(void); + extern void container_dev_init(void); ++#ifdef CONFIG_AUXILIARY_BUS ++extern void auxiliary_bus_init(void); ++#else ++static inline void auxiliary_bus_init(void) { } ++#endif + + struct kobject *virtual_device_parent(struct device *dev); + +diff --git a/drivers/base/init.c b/drivers/base/init.c +index 908e6520e804..a9f57c22fb9e 100644 +--- a/drivers/base/init.c ++++ b/drivers/base/init.c +@@ -32,6 +32,7 @@ void __init driver_init(void) + */ + of_core_init(); + platform_bus_init(); ++ auxiliary_bus_init(); + cpu_dev_init(); + memory_dev_init(); + container_dev_init(); +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch b/kernel-std/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch new file mode 100644 index 00000000..f72de9cf --- /dev/null +++ b/kernel-std/centos/patches/0026-driver-core-auxiliary-bus-Remove-unneeded-module-bit.patch @@ -0,0 +1,35 @@ +From bcfe18a2fd6d45f14ae60c742a7661a64e46305e Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Thu, 11 Feb 2021 13:21:29 -0700 +Subject: [PATCH] driver core: auxiliary bus: Remove unneeded module bits + +Remove module bits in the auxiliary bus code since the auxiliary bus +cannot be built as a module and the relevant code is not needed. + +Cc: Dave Ertman +Suggested-by: Greg Kroah-Hartman +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/161307488980.1896017.15627190714413338196.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit bbf44abeeabfe05a124535e6c3a9fd7d682d42bf) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index d8b314e7d0fd..adc199dfba3c 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -265,8 +265,3 @@ void __init auxiliary_bus_init(void) + { + WARN_ON(bus_register(&auxiliary_bus_type)); + } +- +-MODULE_LICENSE("GPL v2"); +-MODULE_DESCRIPTION("Auxiliary Bus"); +-MODULE_AUTHOR("David Ertman "); +-MODULE_AUTHOR("Kiran Patil "); +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch b/kernel-std/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch new file mode 100644 index 00000000..9b893e99 --- /dev/null +++ b/kernel-std/centos/patches/0027-driver-core-auxiliary-bus-Fix-memory-leak-when-drive.patch @@ -0,0 +1,51 @@ +From 09b57232d358202d79e2133d523a664906e9759c Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +Date: Tue, 13 Jul 2021 12:34:38 +0300 +Subject: [PATCH] driver core: auxiliary bus: Fix memory leak when + driver_register() fail + +If driver_register() returns with error we need to free the memory +allocated for auxdrv->driver.name before returning from +__auxiliary_driver_register() + +Fixes: 7de3697e9cbd4 ("Add auxiliary bus support") +Reviewed-by: Dan Williams +Cc: stable +Signed-off-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20210713093438.3173-1-peter.ujfalusi@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +(cherry picked from commit 4afa0c22eed33cfe0c590742387f0d16f32412f3) +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/auxiliary.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c +index adc199dfba3c..6a30264ab2ba 100644 +--- a/drivers/base/auxiliary.c ++++ b/drivers/base/auxiliary.c +@@ -231,6 +231,8 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); + int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, + struct module *owner, const char *modname) + { ++ int ret; ++ + if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) + return -EINVAL; + +@@ -246,7 +248,11 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, + auxdrv->driver.bus = &auxiliary_bus_type; + auxdrv->driver.mod_name = modname; + +- return driver_register(&auxdrv->driver); ++ ret = driver_register(&auxdrv->driver); ++ if (ret) ++ kfree(auxdrv->driver.name); ++ ++ return ret; + } + EXPORT_SYMBOL_GPL(__auxiliary_driver_register); + +-- +2.29.2 + diff --git a/kernel-std/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch b/kernel-std/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch new file mode 100644 index 00000000..779f2e42 --- /dev/null +++ b/kernel-std/centos/patches/0028-driver-core-auxiliary-bus-Enable-by-default.patch @@ -0,0 +1,38 @@ +From b1d1297d44033ae1d756838d6e06f04d52d1ceb6 Mon Sep 17 00:00:00 2001 +From: "M. Vefa Bicakci" +Date: Thu, 17 Feb 2022 14:17:58 -0500 +Subject: [PATCH] driver core: auxiliary bus: Enable by default + +This commit enables CONFIG_AUXILIARY_BUS by default. This is necessary, +because StarlingX does not enable any kernel modules that 'select' +CONFIG_AUXILIARY_BUS, which causes the kernel's build system to +automatically disable this option. + +However, StarlingX has out-of-tree users of this functionality (such as +the 'ice' and 'mlnx-ofa_kernel' out-of-tree kernel driver packages), +hence the need for this change. Prior to this commit, the aforementioned +out-of-tree kernel drivers would use their embedded/bundled copy of the +same functionality, which would cause kernel symbol conflicts at +run-time when users attempted to load both ice and mlnx-ofa_kernel +drivers. + +Signed-off-by: M. Vefa Bicakci +--- + drivers/base/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 040be48ce046..a18ec49b9dac 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -3,6 +3,7 @@ menu "Generic Driver Options" + + config AUXILIARY_BUS + bool ++ default y + + config UEVENT_HELPER + bool "Support for uevent helper" +-- +2.29.2 +