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

Generated by: LCOV version 1.14