linux/drivers/base/cpu.c

// SPDX-License-Identifier: GPL-2.0
/*
 * CPU subsystem support
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/cpu.h>
#include <linux/topology.h>
#include <linux/device.h>
#include <linux/node.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/cpufeature.h>
#include <linux/tick.h>
#include <linux/pm_qos.h>
#include <linux/delay.h>
#include <linux/sched/isolation.h>

#include "base.h"

static DEFINE_PER_CPU(struct device *, cpu_sys_devices);

static int cpu_subsys_match(struct device *dev, const struct device_driver *drv)
{}

#ifdef CONFIG_HOTPLUG_CPU
static void change_cpu_under_node(struct cpu *cpu,
			unsigned int from_nid, unsigned int to_nid)
{}

static int cpu_subsys_online(struct device *dev)
{}

static int cpu_subsys_offline(struct device *dev)
{}

void unregister_cpu(struct cpu *cpu)
{}

#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t cpu_probe_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf,
			       size_t count)
{
	ssize_t cnt;
	int ret;

	ret = lock_device_hotplug_sysfs();
	if (ret)
		return ret;

	cnt = arch_cpu_probe(buf, count);

	unlock_device_hotplug();
	return cnt;
}

static ssize_t cpu_release_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf,
				 size_t count)
{
	ssize_t cnt;
	int ret;

	ret = lock_device_hotplug_sysfs();
	if (ret)
		return ret;

	cnt = arch_cpu_release(buf, count);

	unlock_device_hotplug();
	return cnt;
}

static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#endif /* CONFIG_HOTPLUG_CPU */

#ifdef CONFIG_CRASH_DUMP
#include <linux/kexec.h>

static ssize_t crash_notes_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{}
static DEVICE_ATTR_ADMIN_RO(crash_notes);

static ssize_t crash_notes_size_show(struct device *dev,
				     struct device_attribute *attr,
				     char *buf)
{}
static DEVICE_ATTR_ADMIN_RO(crash_notes_size);

static struct attribute *crash_note_cpu_attrs[] =;

static const struct attribute_group crash_note_cpu_attr_group =;
#endif

static const struct attribute_group *common_cpu_attr_groups[] =;

static const struct attribute_group *hotplugable_cpu_attr_groups[] =;

/*
 * Print cpu online, possible, present, and system maps
 */

struct cpu_attr {};

static ssize_t show_cpus_attr(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{}

#define _CPU_ATTR(name, map)

/* Keep in sync with cpu_subsys_attrs */
static struct cpu_attr cpu_attrs[] =;

/*
 * Print values for NR_CPUS and offlined cpus
 */
static ssize_t print_cpus_kernel_max(struct device *dev,
				     struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);

/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
unsigned int total_cpus;

static ssize_t print_cpus_offline(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);

static ssize_t print_cpus_enabled(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(enabled, 0444, print_cpus_enabled, NULL);

static ssize_t print_cpus_isolated(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);

#ifdef CONFIG_NO_HZ_FULL
static ssize_t print_cpus_nohz_full(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask));
}
static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL);
#endif

#ifdef CONFIG_CRASH_HOTPLUG
static ssize_t crash_hotplug_show(struct device *dev,
				     struct device_attribute *attr,
				     char *buf)
{}
static DEVICE_ATTR_RO(crash_hotplug);
#endif

static void cpu_device_release(struct device *dev)
{}

#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
static ssize_t print_cpu_modalias(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{}

static int cpu_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}
#endif

const struct bus_type cpu_subsys =;
EXPORT_SYMBOL_GPL();

/*
 * register_cpu - Setup a sysfs device for a CPU.
 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
 *	  sysfs for this CPU.
 * @num - CPU number to use when creating the device.
 *
 * Initialize and register the CPU device.
 */
int register_cpu(struct cpu *cpu, int num)
{}

struct device *get_cpu_device(unsigned int cpu)
{}
EXPORT_SYMBOL_GPL();

static void device_create_release(struct device *dev)
{}

__printf(4, 0)
static struct device *
__cpu_device_create(struct device *parent, void *drvdata,
		    const struct attribute_group **groups,
		    const char *fmt, va_list args)
{}

struct device *cpu_device_create(struct device *parent, void *drvdata,
				 const struct attribute_group **groups,
				 const char *fmt, ...)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
#endif

static struct attribute *cpu_root_attrs[] =;

static const struct attribute_group cpu_root_attr_group =;

static const struct attribute_group *cpu_root_attr_groups[] =;

bool cpu_is_hotpluggable(unsigned int cpu)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_GENERIC_CPU_DEVICES
DEFINE_PER_CPU(struct cpu, cpu_devices);

bool __weak arch_cpu_is_hotpluggable(int cpu)
{}

int __weak arch_register_cpu(int cpu)
{}

#ifdef CONFIG_HOTPLUG_CPU
void __weak arch_unregister_cpu(int num)
{}
#endif /* CONFIG_HOTPLUG_CPU */
#endif /* CONFIG_GENERIC_CPU_DEVICES */

static void __init cpu_dev_register_generic(void)
{}

#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
static ssize_t cpu_show_not_affected(struct device *dev,
			      struct device_attribute *attr, char *buf)
{}

#define CPU_SHOW_VULN_FALLBACK(func)

CPU_SHOW_VULN_FALLBACK(meltdown);
CPU_SHOW_VULN_FALLBACK(spectre_v1);
CPU_SHOW_VULN_FALLBACK(spectre_v2);
CPU_SHOW_VULN_FALLBACK(spec_store_bypass);
CPU_SHOW_VULN_FALLBACK(l1tf);
CPU_SHOW_VULN_FALLBACK(mds);
CPU_SHOW_VULN_FALLBACK(tsx_async_abort);
CPU_SHOW_VULN_FALLBACK(itlb_multihit);
CPU_SHOW_VULN_FALLBACK(srbds);
CPU_SHOW_VULN_FALLBACK(mmio_stale_data);
CPU_SHOW_VULN_FALLBACK(retbleed);
CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow);
CPU_SHOW_VULN_FALLBACK(gds);
CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling);

static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL);
static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);
static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL);
static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL);

static struct attribute *cpu_root_vulnerabilities_attrs[] =;

static const struct attribute_group cpu_root_vulnerabilities_group =;

static void __init cpu_register_vulnerabilities(void)
{}

#else
static inline void cpu_register_vulnerabilities(void) { }
#endif

void __init cpu_dev_init(void)
{}