Commit 28a4f91f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull driver core updates from Greg KH:
 "Here is a small set of driver core updates and additions for 6.6-rc1.

  Included in here are:

   - stable kernel documentation updates

   - class structure const work from Ivan on various subsystems

   - kernfs tweaks

   - driver core tests!

   - kobject sanity cleanups

   - kobject structure reordering to save space

   - driver core error code handling fixups

   - other minor driver core cleanups

  All of these have been in linux-next for a while with no reported
  problems"

* tag 'driver-core-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (32 commits)
  driver core: Call in reversed order in device_platform_notify_remove()
  driver core: Return proper error code when dev_set_name() fails
  kobject: Remove redundant checks for whether ktype is NULL
  kobject: Add sanity check for kset->kobj.ktype in kset_register()
  drivers: base: test: Add missing MODULE_* macros to root device tests
  drivers: base: test: Add missing MODULE_* macros for platform devices tests
  drivers: base: Free devm resources when unregistering a device
  drivers: base: Add basic devm tests for platform devices
  drivers: base: Add basic devm tests for root devices
  kernfs: fix missing kernfs_iattr_rwsem locking
  docs: stable-kernel-rules: mention that regressions must be prevented
  docs: stable-kernel-rules: fine-tune various details
  docs: stable-kernel-rules: make the examples for option 1 a proper list
  docs: stable-kernel-rules: move text around to improve flow
  docs: stable-kernel-rules: improve structure by changing headlines
  base/node: Remove duplicated include
  kernfs: attach uuid for every kernfs and report it in fsid
  kernfs: add stub helper for kernfs_generic_poll()
  x86/resctrl: make pseudo_lock_class a static const structure
  x86/MSR: make msr_class a static const structure
  ...
