mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
Driver core changes for 6.8-rc1
Here are the set of driver core and kernfs changes for 6.8-rc1. Nothing major in here this release cycle, just lots of small cleanups and some tweaks on kernfs that in the very end, got reverted and will come back in a safer way next release cycle. Included in here are: - more driver core 'const' cleanups and fixes - fw_devlink=rpm is now the default behavior - kernfs tiny changes to remove some string functions - cpu handling in the driver core is updated to work better on many systems that add topologies and cpus after booting - other minor changes and cleanups All of the cpu handling patches have been acked by the respective maintainers and are coming in here in one series. Everything has been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZaeOrg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymtcwCffzvKKkSY9qAp6+0v2WQNkZm1JWoAoJCPYUwF If6wEoPLWvRfKx4gIoq9 =D96r -----END PGP SIGNATURE----- Merge tag 'driver-core-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here are the set of driver core and kernfs changes for 6.8-rc1. Nothing major in here this release cycle, just lots of small cleanups and some tweaks on kernfs that in the very end, got reverted and will come back in a safer way next release cycle. Included in here are: - more driver core 'const' cleanups and fixes - fw_devlink=rpm is now the default behavior - kernfs tiny changes to remove some string functions - cpu handling in the driver core is updated to work better on many systems that add topologies and cpus after booting - other minor changes and cleanups All of the cpu handling patches have been acked by the respective maintainers and are coming in here in one series. Everything has been in linux-next for a while with no reported issues" * tag 'driver-core-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (51 commits) Revert "kernfs: convert kernfs_idr_lock to an irq safe raw spinlock" kernfs: convert kernfs_idr_lock to an irq safe raw spinlock class: fix use-after-free in class_register() PM: clk: make pm_clk_add_notifier() take a const pointer EDAC: constantify the struct bus_type usage kernfs: fix reference to renamed function driver core: device.h: fix Excess kernel-doc description warning driver core: class: fix Excess kernel-doc description warning driver core: mark remaining local bus_type variables as const driver core: container: make container_subsys const driver core: bus: constantify subsys_register() calls driver core: bus: make bus_sort_breadthfirst() take a const pointer kernfs: d_obtain_alias(NULL) will do the right thing... driver core: Better advertise dev_err_probe() kernfs: Convert kernfs_path_from_node_locked() from strlcpy() to strscpy() kernfs: Convert kernfs_name_locked() from strlcpy() to strscpy() kernfs: Convert kernfs_walk_ns() from strlcpy() to strscpy() initramfs: Expose retained initrd as sysfs file fs/kernfs/dir: obey S_ISGID kernel/cgroup: use kernfs_create_dir_ns() ...
This commit is contained in:
commit
80955ae955
8
Documentation/ABI/testing/sysfs-firmware-initrd
Normal file
8
Documentation/ABI/testing/sysfs-firmware-initrd
Normal file
@ -0,0 +1,8 @@
|
||||
What: /sys/firmware/initrd
|
||||
Date: December 2023
|
||||
Contact: Alexander Graf <graf@amazon.com>
|
||||
Description:
|
||||
When the kernel was booted with an initrd and the
|
||||
"retain_initrd" option is set on the kernel command
|
||||
line, /sys/firmware/initrd contains the contents of the
|
||||
initrd that the kernel was booted with.
|
@ -2449,7 +2449,7 @@
|
||||
between unregistering the boot console and initializing
|
||||
the real console.
|
||||
|
||||
keepinitrd [HW,ARM]
|
||||
keepinitrd [HW,ARM] See retain_initrd.
|
||||
|
||||
kernelcore= [KNL,X86,IA-64,PPC]
|
||||
Format: nn[KMGTPE] | nn% | "mirror"
|
||||
@ -5604,7 +5604,8 @@
|
||||
Useful for devices that are detected asynchronously
|
||||
(e.g. USB and MMC devices).
|
||||
|
||||
retain_initrd [RAM] Keep initrd memory after extraction
|
||||
retain_initrd [RAM] Keep initrd memory after extraction. After boot, it will
|
||||
be accessible via /sys/firmware/initrd.
|
||||
|
||||
retbleed= [X86] Control mitigation of RETBleed (Arbitrary
|
||||
Speculative Code Execution with Return Instructions)
|
||||
|
@ -133,6 +133,7 @@ config ARM64
|
||||
select GENERIC_ARCH_TOPOLOGY
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_CPU_VULNERABILITIES
|
||||
select GENERIC_EARLY_IOREMAP
|
||||
select GENERIC_IDLE_POLL_SETUP
|
||||
|
@ -38,7 +38,6 @@ struct cpuinfo_32bit {
|
||||
};
|
||||
|
||||
struct cpuinfo_arm64 {
|
||||
struct cpu cpu;
|
||||
struct kobject kobj;
|
||||
u64 reg_ctr;
|
||||
u64 reg_cntfrq;
|
||||
|
@ -402,19 +402,10 @@ static inline bool cpu_can_disable(unsigned int cpu)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __init topology_init(void)
|
||||
bool arch_cpu_is_hotpluggable(int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
|
||||
cpu->hotpluggable = cpu_can_disable(i);
|
||||
register_cpu(cpu, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpu_can_disable(num);
|
||||
}
|
||||
subsys_initcall(topology_init);
|
||||
|
||||
static void dump_kernel_offset(void)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ config LOONGARCH
|
||||
select ACPI
|
||||
select ACPI_GENERIC_GSI if ACPI
|
||||
select ACPI_MCFG if ACPI
|
||||
select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU
|
||||
select ACPI_PPTT if ACPI
|
||||
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
|
||||
select ARCH_BINFMT_ELF_STATE
|
||||
@ -71,6 +72,7 @@ config LOONGARCH
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CMOS_UPDATE
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_ENTRY
|
||||
select GENERIC_GETTIMEOFDAY
|
||||
select GENERIC_IOREMAP if !ARCH_IOREMAP
|
||||
|
@ -10,47 +10,9 @@
|
||||
|
||||
#include <acpi/processor.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
int arch_register_cpu(int cpu)
|
||||
bool arch_cpu_is_hotpluggable(int cpu)
|
||||
{
|
||||
int ret;
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
|
||||
c->hotpluggable = 1;
|
||||
ret = register_cpu(c, cpu);
|
||||
if (ret < 0)
|
||||
pr_warn("register_cpu %d failed (%d)\n", cpu, ret);
|
||||
|
||||
return ret;
|
||||
return !io_master(cpu);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_register_cpu);
|
||||
|
||||
void arch_unregister_cpu(int cpu)
|
||||
{
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
|
||||
c->hotpluggable = 0;
|
||||
unregister_cpu(c);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_unregister_cpu);
|
||||
#endif
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for_each_present_cpu(i) {
|
||||
struct cpu *c = &per_cpu(cpu_devices, i);
|
||||
|
||||
c->hotpluggable = !io_master(i);
|
||||
ret = register_cpu(c, i);
|
||||
if (ret < 0)
|
||||
pr_warn("topology_init: register_cpu %d failed (%d)\n", i, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(topology_init);
|
||||
|
@ -72,6 +72,7 @@ config RISCV
|
||||
select GENERIC_ARCH_TOPOLOGY
|
||||
select GENERIC_ATOMIC64 if !64BIT
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_EARLY_IOREMAP
|
||||
select GENERIC_ENTRY
|
||||
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
|
||||
|
@ -50,7 +50,6 @@ atomic_t hart_lottery __section(".sdata")
|
||||
#endif
|
||||
;
|
||||
unsigned long boot_cpu_hartid;
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
/*
|
||||
* Place kernel memory regions on the resource tree so that
|
||||
@ -298,23 +297,10 @@ void __init setup_arch(char **cmdline_p)
|
||||
riscv_user_isa_enable();
|
||||
}
|
||||
|
||||
static int __init topology_init(void)
|
||||
bool arch_cpu_is_hotpluggable(int cpu)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cpu *cpu = &per_cpu(cpu_devices, i);
|
||||
|
||||
cpu->hotpluggable = cpu_has_hotplug(i);
|
||||
ret = register_cpu(cpu, i);
|
||||
if (unlikely(ret))
|
||||
pr_warn("Warning: %s: register_cpu %d failed (%d)\n",
|
||||
__func__, i, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpu_has_hotplug(cpu);
|
||||
}
|
||||
subsys_initcall(topology_init);
|
||||
|
||||
void free_initmem(void)
|
||||
{
|
||||
|
@ -59,6 +59,7 @@ config X86
|
||||
#
|
||||
select ACPI_LEGACY_TABLES_LOOKUP if ACPI
|
||||
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
|
||||
select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU
|
||||
select ARCH_32BIT_OFF_T if X86_32
|
||||
select ARCH_CLOCKSOURCE_INIT
|
||||
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
|
||||
@ -148,6 +149,7 @@ config X86
|
||||
select GENERIC_CLOCKEVENTS_MIN_ADJUST
|
||||
select GENERIC_CMOS_UPDATE
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_CPU_VULNERABILITIES
|
||||
select GENERIC_EARLY_IOREMAP
|
||||
select GENERIC_ENTRY
|
||||
|
@ -23,10 +23,6 @@ static inline void prefill_possible_map(void) {}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
struct x86_cpu {
|
||||
struct cpu cpu;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
extern void soft_restart_cpu(void);
|
||||
#endif
|
||||
|
@ -35,38 +35,9 @@
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/cpu.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
int arch_register_cpu(int cpu)
|
||||
bool arch_cpu_is_hotpluggable(int cpu)
|
||||
{
|
||||
struct x86_cpu *xc = per_cpu_ptr(&cpu_devices, cpu);
|
||||
|
||||
xc->cpu.hotpluggable = cpu > 0;
|
||||
return register_cpu(&xc->cpu, cpu);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_register_cpu);
|
||||
|
||||
void arch_unregister_cpu(int num)
|
||||
{
|
||||
unregister_cpu(&per_cpu(cpu_devices, num).cpu);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_unregister_cpu);
|
||||
#else /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
int __init arch_register_cpu(int num)
|
||||
{
|
||||
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
|
||||
return cpu > 0;
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_present_cpu(i)
|
||||
arch_register_cpu(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(topology_init);
|
||||
|
@ -314,7 +314,6 @@ config ACPI_HOTPLUG_CPU
|
||||
bool
|
||||
depends on ACPI_PROCESSOR && HOTPLUG_CPU
|
||||
select ACPI_CONTAINER
|
||||
default y
|
||||
|
||||
config ACPI_PROCESSOR_AGGREGATOR
|
||||
tristate "Processor Aggregator"
|
||||
|
@ -184,24 +184,6 @@ static void __init acpi_pcc_cpufreq_init(void) {}
|
||||
|
||||
/* Initialization */
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
int __weak acpi_map_cpu(acpi_handle handle,
|
||||
phys_cpuid_t physid, u32 acpi_id, int *pcpu)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int __weak acpi_unmap_cpu(int cpu)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int __weak arch_register_cpu(int cpu)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
void __weak arch_unregister_cpu(int cpu) {}
|
||||
|
||||
static int acpi_processor_hotadd_init(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned long long sta;
|
||||
|
@ -881,6 +881,7 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f
|
||||
* @index: Index of the reference to return
|
||||
* @num_args: Maximum number of arguments after each reference
|
||||
* @args: Location to store the returned reference with optional arguments
|
||||
* (may be NULL)
|
||||
*
|
||||
* Find property with @name, verifify that it is a package containing at least
|
||||
* one object reference and if so, store the ACPI device object pointer to the
|
||||
@ -938,6 +939,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
if (!args)
|
||||
return 0;
|
||||
|
||||
args->fwnode = acpi_fwnode_handle(device);
|
||||
args->nargs = 0;
|
||||
|
||||
|
@ -219,20 +219,34 @@ static DECLARE_WORK(update_topology_flags_work, update_topology_flags_workfn);
|
||||
|
||||
static DEVICE_ATTR_RO(cpu_capacity);
|
||||
|
||||
static int cpu_capacity_sysctl_add(unsigned int cpu)
|
||||
{
|
||||
struct device *cpu_dev = get_cpu_device(cpu);
|
||||
|
||||
if (!cpu_dev)
|
||||
return -ENOENT;
|
||||
|
||||
device_create_file(cpu_dev, &dev_attr_cpu_capacity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_capacity_sysctl_remove(unsigned int cpu)
|
||||
{
|
||||
struct device *cpu_dev = get_cpu_device(cpu);
|
||||
|
||||
if (!cpu_dev)
|
||||
return -ENOENT;
|
||||
|
||||
device_remove_file(cpu_dev, &dev_attr_cpu_capacity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int register_cpu_capacity_sysctl(void)
|
||||
{
|
||||
int i;
|
||||
struct device *cpu;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
cpu = get_cpu_device(i);
|
||||
if (!cpu) {
|
||||
pr_err("%s: too early to get CPU%d device!\n",
|
||||
__func__, i);
|
||||
continue;
|
||||
}
|
||||
device_create_file(cpu, &dev_attr_cpu_capacity);
|
||||
}
|
||||
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "topology/cpu-capacity",
|
||||
cpu_capacity_sysctl_add, cpu_capacity_sysctl_remove);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ static void auxiliary_bus_shutdown(struct device *dev)
|
||||
auxdrv->shutdown(auxdev);
|
||||
}
|
||||
|
||||
static struct bus_type auxiliary_bus_type = {
|
||||
static const struct bus_type auxiliary_bus_type = {
|
||||
.name = "auxiliary",
|
||||
.probe = auxiliary_bus_probe,
|
||||
.remove = auxiliary_bus_remove,
|
||||
|
@ -1030,7 +1030,7 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
|
||||
list_move_tail(&a->p->knode_bus.n_node, list);
|
||||
}
|
||||
|
||||
void bus_sort_breadthfirst(struct bus_type *bus,
|
||||
void bus_sort_breadthfirst(const struct bus_type *bus,
|
||||
int (*compare)(const struct device *a,
|
||||
const struct device *b))
|
||||
{
|
||||
@ -1194,7 +1194,7 @@ static void system_root_device_release(struct device *dev)
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
static int subsys_register(struct bus_type *subsys,
|
||||
static int subsys_register(const struct bus_type *subsys,
|
||||
const struct attribute_group **groups,
|
||||
struct kobject *parent_of_root)
|
||||
{
|
||||
@ -1264,7 +1264,7 @@ static int subsys_register(struct bus_type *subsys,
|
||||
* directory itself and not some create fake root-device placed in
|
||||
* /sys/devices/system/<name>.
|
||||
*/
|
||||
int subsys_system_register(struct bus_type *subsys,
|
||||
int subsys_system_register(const struct bus_type *subsys,
|
||||
const struct attribute_group **groups)
|
||||
{
|
||||
return subsys_register(subsys, groups, &system_kset->kobj);
|
||||
@ -1282,7 +1282,7 @@ EXPORT_SYMBOL_GPL(subsys_system_register);
|
||||
* There's no restriction on device naming. This is for kernel software
|
||||
* constructs which need sysfs interface.
|
||||
*/
|
||||
int subsys_virtual_register(struct bus_type *subsys,
|
||||
int subsys_virtual_register(const struct bus_type *subsys,
|
||||
const struct attribute_group **groups)
|
||||
{
|
||||
struct kobject *virtual_dir;
|
||||
|
@ -213,6 +213,7 @@ int class_register(const struct class *cls)
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
lockdep_unregister_key(key);
|
||||
kfree(cp);
|
||||
return error;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ static int container_offline(struct device *dev)
|
||||
return cdev->offline ? cdev->offline(cdev) : 0;
|
||||
}
|
||||
|
||||
struct bus_type container_subsys = {
|
||||
const struct bus_type container_subsys = {
|
||||
.name = CONTAINER_BUS_NAME,
|
||||
.dev_name = CONTAINER_BUS_NAME,
|
||||
.online = trivial_online,
|
||||
|
@ -298,7 +298,7 @@ static inline bool device_link_flag_is_sync_state_only(u32 flags)
|
||||
* Check if @target depends on @dev or any device dependent on it (its child or
|
||||
* its consumer etc). Return 1 if that is the case or 0 otherwise.
|
||||
*/
|
||||
int device_is_dependent(struct device *dev, void *target)
|
||||
static int device_is_dependent(struct device *dev, void *target)
|
||||
{
|
||||
struct device_link *link;
|
||||
int ret;
|
||||
@ -1641,7 +1641,7 @@ static void device_links_purge(struct device *dev)
|
||||
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
|
||||
DL_FLAG_PM_RUNTIME)
|
||||
|
||||
static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON;
|
||||
static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_RPM;
|
||||
static int __init fw_devlink_setup(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
@ -4944,13 +4944,14 @@ define_dev_printk_level(_dev_info, KERN_INFO);
|
||||
*
|
||||
* return dev_err_probe(dev, err, ...);
|
||||
*
|
||||
* Note that it is deemed acceptable to use this function for error
|
||||
* prints during probe even if the @err is known to never be -EPROBE_DEFER.
|
||||
* Using this helper in your probe function is totally fine even if @err is
|
||||
* known to never be -EPROBE_DEFER.
|
||||
* The benefit compared to a normal dev_err() is the standardized format
|
||||
* of the error code and the fact that the error code is returned.
|
||||
* of the error code, it being emitted symbolically (i.e. you get "EAGAIN"
|
||||
* instead of "-35") and the fact that the error code is returned which allows
|
||||
* more compact error paths.
|
||||
*
|
||||
* Returns @err.
|
||||
*
|
||||
*/
|
||||
int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
|
||||
{
|
||||
|
@ -525,19 +525,42 @@ bool cpu_is_hotpluggable(unsigned int cpu)
|
||||
EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
|
||||
|
||||
#ifdef CONFIG_GENERIC_CPU_DEVICES
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
#endif
|
||||
DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
bool __weak arch_cpu_is_hotpluggable(int cpu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int __weak arch_register_cpu(int cpu)
|
||||
{
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
|
||||
c->hotpluggable = arch_cpu_is_hotpluggable(cpu);
|
||||
|
||||
return register_cpu(c, cpu);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
void __weak arch_unregister_cpu(int num)
|
||||
{
|
||||
unregister_cpu(&per_cpu(cpu_devices, num));
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
#endif /* CONFIG_GENERIC_CPU_DEVICES */
|
||||
|
||||
static void __init cpu_dev_register_generic(void)
|
||||
{
|
||||
#ifdef CONFIG_GENERIC_CPU_DEVICES
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
if (register_cpu(&per_cpu(cpu_devices, i), i))
|
||||
panic("Failed to register CPU device");
|
||||
if (!IS_ENABLED(CONFIG_GENERIC_CPU_DEVICES))
|
||||
return;
|
||||
|
||||
for_each_present_cpu(i) {
|
||||
ret = arch_register_cpu(i);
|
||||
if (ret)
|
||||
pr_warn("register_cpu %d failed (%d)\n", i, ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
|
||||
|
@ -313,7 +313,7 @@ static void deferred_probe_timeout_work_func(struct work_struct *work)
|
||||
|
||||
mutex_lock(&deferred_probe_mutex);
|
||||
list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe)
|
||||
dev_info(p->device, "deferred probe pending\n");
|
||||
dev_info(p->device, "deferred probe pending: %s", p->deferred_probe_reason ?: "(reason unknown)\n");
|
||||
mutex_unlock(&deferred_probe_mutex);
|
||||
|
||||
fw_devlink_probing_done();
|
||||
|
@ -35,8 +35,8 @@ void __init driver_init(void)
|
||||
of_core_init();
|
||||
platform_bus_init();
|
||||
auxiliary_bus_init();
|
||||
cpu_dev_init();
|
||||
memory_dev_init();
|
||||
node_dev_init();
|
||||
cpu_dev_init();
|
||||
container_dev_init();
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ static int isa_bus_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bus_type isa_bus_type = {
|
||||
static const struct bus_type isa_bus_type = {
|
||||
.name = "isa",
|
||||
.match = isa_bus_match,
|
||||
.probe = isa_bus_probe,
|
||||
|
@ -68,7 +68,7 @@ static inline unsigned long phys_to_block_id(unsigned long phys)
|
||||
static int memory_subsys_online(struct device *dev);
|
||||
static int memory_subsys_offline(struct device *dev);
|
||||
|
||||
static struct bus_type memory_subsys = {
|
||||
static const struct bus_type memory_subsys = {
|
||||
.name = MEMORY_CLASS_NAME,
|
||||
.dev_name = MEMORY_CLASS_NAME,
|
||||
.online = memory_subsys_online,
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/swap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static struct bus_type node_subsys = {
|
||||
static const struct bus_type node_subsys = {
|
||||
.name = "node",
|
||||
.dev_name = "node",
|
||||
};
|
||||
@ -868,11 +868,15 @@ int __register_one_node(int nid)
|
||||
{
|
||||
int error;
|
||||
int cpu;
|
||||
struct node *node;
|
||||
|
||||
node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
|
||||
if (!node_devices[nid])
|
||||
node = kzalloc(sizeof(struct node), GFP_KERNEL);
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&node->access_list);
|
||||
node_devices[nid] = node;
|
||||
|
||||
error = register_node(node_devices[nid], nid);
|
||||
|
||||
/* link cpu under this node */
|
||||
@ -881,7 +885,6 @@ int __register_one_node(int nid)
|
||||
register_cpu_under_node(cpu, nid);
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&node_devices[nid]->access_list);
|
||||
node_init_caches(nid);
|
||||
|
||||
return error;
|
||||
|
@ -793,7 +793,7 @@ static int pm_clk_notify(struct notifier_block *nb,
|
||||
* the remaining members of @clknb should be populated prior to calling this
|
||||
* routine.
|
||||
*/
|
||||
void pm_clk_add_notifier(struct bus_type *bus,
|
||||
void pm_clk_add_notifier(const struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb)
|
||||
{
|
||||
if (!bus || !clknb)
|
||||
|
@ -543,6 +543,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_property_string);
|
||||
* @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
|
||||
* @index: Index of the reference, from zero onwards.
|
||||
* @args: Result structure with reference and integer arguments.
|
||||
* May be NULL.
|
||||
*
|
||||
* Obtain a reference based on a named property in an fwnode, with
|
||||
* integer arguments.
|
||||
|
@ -28,7 +28,7 @@ struct soc_device {
|
||||
int soc_dev_num;
|
||||
};
|
||||
|
||||
static struct bus_type soc_bus_type = {
|
||||
static const struct bus_type soc_bus_type = {
|
||||
.name = "soc",
|
||||
};
|
||||
static bool soc_bus_registered;
|
||||
@ -106,7 +106,7 @@ static void soc_release(struct device *dev)
|
||||
{
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
|
||||
ida_simple_remove(&soc_ida, soc_dev->soc_dev_num);
|
||||
ida_free(&soc_ida, soc_dev->soc_dev_num);
|
||||
kfree(soc_dev->dev.groups);
|
||||
kfree(soc_dev);
|
||||
}
|
||||
@ -155,7 +155,7 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr
|
||||
soc_attr_groups[1] = soc_dev_attr->custom_attr_group;
|
||||
|
||||
/* Fetch a unique (reclaimable) SOC ID. */
|
||||
ret = ida_simple_get(&soc_ida, 0, 0, GFP_KERNEL);
|
||||
ret = ida_alloc(&soc_ida, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto out3;
|
||||
soc_dev->soc_dev_num = ret;
|
||||
|
@ -541,6 +541,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
|
||||
if (nargs > NR_FWNODE_REFERENCE_ARGS)
|
||||
return -EINVAL;
|
||||
|
||||
if (!args)
|
||||
return 0;
|
||||
|
||||
args->fwnode = software_node_get(refnode);
|
||||
args->nargs = nargs;
|
||||
|
||||
@ -747,10 +750,10 @@ static void software_node_release(struct kobject *kobj)
|
||||
struct swnode *swnode = kobj_to_swnode(kobj);
|
||||
|
||||
if (swnode->parent) {
|
||||
ida_simple_remove(&swnode->parent->child_ids, swnode->id);
|
||||
ida_free(&swnode->parent->child_ids, swnode->id);
|
||||
list_del(&swnode->entry);
|
||||
} else {
|
||||
ida_simple_remove(&swnode_root_ids, swnode->id);
|
||||
ida_free(&swnode_root_ids, swnode->id);
|
||||
}
|
||||
|
||||
if (swnode->allocated)
|
||||
@ -776,8 +779,8 @@ swnode_register(const struct software_node *node, struct swnode *parent,
|
||||
if (!swnode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
|
||||
0, 0, GFP_KERNEL);
|
||||
ret = ida_alloc(parent ? &parent->child_ids : &swnode_root_ids,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
kfree(swnode);
|
||||
return ERR_PTR(ret);
|
||||
|
@ -176,7 +176,7 @@ struct edac_device_ctl_info {
|
||||
struct edac_dev_sysfs_attribute *sysfs_attributes;
|
||||
|
||||
/* pointer to main 'edac' subsys in sysfs */
|
||||
struct bus_type *edac_subsys;
|
||||
const struct bus_type *edac_subsys;
|
||||
|
||||
/* the internal state of this controller instance */
|
||||
int op_state;
|
||||
|
@ -229,7 +229,7 @@ static struct kobj_type ktype_device_ctrl = {
|
||||
int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
|
||||
{
|
||||
struct device *dev_root;
|
||||
struct bus_type *edac_subsys;
|
||||
const struct bus_type *edac_subsys;
|
||||
int err = -ENODEV;
|
||||
|
||||
edac_dbg(1, "\n");
|
||||
|
@ -67,7 +67,7 @@ char *edac_op_state_to_string(int opstate)
|
||||
* sysfs object: /sys/devices/system/edac
|
||||
* need to export to other files
|
||||
*/
|
||||
static struct bus_type edac_subsys = {
|
||||
static const struct bus_type edac_subsys = {
|
||||
.name = "edac",
|
||||
.dev_name = "edac",
|
||||
};
|
||||
@ -90,7 +90,7 @@ static void edac_subsys_exit(void)
|
||||
}
|
||||
|
||||
/* return pointer to the 'edac' node in sysfs */
|
||||
struct bus_type *edac_get_sysfs_subsys(void)
|
||||
const struct bus_type *edac_get_sysfs_subsys(void)
|
||||
{
|
||||
return &edac_subsys;
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ static struct kobj_type ktype_edac_pci_main_kobj = {
|
||||
static int edac_pci_main_kobj_setup(void)
|
||||
{
|
||||
int err = -ENODEV;
|
||||
struct bus_type *edac_subsys;
|
||||
const struct bus_type *edac_subsys;
|
||||
struct device *dev_root;
|
||||
|
||||
edac_dbg(0, "\n");
|
||||
|
@ -2668,7 +2668,7 @@ static void genpd_release_dev(struct device *dev)
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
static struct bus_type genpd_bus_type = {
|
||||
static const struct bus_type genpd_bus_type = {
|
||||
.name = "genpd",
|
||||
};
|
||||
|
||||
|
@ -54,9 +54,9 @@ static bool kernfs_lockdep(struct kernfs_node *kn)
|
||||
static int kernfs_name_locked(struct kernfs_node *kn, char *buf, size_t buflen)
|
||||
{
|
||||
if (!kn)
|
||||
return strlcpy(buf, "(null)", buflen);
|
||||
return strscpy(buf, "(null)", buflen);
|
||||
|
||||
return strlcpy(buf, kn->parent ? kn->name : "/", buflen);
|
||||
return strscpy(buf, kn->parent ? kn->name : "/", buflen);
|
||||
}
|
||||
|
||||
/* kernfs_node_depth - compute depth from @from to @to */
|
||||
@ -127,7 +127,7 @@ static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a,
|
||||
*
|
||||
* [3] when @kn_to is %NULL result will be "(null)"
|
||||
*
|
||||
* Return: the length of the full path. If the full length is equal to or
|
||||
* Return: the length of the constructed path. If the path would have been
|
||||
* greater than @buflen, @buf contains the truncated path with the trailing
|
||||
* '\0'. On error, -errno is returned.
|
||||
*/
|
||||
@ -138,16 +138,17 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
|
||||
struct kernfs_node *kn, *common;
|
||||
const char parent_str[] = "/..";
|
||||
size_t depth_from, depth_to, len = 0;
|
||||
ssize_t copied;
|
||||
int i, j;
|
||||
|
||||
if (!kn_to)
|
||||
return strlcpy(buf, "(null)", buflen);
|
||||
return strscpy(buf, "(null)", buflen);
|
||||
|
||||
if (!kn_from)
|
||||
kn_from = kernfs_root(kn_to)->kn;
|
||||
|
||||
if (kn_from == kn_to)
|
||||
return strlcpy(buf, "/", buflen);
|
||||
return strscpy(buf, "/", buflen);
|
||||
|
||||
common = kernfs_common_ancestor(kn_from, kn_to);
|
||||
if (WARN_ON(!common))
|
||||
@ -158,18 +159,19 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
for (i = 0; i < depth_from; i++)
|
||||
len += strlcpy(buf + len, parent_str,
|
||||
len < buflen ? buflen - len : 0);
|
||||
for (i = 0; i < depth_from; i++) {
|
||||
copied = strscpy(buf + len, parent_str, buflen - len);
|
||||
if (copied < 0)
|
||||
return copied;
|
||||
len += copied;
|
||||
}
|
||||
|
||||
/* Calculate how many bytes we need for the rest */
|
||||
for (i = depth_to - 1; i >= 0; i--) {
|
||||
for (kn = kn_to, j = 0; j < i; j++)
|
||||
kn = kn->parent;
|
||||
len += strlcpy(buf + len, "/",
|
||||
len < buflen ? buflen - len : 0);
|
||||
len += strlcpy(buf + len, kn->name,
|
||||
len < buflen ? buflen - len : 0);
|
||||
|
||||
len += scnprintf(buf + len, buflen - len, "/%s", kn->name);
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -182,12 +184,12 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
|
||||
* @buflen: size of @buf
|
||||
*
|
||||
* Copies the name of @kn into @buf of @buflen bytes. The behavior is
|
||||
* similar to strlcpy().
|
||||
* similar to strscpy().
|
||||
*
|
||||
* Fills buffer with "(null)" if @kn is %NULL.
|
||||
*
|
||||
* Return: the length of @kn's name and if @buf isn't long enough,
|
||||
* it's filled up to @buflen-1 and nul terminated.
|
||||
* Return: the resulting length of @buf. If @buf isn't long enough,
|
||||
* it's filled up to @buflen-1 and nul terminated, and returns -E2BIG.
|
||||
*
|
||||
* This function can be called from any context.
|
||||
*/
|
||||
@ -214,7 +216,7 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen)
|
||||
* path (which includes '..'s) as needed to reach from @from to @to is
|
||||
* returned.
|
||||
*
|
||||
* Return: the length of the full path. If the full length is equal to or
|
||||
* Return: the length of the constructed path. If the path would have been
|
||||
* greater than @buflen, @buf contains the truncated path with the trailing
|
||||
* '\0'. On error, -errno is returned.
|
||||
*/
|
||||
@ -265,12 +267,10 @@ void pr_cont_kernfs_path(struct kernfs_node *kn)
|
||||
sz = kernfs_path_from_node(kn, NULL, kernfs_pr_cont_buf,
|
||||
sizeof(kernfs_pr_cont_buf));
|
||||
if (sz < 0) {
|
||||
pr_cont("(error)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sz >= sizeof(kernfs_pr_cont_buf)) {
|
||||
pr_cont("(name too long)");
|
||||
if (sz == -E2BIG)
|
||||
pr_cont("(name too long)");
|
||||
else
|
||||
pr_cont("(error)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -676,6 +676,18 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
|
||||
{
|
||||
struct kernfs_node *kn;
|
||||
|
||||
if (parent->mode & S_ISGID) {
|
||||
/* this code block imitates inode_init_owner() for
|
||||
* kernfs
|
||||
*/
|
||||
|
||||
if (parent->iattr)
|
||||
gid = parent->iattr->ia_gid;
|
||||
|
||||
if (flags & KERNFS_DIR)
|
||||
mode |= S_ISGID;
|
||||
}
|
||||
|
||||
kn = __kernfs_new_node(kernfs_root(parent), parent,
|
||||
name, mode, uid, gid, flags);
|
||||
if (kn) {
|
||||
@ -850,16 +862,16 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
|
||||
const unsigned char *path,
|
||||
const void *ns)
|
||||
{
|
||||
size_t len;
|
||||
ssize_t len;
|
||||
char *p, *name;
|
||||
|
||||
lockdep_assert_held_read(&kernfs_root(parent)->kernfs_rwsem);
|
||||
|
||||
spin_lock_irq(&kernfs_pr_cont_lock);
|
||||
|
||||
len = strlcpy(kernfs_pr_cont_buf, path, sizeof(kernfs_pr_cont_buf));
|
||||
len = strscpy(kernfs_pr_cont_buf, path, sizeof(kernfs_pr_cont_buf));
|
||||
|
||||
if (len >= sizeof(kernfs_pr_cont_buf)) {
|
||||
if (len < 0) {
|
||||
spin_unlock_irq(&kernfs_pr_cont_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
* warnings and we don't want to add spurious locking dependency
|
||||
* between the two. Check whether mmap is actually implemented
|
||||
* without grabbing @of->mutex by testing HAS_MMAP flag. See the
|
||||
* comment in kernfs_file_open() for more details.
|
||||
* comment in kernfs_fop_open() for more details.
|
||||
*/
|
||||
if (!(of->kn->flags & KERNFS_HAS_MMAP))
|
||||
return -ENODEV;
|
||||
|
@ -125,9 +125,6 @@ static struct dentry *__kernfs_fh_to_dentry(struct super_block *sb,
|
||||
|
||||
inode = kernfs_get_inode(sb, kn);
|
||||
kernfs_put(kn);
|
||||
if (!inode)
|
||||
return ERR_PTR(-ESTALE);
|
||||
|
||||
return d_obtain_alias(inode);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ void sysfs_remove_dir(struct kobject *kobj)
|
||||
struct kernfs_node *kn = kobj->sd;
|
||||
|
||||
/*
|
||||
* In general, kboject owner is responsible for ensuring removal
|
||||
* In general, kobject owner is responsible for ensuring removal
|
||||
* doesn't race with other operations and sysfs doesn't provide any
|
||||
* protection; however, when @kobj is used as a symlink target, the
|
||||
* symlinking entity usually doesn't own @kobj and thus has no
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/device.h>
|
||||
|
||||
/* drivers/base/power/container.c */
|
||||
extern struct bus_type container_subsys;
|
||||
extern const struct bus_type container_subsys;
|
||||
|
||||
struct container_dev {
|
||||
struct device dev;
|
||||
|
@ -80,6 +80,7 @@ extern __printf(4, 5)
|
||||
struct device *cpu_device_create(struct device *parent, void *drvdata,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...);
|
||||
extern bool arch_cpu_is_hotpluggable(int cpu);
|
||||
extern int arch_register_cpu(int cpu);
|
||||
extern void arch_unregister_cpu(int cpu);
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
@ -88,6 +89,10 @@ extern ssize_t arch_cpu_probe(const char *, size_t);
|
||||
extern ssize_t arch_cpu_release(const char *, size_t);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GENERIC_CPU_DEVICES
|
||||
DECLARE_PER_CPU(struct cpu, cpu_devices);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These states are not related to the core CPU hotplug mechanism. They are
|
||||
* used by various (sub)architectures to track internal state
|
||||
|
@ -63,7 +63,7 @@ struct msi_device_data;
|
||||
*/
|
||||
struct subsys_interface {
|
||||
const char *name;
|
||||
struct bus_type *subsys;
|
||||
const struct bus_type *subsys;
|
||||
struct list_head node;
|
||||
int (*add_dev)(struct device *dev, struct subsys_interface *sif);
|
||||
void (*remove_dev)(struct device *dev, struct subsys_interface *sif);
|
||||
@ -72,9 +72,9 @@ struct subsys_interface {
|
||||
int subsys_interface_register(struct subsys_interface *sif);
|
||||
void subsys_interface_unregister(struct subsys_interface *sif);
|
||||
|
||||
int subsys_system_register(struct bus_type *subsys,
|
||||
int subsys_system_register(const struct bus_type *subsys,
|
||||
const struct attribute_group **groups);
|
||||
int subsys_virtual_register(struct bus_type *subsys,
|
||||
int subsys_virtual_register(const struct bus_type *subsys,
|
||||
const struct attribute_group **groups);
|
||||
|
||||
/*
|
||||
@ -662,7 +662,6 @@ struct device_physical_location {
|
||||
* @id: device instance
|
||||
* @devres_lock: Spinlock to protect the resource of the device.
|
||||
* @devres_head: The resources list of the device.
|
||||
* @knode_class: The node used to add the device to the class list.
|
||||
* @class: The class of the device.
|
||||
* @groups: Optional attribute groups.
|
||||
* @release: Callback to free the device after all references have
|
||||
@ -1073,7 +1072,6 @@ int device_rename(struct device *dev, const char *new_name);
|
||||
int device_move(struct device *dev, struct device *new_parent,
|
||||
enum dpm_order dpm_order);
|
||||
int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid);
|
||||
int device_is_dependent(struct device *dev, void *target);
|
||||
|
||||
static inline bool device_supports_offline(struct device *dev)
|
||||
{
|
||||
|
@ -232,7 +232,7 @@ bus_find_device_by_acpi_dev(const struct bus_type *bus, const void *adev)
|
||||
|
||||
int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start,
|
||||
void *data, int (*fn)(struct device_driver *, void *));
|
||||
void bus_sort_breadthfirst(struct bus_type *bus,
|
||||
void bus_sort_breadthfirst(const struct bus_type *bus,
|
||||
int (*compare)(const struct device *a,
|
||||
const struct device *b));
|
||||
/*
|
||||
|
@ -40,8 +40,6 @@ struct fwnode_handle;
|
||||
* for the devices belonging to the class. Usually tied to
|
||||
* device's namespace.
|
||||
* @pm: The default device power management operations of this class.
|
||||
* @p: The private data of the driver core, no one other than the
|
||||
* driver core can touch this.
|
||||
*
|
||||
* A class is a higher-level view of a device that abstracts out low-level
|
||||
* implementation details. Drivers may see a SCSI disk or an ATA disk, but,
|
||||
|
@ -30,7 +30,7 @@ struct device;
|
||||
|
||||
extern int edac_op_state;
|
||||
|
||||
struct bus_type *edac_get_sysfs_subsys(void);
|
||||
const struct bus_type *edac_get_sysfs_subsys(void);
|
||||
|
||||
static inline void opstate_init(void)
|
||||
{
|
||||
@ -495,7 +495,7 @@ struct edac_raw_error_desc {
|
||||
*/
|
||||
struct mem_ctl_info {
|
||||
struct device dev;
|
||||
struct bus_type *bus;
|
||||
const struct bus_type *bus;
|
||||
|
||||
struct list_head link; /* for global list of mem_ctl_info structs */
|
||||
|
||||
|
@ -91,10 +91,10 @@ static inline int devm_pm_clk_create(struct device *dev)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
extern void pm_clk_add_notifier(struct bus_type *bus,
|
||||
extern void pm_clk_add_notifier(const struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb);
|
||||
#else
|
||||
static inline void pm_clk_add_notifier(struct bus_type *bus,
|
||||
static inline void pm_clk_add_notifier(const struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb)
|
||||
{
|
||||
}
|
||||
|
@ -574,6 +574,16 @@ extern unsigned long __initramfs_size;
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/kexec.h>
|
||||
|
||||
static ssize_t raw_read(struct file *file, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t pos, size_t count)
|
||||
{
|
||||
memcpy(buf, attr->private + pos, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static BIN_ATTR(initrd, 0440, raw_read, NULL, 0);
|
||||
|
||||
void __init reserve_initrd_mem(void)
|
||||
{
|
||||
phys_addr_t start;
|
||||
@ -715,8 +725,14 @@ static void __init do_populate_rootfs(void *unused, async_cookie_t cookie)
|
||||
* If the initrd region is overlapped with crashkernel reserved region,
|
||||
* free only memory that is not part of crashkernel region.
|
||||
*/
|
||||
if (!do_retain_initrd && initrd_start && !kexec_free_initrd())
|
||||
if (!do_retain_initrd && initrd_start && !kexec_free_initrd()) {
|
||||
free_initrd_mem(initrd_start, initrd_end);
|
||||
} else if (do_retain_initrd && initrd_start) {
|
||||
bin_attr_initrd.size = initrd_end - initrd_start;
|
||||
bin_attr_initrd.private = (void *)initrd_start;
|
||||
if (sysfs_create_bin_file(firmware_kobj, &bin_attr_initrd))
|
||||
pr_err("Failed to create initrd sysfs file");
|
||||
}
|
||||
initrd_start = 0;
|
||||
initrd_end = 0;
|
||||
|
||||
|
@ -802,7 +802,7 @@ void cgroup1_release_agent(struct work_struct *work)
|
||||
goto out_free;
|
||||
|
||||
ret = cgroup_path_ns(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns);
|
||||
if (ret < 0 || ret >= PATH_MAX)
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
|
||||
argv[0] = agentbuf;
|
||||
|
@ -1906,7 +1906,7 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,
|
||||
len = kernfs_path_from_node(kf_node, ns_cgroup->kn, buf, PATH_MAX);
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
|
||||
if (len >= PATH_MAX)
|
||||
if (len == -E2BIG)
|
||||
len = -ERANGE;
|
||||
else if (len > 0) {
|
||||
seq_escape(sf, buf, " \t\n\\");
|
||||
@ -4182,20 +4182,6 @@ static struct kernfs_ops cgroup_kf_ops = {
|
||||
.seq_show = cgroup_seqfile_show,
|
||||
};
|
||||
|
||||
/* set uid and gid of cgroup dirs and files to that of the creator */
|
||||
static int cgroup_kn_set_ugid(struct kernfs_node *kn)
|
||||
{
|
||||
struct iattr iattr = { .ia_valid = ATTR_UID | ATTR_GID,
|
||||
.ia_uid = current_fsuid(),
|
||||
.ia_gid = current_fsgid(), };
|
||||
|
||||
if (uid_eq(iattr.ia_uid, GLOBAL_ROOT_UID) &&
|
||||
gid_eq(iattr.ia_gid, GLOBAL_ROOT_GID))
|
||||
return 0;
|
||||
|
||||
return kernfs_setattr(kn, &iattr);
|
||||
}
|
||||
|
||||
static void cgroup_file_notify_timer(struct timer_list *timer)
|
||||
{
|
||||
cgroup_file_notify(container_of(timer, struct cgroup_file,
|
||||
@ -4208,25 +4194,18 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
|
||||
char name[CGROUP_FILE_NAME_MAX];
|
||||
struct kernfs_node *kn;
|
||||
struct lock_class_key *key = NULL;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
key = &cft->lockdep_key;
|
||||
#endif
|
||||
kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name),
|
||||
cgroup_file_mode(cft),
|
||||
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
|
||||
current_fsuid(), current_fsgid(),
|
||||
0, cft->kf_ops, cft,
|
||||
NULL, key);
|
||||
if (IS_ERR(kn))
|
||||
return PTR_ERR(kn);
|
||||
|
||||
ret = cgroup_kn_set_ugid(kn);
|
||||
if (ret) {
|
||||
kernfs_remove(kn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cft->file_offset) {
|
||||
struct cgroup_file *cfile = (void *)css + cft->file_offset;
|
||||
|
||||
@ -5629,7 +5608,9 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
|
||||
goto out_cancel_ref;
|
||||
|
||||
/* create the directory */
|
||||
kn = kernfs_create_dir(parent->kn, name, mode, cgrp);
|
||||
kn = kernfs_create_dir_ns(parent->kn, name, mode,
|
||||
current_fsuid(), current_fsgid(),
|
||||
cgrp, NULL);
|
||||
if (IS_ERR(kn)) {
|
||||
ret = PTR_ERR(kn);
|
||||
goto out_stat_exit;
|
||||
@ -5774,10 +5755,6 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode)
|
||||
*/
|
||||
kernfs_get(cgrp->kn);
|
||||
|
||||
ret = cgroup_kn_set_ugid(cgrp->kn);
|
||||
if (ret)
|
||||
goto out_destroy;
|
||||
|
||||
ret = css_populate_dir(&cgrp->self);
|
||||
if (ret)
|
||||
goto out_destroy;
|
||||
@ -6316,7 +6293,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) {
|
||||
retval = cgroup_path_ns_locked(cgrp, buf, PATH_MAX,
|
||||
current->nsproxy->cgroup_ns);
|
||||
if (retval >= PATH_MAX)
|
||||
if (retval == -E2BIG)
|
||||
retval = -ENAMETOOLONG;
|
||||
if (retval < 0)
|
||||
goto out_unlock;
|
||||
|
@ -5092,7 +5092,7 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
|
||||
current->nsproxy->cgroup_ns);
|
||||
css_put(css);
|
||||
if (retval >= PATH_MAX)
|
||||
if (retval == -E2BIG)
|
||||
retval = -ENAMETOOLONG;
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
|
Loading…
Reference in New Issue
Block a user