LCOV - code coverage report
Current view: top level - drivers/base - cpu.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 28 89 31.5 %
Date: 2023-03-27 20:00:47 Functions: 4 14 28.6 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * CPU subsystem support
       4             :  */
       5             : 
       6             : #include <linux/kernel.h>
       7             : #include <linux/module.h>
       8             : #include <linux/init.h>
       9             : #include <linux/sched.h>
      10             : #include <linux/cpu.h>
      11             : #include <linux/topology.h>
      12             : #include <linux/device.h>
      13             : #include <linux/node.h>
      14             : #include <linux/gfp.h>
      15             : #include <linux/slab.h>
      16             : #include <linux/percpu.h>
      17             : #include <linux/acpi.h>
      18             : #include <linux/of.h>
      19             : #include <linux/cpufeature.h>
      20             : #include <linux/tick.h>
      21             : #include <linux/pm_qos.h>
      22             : #include <linux/sched/isolation.h>
      23             : 
      24             : #include "base.h"
      25             : 
      26             : static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
      27             : 
      28           0 : static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
      29             : {
      30             :         /* ACPI style match is the only one that may succeed. */
      31           0 :         if (acpi_driver_match_device(dev, drv))
      32             :                 return 1;
      33             : 
      34             :         return 0;
      35             : }
      36             : 
      37             : #ifdef CONFIG_HOTPLUG_CPU
      38             : static void change_cpu_under_node(struct cpu *cpu,
      39             :                         unsigned int from_nid, unsigned int to_nid)
      40             : {
      41             :         int cpuid = cpu->dev.id;
      42             :         unregister_cpu_under_node(cpuid, from_nid);
      43             :         register_cpu_under_node(cpuid, to_nid);
      44             :         cpu->node_id = to_nid;
      45             : }
      46             : 
      47             : static int cpu_subsys_online(struct device *dev)
      48             : {
      49             :         struct cpu *cpu = container_of(dev, struct cpu, dev);
      50             :         int cpuid = dev->id;
      51             :         int from_nid, to_nid;
      52             :         int ret;
      53             : 
      54             :         from_nid = cpu_to_node(cpuid);
      55             :         if (from_nid == NUMA_NO_NODE)
      56             :                 return -ENODEV;
      57             : 
      58             :         ret = cpu_device_up(dev);
      59             :         /*
      60             :          * When hot adding memory to memoryless node and enabling a cpu
      61             :          * on the node, node number of the cpu may internally change.
      62             :          */
      63             :         to_nid = cpu_to_node(cpuid);
      64             :         if (from_nid != to_nid)
      65             :                 change_cpu_under_node(cpu, from_nid, to_nid);
      66             : 
      67             :         return ret;
      68             : }
      69             : 
      70             : static int cpu_subsys_offline(struct device *dev)
      71             : {
      72             :         return cpu_device_down(dev);
      73             : }
      74             : 
      75             : void unregister_cpu(struct cpu *cpu)
      76             : {
      77             :         int logical_cpu = cpu->dev.id;
      78             : 
      79             :         unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
      80             : 
      81             :         device_unregister(&cpu->dev);
      82             :         per_cpu(cpu_sys_devices, logical_cpu) = NULL;
      83             :         return;
      84             : }
      85             : 
      86             : #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
      87             : static ssize_t cpu_probe_store(struct device *dev,
      88             :                                struct device_attribute *attr,
      89             :                                const char *buf,
      90             :                                size_t count)
      91             : {
      92             :         ssize_t cnt;
      93             :         int ret;
      94             : 
      95             :         ret = lock_device_hotplug_sysfs();
      96             :         if (ret)
      97             :                 return ret;
      98             : 
      99             :         cnt = arch_cpu_probe(buf, count);
     100             : 
     101             :         unlock_device_hotplug();
     102             :         return cnt;
     103             : }
     104             : 
     105             : static ssize_t cpu_release_store(struct device *dev,
     106             :                                  struct device_attribute *attr,
     107             :                                  const char *buf,
     108             :                                  size_t count)
     109             : {
     110             :         ssize_t cnt;
     111             :         int ret;
     112             : 
     113             :         ret = lock_device_hotplug_sysfs();
     114             :         if (ret)
     115             :                 return ret;
     116             : 
     117             :         cnt = arch_cpu_release(buf, count);
     118             : 
     119             :         unlock_device_hotplug();
     120             :         return cnt;
     121             : }
     122             : 
     123             : static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
     124             : static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
     125             : #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
     126             : #endif /* CONFIG_HOTPLUG_CPU */
     127             : 
     128             : #ifdef CONFIG_KEXEC
     129             : #include <linux/kexec.h>
     130             : 
     131             : static ssize_t crash_notes_show(struct device *dev,
     132             :                                 struct device_attribute *attr,
     133             :                                 char *buf)
     134             : {
     135             :         struct cpu *cpu = container_of(dev, struct cpu, dev);
     136             :         unsigned long long addr;
     137             :         int cpunum;
     138             : 
     139             :         cpunum = cpu->dev.id;
     140             : 
     141             :         /*
     142             :          * Might be reading other cpu's data based on which cpu read thread
     143             :          * has been scheduled. But cpu data (memory) is allocated once during
     144             :          * boot up and this data does not change there after. Hence this
     145             :          * operation should be safe. No locking required.
     146             :          */
     147             :         addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
     148             : 
     149             :         return sysfs_emit(buf, "%llx\n", addr);
     150             : }
     151             : static DEVICE_ATTR_ADMIN_RO(crash_notes);
     152             : 
     153             : static ssize_t crash_notes_size_show(struct device *dev,
     154             :                                      struct device_attribute *attr,
     155             :                                      char *buf)
     156             : {
     157             :         return sysfs_emit(buf, "%zu\n", sizeof(note_buf_t));
     158             : }
     159             : static DEVICE_ATTR_ADMIN_RO(crash_notes_size);
     160             : 
     161             : static struct attribute *crash_note_cpu_attrs[] = {
     162             :         &dev_attr_crash_notes.attr,
     163             :         &dev_attr_crash_notes_size.attr,
     164             :         NULL
     165             : };
     166             : 
     167             : static const struct attribute_group crash_note_cpu_attr_group = {
     168             :         .attrs = crash_note_cpu_attrs,
     169             : };
     170             : #endif
     171             : 
     172             : static const struct attribute_group *common_cpu_attr_groups[] = {
     173             : #ifdef CONFIG_KEXEC
     174             :         &crash_note_cpu_attr_group,
     175             : #endif
     176             :         NULL
     177             : };
     178             : 
     179             : static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
     180             : #ifdef CONFIG_KEXEC
     181             :         &crash_note_cpu_attr_group,
     182             : #endif
     183             :         NULL
     184             : };
     185             : 
     186             : /*
     187             :  * Print cpu online, possible, present, and system maps
     188             :  */
     189             : 
     190             : struct cpu_attr {
     191             :         struct device_attribute attr;
     192             :         const struct cpumask *const map;
     193             : };
     194             : 
     195           0 : static ssize_t show_cpus_attr(struct device *dev,
     196             :                               struct device_attribute *attr,
     197             :                               char *buf)
     198             : {
     199           0 :         struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
     200             : 
     201           0 :         return cpumap_print_to_pagebuf(true, buf, ca->map);
     202             : }
     203             : 
     204             : #define _CPU_ATTR(name, map) \
     205             :         { __ATTR(name, 0444, show_cpus_attr, NULL), map }
     206             : 
     207             : /* Keep in sync with cpu_subsys_attrs */
     208             : static struct cpu_attr cpu_attrs[] = {
     209             :         _CPU_ATTR(online, &__cpu_online_mask),
     210             :         _CPU_ATTR(possible, &__cpu_possible_mask),
     211             :         _CPU_ATTR(present, &__cpu_present_mask),
     212             : };
     213             : 
     214             : /*
     215             :  * Print values for NR_CPUS and offlined cpus
     216             :  */
     217           0 : static ssize_t print_cpus_kernel_max(struct device *dev,
     218             :                                      struct device_attribute *attr, char *buf)
     219             : {
     220           0 :         return sysfs_emit(buf, "%d\n", NR_CPUS - 1);
     221             : }
     222             : static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
     223             : 
     224             : /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
     225             : unsigned int total_cpus;
     226             : 
     227           0 : static ssize_t print_cpus_offline(struct device *dev,
     228             :                                   struct device_attribute *attr, char *buf)
     229             : {
     230           0 :         int len = 0;
     231             :         cpumask_var_t offline;
     232             : 
     233             :         /* display offline cpus < nr_cpu_ids */
     234           0 :         if (!alloc_cpumask_var(&offline, GFP_KERNEL))
     235             :                 return -ENOMEM;
     236           0 :         cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
     237           0 :         len += sysfs_emit_at(buf, len, "%*pbl", cpumask_pr_args(offline));
     238           0 :         free_cpumask_var(offline);
     239             : 
     240             :         /* display offline cpus >= nr_cpu_ids */
     241           0 :         if (total_cpus && nr_cpu_ids < total_cpus) {
     242           0 :                 len += sysfs_emit_at(buf, len, ",");
     243             : 
     244           0 :                 if (nr_cpu_ids == total_cpus-1)
     245           0 :                         len += sysfs_emit_at(buf, len, "%u", nr_cpu_ids);
     246             :                 else
     247           0 :                         len += sysfs_emit_at(buf, len, "%u-%d",
     248             :                                              nr_cpu_ids, total_cpus - 1);
     249             :         }
     250             : 
     251           0 :         len += sysfs_emit_at(buf, len, "\n");
     252             : 
     253           0 :         return len;
     254             : }
     255             : static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
     256             : 
     257           0 : static ssize_t print_cpus_isolated(struct device *dev,
     258             :                                   struct device_attribute *attr, char *buf)
     259             : {
     260             :         int len;
     261             :         cpumask_var_t isolated;
     262             : 
     263           0 :         if (!alloc_cpumask_var(&isolated, GFP_KERNEL))
     264             :                 return -ENOMEM;
     265             : 
     266           0 :         cpumask_andnot(isolated, cpu_possible_mask,
     267             :                        housekeeping_cpumask(HK_TYPE_DOMAIN));
     268           0 :         len = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated));
     269             : 
     270           0 :         free_cpumask_var(isolated);
     271             : 
     272           0 :         return len;
     273             : }
     274             : static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);
     275             : 
     276             : #ifdef CONFIG_NO_HZ_FULL
     277             : static ssize_t print_cpus_nohz_full(struct device *dev,
     278             :                                     struct device_attribute *attr, char *buf)
     279             : {
     280             :         return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask));
     281             : }
     282             : static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL);
     283             : #endif
     284             : 
     285           0 : static void cpu_device_release(struct device *dev)
     286             : {
     287             :         /*
     288             :          * This is an empty function to prevent the driver core from spitting a
     289             :          * warning at us.  Yes, I know this is directly opposite of what the
     290             :          * documentation for the driver core and kobjects say, and the author
     291             :          * of this code has already been publically ridiculed for doing
     292             :          * something as foolish as this.  However, at this point in time, it is
     293             :          * the only way to handle the issue of statically allocated cpu
     294             :          * devices.  The different architectures will have their cpu device
     295             :          * code reworked to properly handle this in the near future, so this
     296             :          * function will then be changed to correctly free up the memory held
     297             :          * by the cpu device.
     298             :          *
     299             :          * Never copy this way of doing things, or you too will be made fun of
     300             :          * on the linux-kernel list, you have been warned.
     301             :          */
     302           0 : }
     303             : 
     304             : #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
     305             : static ssize_t print_cpu_modalias(struct device *dev,
     306             :                                   struct device_attribute *attr,
     307             :                                   char *buf)
     308             : {
     309             :         int len = 0;
     310             :         u32 i;
     311             : 
     312             :         len += sysfs_emit_at(buf, len,
     313             :                              "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
     314             :                              CPU_FEATURE_TYPEVAL);
     315             : 
     316             :         for (i = 0; i < MAX_CPU_FEATURES; i++)
     317             :                 if (cpu_have_feature(i)) {
     318             :                         if (len + sizeof(",XXXX\n") >= PAGE_SIZE) {
     319             :                                 WARN(1, "CPU features overflow page\n");
     320             :                                 break;
     321             :                         }
     322             :                         len += sysfs_emit_at(buf, len, ",%04X", i);
     323             :                 }
     324             :         len += sysfs_emit_at(buf, len, "\n");
     325             :         return len;
     326             : }
     327             : 
     328             : static int cpu_uevent(const struct device *dev, struct kobj_uevent_env *env)
     329             : {
     330             :         char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
     331             :         if (buf) {
     332             :                 print_cpu_modalias(NULL, NULL, buf);
     333             :                 add_uevent_var(env, "MODALIAS=%s", buf);
     334             :                 kfree(buf);
     335             :         }
     336             :         return 0;
     337             : }
     338             : #endif
     339             : 
     340             : struct bus_type cpu_subsys = {
     341             :         .name = "cpu",
     342             :         .dev_name = "cpu",
     343             :         .match = cpu_subsys_match,
     344             : #ifdef CONFIG_HOTPLUG_CPU
     345             :         .online = cpu_subsys_online,
     346             :         .offline = cpu_subsys_offline,
     347             : #endif
     348             : #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
     349             :         .uevent = cpu_uevent,
     350             : #endif
     351             : };
     352             : EXPORT_SYMBOL_GPL(cpu_subsys);
     353             : 
     354             : /*
     355             :  * register_cpu - Setup a sysfs device for a CPU.
     356             :  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
     357             :  *        sysfs for this CPU.
     358             :  * @num - CPU number to use when creating the device.
     359             :  *
     360             :  * Initialize and register the CPU device.
     361             :  */
     362           1 : int register_cpu(struct cpu *cpu, int num)
     363             : {
     364             :         int error;
     365             : 
     366           1 :         cpu->node_id = cpu_to_node(num);
     367           1 :         memset(&cpu->dev, 0x00, sizeof(struct device));
     368           1 :         cpu->dev.id = num;
     369           1 :         cpu->dev.bus = &cpu_subsys;
     370           1 :         cpu->dev.release = cpu_device_release;
     371           1 :         cpu->dev.offline_disabled = !cpu->hotpluggable;
     372           1 :         cpu->dev.offline = !cpu_online(num);
     373           1 :         cpu->dev.of_node = of_get_cpu_node(num, NULL);
     374           1 :         cpu->dev.groups = common_cpu_attr_groups;
     375           1 :         if (cpu->hotpluggable)
     376           0 :                 cpu->dev.groups = hotplugable_cpu_attr_groups;
     377           1 :         error = device_register(&cpu->dev);
     378           1 :         if (error) {
     379           0 :                 put_device(&cpu->dev);
     380           0 :                 return error;
     381             :         }
     382             : 
     383           1 :         per_cpu(cpu_sys_devices, num) = &cpu->dev;
     384           1 :         register_cpu_under_node(num, cpu_to_node(num));
     385           1 :         dev_pm_qos_expose_latency_limit(&cpu->dev,
     386             :                                         PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
     387             : 
     388           1 :         return 0;
     389             : }
     390             : 
     391           1 : struct device *get_cpu_device(unsigned int cpu)
     392             : {
     393           1 :         if (cpu < nr_cpu_ids && cpu_possible(cpu))
     394           1 :                 return per_cpu(cpu_sys_devices, cpu);
     395             :         else
     396             :                 return NULL;
     397             : }
     398             : EXPORT_SYMBOL_GPL(get_cpu_device);
     399             : 
     400           0 : static void device_create_release(struct device *dev)
     401             : {
     402           0 :         kfree(dev);
     403           0 : }
     404             : 
     405             : __printf(4, 0)
     406             : static struct device *
     407           0 : __cpu_device_create(struct device *parent, void *drvdata,
     408             :                     const struct attribute_group **groups,
     409             :                     const char *fmt, va_list args)
     410             : {
     411           0 :         struct device *dev = NULL;
     412           0 :         int retval = -ENOMEM;
     413             : 
     414           0 :         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
     415           0 :         if (!dev)
     416             :                 goto error;
     417             : 
     418           0 :         device_initialize(dev);
     419           0 :         dev->parent = parent;
     420           0 :         dev->groups = groups;
     421           0 :         dev->release = device_create_release;
     422           0 :         device_set_pm_not_required(dev);
     423           0 :         dev_set_drvdata(dev, drvdata);
     424             : 
     425           0 :         retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
     426           0 :         if (retval)
     427             :                 goto error;
     428             : 
     429           0 :         retval = device_add(dev);
     430           0 :         if (retval)
     431             :                 goto error;
     432             : 
     433             :         return dev;
     434             : 
     435             : error:
     436           0 :         put_device(dev);
     437           0 :         return ERR_PTR(retval);
     438             : }
     439             : 
     440           0 : struct device *cpu_device_create(struct device *parent, void *drvdata,
     441             :                                  const struct attribute_group **groups,
     442             :                                  const char *fmt, ...)
     443             : {
     444             :         va_list vargs;
     445             :         struct device *dev;
     446             : 
     447           0 :         va_start(vargs, fmt);
     448           0 :         dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs);
     449           0 :         va_end(vargs);
     450           0 :         return dev;
     451             : }
     452             : EXPORT_SYMBOL_GPL(cpu_device_create);
     453             : 
     454             : #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
     455             : static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
     456             : #endif
     457             : 
     458             : static struct attribute *cpu_root_attrs[] = {
     459             : #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
     460             :         &dev_attr_probe.attr,
     461             :         &dev_attr_release.attr,
     462             : #endif
     463             :         &cpu_attrs[0].attr.attr,
     464             :         &cpu_attrs[1].attr.attr,
     465             :         &cpu_attrs[2].attr.attr,
     466             :         &dev_attr_kernel_max.attr,
     467             :         &dev_attr_offline.attr,
     468             :         &dev_attr_isolated.attr,
     469             : #ifdef CONFIG_NO_HZ_FULL
     470             :         &dev_attr_nohz_full.attr,
     471             : #endif
     472             : #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
     473             :         &dev_attr_modalias.attr,
     474             : #endif
     475             :         NULL
     476             : };
     477             : 
     478             : static const struct attribute_group cpu_root_attr_group = {
     479             :         .attrs = cpu_root_attrs,
     480             : };
     481             : 
     482             : static const struct attribute_group *cpu_root_attr_groups[] = {
     483             :         &cpu_root_attr_group,
     484             :         NULL,
     485             : };
     486             : 
     487           0 : bool cpu_is_hotpluggable(unsigned int cpu)
     488             : {
     489           0 :         struct device *dev = get_cpu_device(cpu);
     490           0 :         return dev && container_of(dev, struct cpu, dev)->hotpluggable;
     491             : }
     492             : EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
     493             : 
     494             : #ifdef CONFIG_GENERIC_CPU_DEVICES
     495             : static DEFINE_PER_CPU(struct cpu, cpu_devices);
     496             : #endif
     497             : 
     498           1 : static void __init cpu_dev_register_generic(void)
     499             : {
     500             : #ifdef CONFIG_GENERIC_CPU_DEVICES
     501             :         int i;
     502             : 
     503           2 :         for_each_possible_cpu(i) {
     504           1 :                 if (register_cpu(&per_cpu(cpu_devices, i), i))
     505           0 :                         panic("Failed to register CPU device");
     506             :         }
     507             : #endif
     508           1 : }
     509             : 
     510             : #ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
     511             : 
     512             : ssize_t __weak cpu_show_meltdown(struct device *dev,
     513             :                                  struct device_attribute *attr, char *buf)
     514             : {
     515             :         return sysfs_emit(buf, "Not affected\n");
     516             : }
     517             : 
     518             : ssize_t __weak cpu_show_spectre_v1(struct device *dev,
     519             :                                    struct device_attribute *attr, char *buf)
     520             : {
     521             :         return sysfs_emit(buf, "Not affected\n");
     522             : }
     523             : 
     524             : ssize_t __weak cpu_show_spectre_v2(struct device *dev,
     525             :                                    struct device_attribute *attr, char *buf)
     526             : {
     527             :         return sysfs_emit(buf, "Not affected\n");
     528             : }
     529             : 
     530             : ssize_t __weak cpu_show_spec_store_bypass(struct device *dev,
     531             :                                           struct device_attribute *attr, char *buf)
     532             : {
     533             :         return sysfs_emit(buf, "Not affected\n");
     534             : }
     535             : 
     536             : ssize_t __weak cpu_show_l1tf(struct device *dev,
     537             :                              struct device_attribute *attr, char *buf)
     538             : {
     539             :         return sysfs_emit(buf, "Not affected\n");
     540             : }
     541             : 
     542             : ssize_t __weak cpu_show_mds(struct device *dev,
     543             :                             struct device_attribute *attr, char *buf)
     544             : {
     545             :         return sysfs_emit(buf, "Not affected\n");
     546             : }
     547             : 
     548             : ssize_t __weak cpu_show_tsx_async_abort(struct device *dev,
     549             :                                         struct device_attribute *attr,
     550             :                                         char *buf)
     551             : {
     552             :         return sysfs_emit(buf, "Not affected\n");
     553             : }
     554             : 
     555             : ssize_t __weak cpu_show_itlb_multihit(struct device *dev,
     556             :                                       struct device_attribute *attr, char *buf)
     557             : {
     558             :         return sysfs_emit(buf, "Not affected\n");
     559             : }
     560             : 
     561             : ssize_t __weak cpu_show_srbds(struct device *dev,
     562             :                               struct device_attribute *attr, char *buf)
     563             : {
     564             :         return sysfs_emit(buf, "Not affected\n");
     565             : }
     566             : 
     567             : ssize_t __weak cpu_show_mmio_stale_data(struct device *dev,
     568             :                                         struct device_attribute *attr, char *buf)
     569             : {
     570             :         return sysfs_emit(buf, "Not affected\n");
     571             : }
     572             : 
     573             : ssize_t __weak cpu_show_retbleed(struct device *dev,
     574             :                                  struct device_attribute *attr, char *buf)
     575             : {
     576             :         return sysfs_emit(buf, "Not affected\n");
     577             : }
     578             : 
     579             : static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
     580             : static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
     581             : static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
     582             : static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL);
     583             : static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);
     584             : static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
     585             : static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
     586             : static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
     587             : static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
     588             : static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL);
     589             : static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
     590             : 
     591             : static struct attribute *cpu_root_vulnerabilities_attrs[] = {
     592             :         &dev_attr_meltdown.attr,
     593             :         &dev_attr_spectre_v1.attr,
     594             :         &dev_attr_spectre_v2.attr,
     595             :         &dev_attr_spec_store_bypass.attr,
     596             :         &dev_attr_l1tf.attr,
     597             :         &dev_attr_mds.attr,
     598             :         &dev_attr_tsx_async_abort.attr,
     599             :         &dev_attr_itlb_multihit.attr,
     600             :         &dev_attr_srbds.attr,
     601             :         &dev_attr_mmio_stale_data.attr,
     602             :         &dev_attr_retbleed.attr,
     603             :         NULL
     604             : };
     605             : 
     606             : static const struct attribute_group cpu_root_vulnerabilities_group = {
     607             :         .name  = "vulnerabilities",
     608             :         .attrs = cpu_root_vulnerabilities_attrs,
     609             : };
     610             : 
     611             : static void __init cpu_register_vulnerabilities(void)
     612             : {
     613             :         struct device *dev = bus_get_dev_root(&cpu_subsys);
     614             : 
     615             :         if (dev) {
     616             :                 if (sysfs_create_group(&dev->kobj, &cpu_root_vulnerabilities_group))
     617             :                         pr_err("Unable to register CPU vulnerabilities\n");
     618             :                 put_device(dev);
     619             :         }
     620             : }
     621             : 
     622             : #else
     623             : static inline void cpu_register_vulnerabilities(void) { }
     624             : #endif
     625             : 
     626           1 : void __init cpu_dev_init(void)
     627             : {
     628           1 :         if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
     629           0 :                 panic("Failed to register CPU subsystem");
     630             : 
     631           1 :         cpu_dev_register_generic();
     632             :         cpu_register_vulnerabilities();
     633           1 : }

Generated by: LCOV version 1.14