parents 8e1e4955 29c8ab79
Loading
Loading
Loading
Loading
+113 −82
Original line number Diff line number Diff line
@@ -6,30 +6,29 @@ Everything you ever wanted to know about Linux -stable releases
Rules on what kind of patches are accepted, and which ones are not, into the
"-stable" tree:

 - It or an equivalent fix must already exist in Linus' tree (upstream).
 - It must be obviously correct and tested.
 - It cannot be bigger than 100 lines, with context.
 - It must fix only one thing.
 - It must fix a real bug that bothers people (not a, "This could be a
   problem..." type thing).
 - It must fix a problem that causes a build error (but not for things
   marked CONFIG_BROKEN), an oops, a hang, data corruption, a real
   security issue, or some "oh, that's not good" issue.  In short, something
   critical.
 - It must follow the
   :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
   rules.
 - It must either fix a real bug that bothers people or just add a device ID.
   To elaborate on the former:

   - It fixes a problem like an oops, a hang, data corruption, a real security
     issue, a hardware quirk, a build error (but not for things marked
     CONFIG_BROKEN), or some "oh, that's not good" issue.
   - Serious issues as reported by a user of a distribution kernel may also
     be considered if they fix a notable performance or interactivity issue.
     As these fixes are not as obvious and have a higher risk of a subtle
     regression they should only be submitted by a distribution kernel
     maintainer and include an addendum linking to a bugzilla entry if it
     exists and additional information on the user-visible impact.
 - New device IDs and quirks are also accepted.
 - No "theoretical race condition" issues, unless an explanation of how the
   race can be exploited is also provided.
 - It cannot contain any "trivial" fixes in it (spelling changes,
   whitespace cleanups, etc).
 - It must follow the
   :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
   rules.
 - It or an equivalent fix must already exist in Linus' tree (upstream).
   - No "This could be a problem..." type of things like a "theoretical race
     condition", unless an explanation of how the bug can be exploited is also
     provided.
   - No "trivial" fixes without benefit for users (spelling changes, whitespace
     cleanups, etc).


Procedure for submitting patches to the -stable tree
@@ -41,70 +40,48 @@ Procedure for submitting patches to the -stable tree
   process but should follow the procedures in
   :ref:`Documentation/process/security-bugs.rst <securitybugs>`.

For all other submissions, choose one of the following procedures
-----------------------------------------------------------------

.. _option_1:

Option 1
********

To have the patch automatically included in the stable tree, add the tag

.. code-block:: none

     Cc: stable@vger.kernel.org
There are three options to submit a change to -stable trees:

in the sign-off area. Once the patch is merged it will be applied to
the stable tree without anything else needing to be done by the author
or subsystem maintainer.
 1. Add a 'stable tag' to the description of a patch you then submit for
    mainline inclusion.
 2. Ask the stable team to pick up a patch already mainlined.
 3. Submit a patch to the stable team that is equivalent to a change already
    mainlined.

.. _option_2:
The sections below describe each of the options in more detail.

Option 2
********
:ref:`option_1` is **strongly** preferred, it is the easiest and most common.
:ref:`option_2` is mainly meant for changes where backporting was not considered
at the time of submission. :ref:`option_3` is an alternative to the two earlier
options for cases where a mainlined patch needs adjustments to apply in older
series (for example due to API changes).

After the patch has been merged to Linus' tree, send an email to
stable@vger.kernel.org containing the subject of the patch, the commit ID,
why you think it should be applied, and what kernel version you wish it to
be applied to.
When using option 2 or 3 you can ask for your change to be included in specific
stable series. When doing so, ensure the fix or an equivalent is applicable,
submitted, or already present in all newer stable trees still supported. This is
meant to prevent regressions that users might later encounter on updating, if
e.g. a fix merged for 5.19-rc1 would be backported to 5.10.y, but not to 5.15.y.

.. _option_3:
.. _option_1:

Option 3
Option 1
********

Send the patch, after verifying that it follows the above rules, to
stable@vger.kernel.org.  You must note the upstream commit ID in the
changelog of your submission, as well as the kernel version you wish
it to be applied to.

:ref:`option_1` is **strongly** preferred, is the easiest and most common.
:ref:`option_2` and :ref:`option_3` are more useful if the patch isn't deemed
worthy at the time it is applied to a public git tree (for instance, because
it deserves more regression testing first).  :ref:`option_3` is especially
useful if the original upstream patch needs to be backported (for example
the backport needs some special handling due to e.g. API changes).

Note that for :ref:`option_3`, if the patch deviates from the original
upstream patch (for example because it had to be backported) this must be very
clearly documented and justified in the patch description.

The upstream commit ID must be specified with a separate line above the commit
text, like this:
To have a patch you submit for mainline inclusion later automatically picked up
for stable trees, add the tag

.. code-block:: none

    commit <sha1> upstream.

or alternatively:
     Cc: stable@vger.kernel.org

.. code-block:: none
in the sign-off area. Once the patch is mainlined it will be applied to the
stable tree without anything else needing to be done by the author or
subsystem maintainer.

    [ Upstream commit <sha1> ]
To sent additional instructions to the stable team, use a shell-style inline
comment:

Additionally, some patches submitted via :ref:`option_1` may have additional
patch prerequisites which can be cherry-picked. This can be specified in the
 * To specify any additional patch prerequisites for cherry picking use the
   following format in the sign-off area:

   .. code-block:: none
@@ -124,8 +101,8 @@ The tag sequence has the meaning of:
     git cherry-pick fd21073
     git cherry-pick <this commit>

Also, some patches may have kernel version prerequisites.  This can be
specified in the following format in the sign-off area:
 * For patches that may have kernel version prerequisites specify them using
   the following format in the sign-off area:

   .. code-block:: none

@@ -139,13 +116,66 @@ The tag has the meaning of:

   For each "-stable" tree starting with the specified version.

Following the submission:
   Note, such tagging is unnecessary if the stable team can derive the
   appropriate versions from Fixes: tags.

 - The sender will receive an ACK when the patch has been accepted into the
 * To delay pick up of patches, use the following format:

   .. code-block:: none

     Cc: <stable@vger.kernel.org> # after 4 weeks in mainline

 * For any other requests, just add a note to the stable tag. This for example
   can be used to point out known problems:

   .. code-block:: none

     Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.3

.. _option_2:

Option 2
********

If the patch already has been merged to mainline, send an email to
stable@vger.kernel.org containing the subject of the patch, the commit ID,
why you think it should be applied, and what kernel versions you wish it to
be applied to.

.. _option_3:

Option 3
********

Send the patch, after verifying that it follows the above rules, to
stable@vger.kernel.org and mention the kernel versions you wish it to be applied
to. When doing so, you must note the upstream commit ID in the changelog of your
submission with a separate line above the commit text, like this:

.. code-block:: none

    commit <sha1> upstream.

or alternatively:

.. code-block:: none

    [ Upstream commit <sha1> ]

If the submitted patch deviates from the original upstream patch (for example
because it had to be adjusted for the older API), this must be very clearly
documented and justified in the patch description.


Following the submission
------------------------

The sender will receive an ACK when the patch has been accepted into the
queue, or a NAK if the patch is rejected.  This response might take a few
   days, according to the developer's schedules.
 - If accepted, the patch will be added to the -stable queue, for review by
   other developers and by the relevant subsystem maintainer.
days, according to the schedules of the stable team members.

If accepted, the patch will be added to the -stable queue, for review by other
developers and by the relevant subsystem maintainer.


Review cycle
@@ -174,6 +204,7 @@ Review cycle
   security kernel team, and not go through the normal review cycle.
   Contact the kernel security team for more details on this procedure.


Trees
-----

+21 −20
Original line number Diff line number Diff line
@@ -45,7 +45,21 @@ static u64 prefetch_disable_bits;
 */
static unsigned int pseudo_lock_major;
static unsigned long pseudo_lock_minor_avail = GENMASK(MINORBITS, 0);
static struct class *pseudo_lock_class;

static char *pseudo_lock_devnode(const struct device *dev, umode_t *mode)
{
	const struct rdtgroup *rdtgrp;

	rdtgrp = dev_get_drvdata(dev);
	if (mode)
		*mode = 0600;
	return kasprintf(GFP_KERNEL, "pseudo_lock/%s", rdtgrp->kn->name);
}

static const struct class pseudo_lock_class = {
	.name = "pseudo_lock",
	.devnode = pseudo_lock_devnode,
};

/**
 * get_prefetch_disable_bits - prefetch disable bits of supported platforms
@@ -1353,7 +1367,7 @@ int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp)
					    &pseudo_measure_fops);
	}

	dev = device_create(pseudo_lock_class, NULL,
	dev = device_create(&pseudo_lock_class, NULL,
			    MKDEV(pseudo_lock_major, new_minor),
			    rdtgrp, "%s", rdtgrp->kn->name);

@@ -1383,7 +1397,7 @@ int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp)
	goto out;

out_device:
	device_destroy(pseudo_lock_class, MKDEV(pseudo_lock_major, new_minor));
	device_destroy(&pseudo_lock_class, MKDEV(pseudo_lock_major, new_minor));
out_debugfs:
	debugfs_remove_recursive(plr->debugfs_dir);
	pseudo_lock_minor_release(new_minor);
@@ -1424,7 +1438,7 @@ void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp)

	pseudo_lock_cstates_relax(plr);
	debugfs_remove_recursive(rdtgrp->plr->debugfs_dir);
	device_destroy(pseudo_lock_class, MKDEV(pseudo_lock_major, plr->minor));
	device_destroy(&pseudo_lock_class, MKDEV(pseudo_lock_major, plr->minor));
	pseudo_lock_minor_release(plr->minor);

free:
@@ -1560,16 +1574,6 @@ static const struct file_operations pseudo_lock_dev_fops = {
	.mmap =		pseudo_lock_dev_mmap,
};

static char *pseudo_lock_devnode(const struct device *dev, umode_t *mode)
{
	const struct rdtgroup *rdtgrp;

	rdtgrp = dev_get_drvdata(dev);
	if (mode)
		*mode = 0600;
	return kasprintf(GFP_KERNEL, "pseudo_lock/%s", rdtgrp->kn->name);
}

int rdt_pseudo_lock_init(void)
{
	int ret;
@@ -1580,21 +1584,18 @@ int rdt_pseudo_lock_init(void)

	pseudo_lock_major = ret;

	pseudo_lock_class = class_create("pseudo_lock");
	if (IS_ERR(pseudo_lock_class)) {
		ret = PTR_ERR(pseudo_lock_class);
	ret = class_register(&pseudo_lock_class);
	if (ret) {
		unregister_chrdev(pseudo_lock_major, "pseudo_lock");
		return ret;
	}

	pseudo_lock_class->devnode = pseudo_lock_devnode;
	return 0;
}

void rdt_pseudo_lock_release(void)
{
	class_destroy(pseudo_lock_class);
	pseudo_lock_class = NULL;
	class_unregister(&pseudo_lock_class);
	unregister_chrdev(pseudo_lock_major, "pseudo_lock");
	pseudo_lock_major = 0;
}
+16 −15
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include <asm/processor.h>
#include <asm/msr.h>

static struct class *cpuid_class;
static enum cpuhp_state cpuhp_cpuid_state;

struct cpuid_regs_done {
@@ -124,26 +123,31 @@ static const struct file_operations cpuid_fops = {
	.open = cpuid_open,
};

static char *cpuid_devnode(const struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
}

static const struct class cpuid_class = {
	.name		= "cpuid",
	.devnode	= cpuid_devnode,
};

static int cpuid_device_create(unsigned int cpu)
{
	struct device *dev;

	dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
	dev = device_create(&cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
			    "cpu%d", cpu);
	return PTR_ERR_OR_ZERO(dev);
}

static int cpuid_device_destroy(unsigned int cpu)
{
	device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
	device_destroy(&cpuid_class, MKDEV(CPUID_MAJOR, cpu));
	return 0;
}

static char *cpuid_devnode(const struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
}

static int __init cpuid_init(void)
{
	int err;
@@ -154,12 +158,9 @@ static int __init cpuid_init(void)
		       CPUID_MAJOR);
		return -EBUSY;
	}
	cpuid_class = class_create("cpuid");
	if (IS_ERR(cpuid_class)) {
		err = PTR_ERR(cpuid_class);
	err = class_register(&cpuid_class);
	if (err)
		goto out_chrdev;
	}
	cpuid_class->devnode = cpuid_devnode;

	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/cpuid:online",
				cpuid_device_create, cpuid_device_destroy);
@@ -170,7 +171,7 @@ static int __init cpuid_init(void)
	return 0;

out_class:
	class_destroy(cpuid_class);
	class_unregister(&cpuid_class);
out_chrdev:
	__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
	return err;
@@ -180,7 +181,7 @@ module_init(cpuid_init);
static void __exit cpuid_exit(void)
{
	cpuhp_remove_state(cpuhp_cpuid_state);
	class_destroy(cpuid_class);
	class_unregister(&cpuid_class);
	__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
}
module_exit(cpuid_exit);
+16 −15
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@
#include <asm/cpufeature.h>
#include <asm/msr.h>

static struct class *msr_class;
static enum cpuhp_state cpuhp_msr_state;

enum allow_write_msrs {
@@ -235,26 +234,31 @@ static const struct file_operations msr_fops = {
	.compat_ioctl = msr_ioctl,
};

static char *msr_devnode(const struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
}

static const struct class msr_class = {
	.name		= "msr",
	.devnode	= msr_devnode,
};

static int msr_device_create(unsigned int cpu)
{
	struct device *dev;

	dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
	dev = device_create(&msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
			    "msr%d", cpu);
	return PTR_ERR_OR_ZERO(dev);
}

static int msr_device_destroy(unsigned int cpu)
{
	device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
	device_destroy(&msr_class, MKDEV(MSR_MAJOR, cpu));
	return 0;
}

static char *msr_devnode(const struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
}

static int __init msr_init(void)
{
	int err;
@@ -263,12 +267,9 @@ static int __init msr_init(void)
		pr_err("unable to get major %d for msr\n", MSR_MAJOR);
		return -EBUSY;
	}
	msr_class = class_create("msr");
	if (IS_ERR(msr_class)) {
		err = PTR_ERR(msr_class);
	err = class_register(&msr_class);
	if (err)
		goto out_chrdev;
	}
	msr_class->devnode = msr_devnode;

	err  = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/msr:online",
				 msr_device_create, msr_device_destroy);
@@ -278,7 +279,7 @@ static int __init msr_init(void)
	return 0;

out_class:
	class_destroy(msr_class);
	class_unregister(&msr_class);
out_chrdev:
	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
	return err;
@@ -288,7 +289,7 @@ module_init(msr_init);
static void __exit msr_exit(void)
{
	cpuhp_remove_state(cpuhp_msr_state);
	class_destroy(msr_class);
	class_unregister(&msr_class);
	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
}
module_exit(msr_exit)
+20 −10
Original line number Diff line number Diff line
@@ -2306,12 +2306,12 @@ static void device_platform_notify(struct device *dev)

static void device_platform_notify_remove(struct device *dev)
{
	acpi_device_notify_remove(dev);
	if (platform_notify_remove)
		platform_notify_remove(dev);

	software_node_notify_remove(dev);

	if (platform_notify_remove)
		platform_notify_remove(dev);
	acpi_device_notify_remove(dev);
}

/**
@@ -3528,18 +3528,17 @@ int device_add(struct device *dev)
	 * the name, and force the use of dev_name()
	 */
	if (dev->init_name) {
		dev_set_name(dev, "%s", dev->init_name);
		error = dev_set_name(dev, "%s", dev->init_name);
		dev->init_name = NULL;
	}

	if (dev_name(dev))
		error = 0;
	/* subsystems can specify simple device enumeration */
	if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
		dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);

	if (!dev_name(dev)) {
		error = -EINVAL;
	else if (dev->bus && dev->bus->dev_name)
		error = dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
	if (error)
		goto name_error;
	}

	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);

@@ -3815,6 +3814,17 @@ void device_del(struct device *dev)
	device_platform_notify_remove(dev);
	device_links_purge(dev);

	/*
	 * If a device does not have a driver attached, we need to clean
	 * up any managed resources. We do this in device_release(), but
	 * it's never called (and we leak the device) if a managed
	 * resource holds a reference to the device. So release all
	 * managed resources here, like we do in driver_detach(). We
	 * still need to do so again in device_release() in case someone
	 * adds a new resource after this point, though.
	 */
	devres_release_all(dev);

	bus_notify(dev, BUS_NOTIFY_REMOVED_DEVICE);
	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
	glue_dir = get_glue_dir(dev);
Loading