#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
#endif
#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[] = …;
struct cpu_attr { … };
static ssize_t show_cpus_attr(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
#define _CPU_ATTR(name, map) …
static struct cpu_attr cpu_attrs[] = …;
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);
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(…);
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
#endif
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)
{ … }