1
2
3
4
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/sched.h>
9#include <linux/cpu.h>
10#include <linux/topology.h>
11#include <linux/device.h>
12#include <linux/node.h>
13#include <linux/gfp.h>
14#include <linux/slab.h>
15#include <linux/percpu.h>
16#include <linux/acpi.h>
17#include <linux/tick.h>
18
19#include "base.h"
20
21static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
22
23static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
24{
25
26 if (acpi_driver_match_device(dev, drv))
27 return 1;
28
29 return 0;
30}
31
32#ifdef CONFIG_HOTPLUG_CPU
33static void change_cpu_under_node(struct cpu *cpu,
34 unsigned int from_nid, unsigned int to_nid)
35{
36 int cpuid = cpu->dev.id;
37 unregister_cpu_under_node(cpuid, from_nid);
38 register_cpu_under_node(cpuid, to_nid);
39 cpu->node_id = to_nid;
40}
41
42static int __ref cpu_subsys_online(struct device *dev)
43{
44 struct cpu *cpu = container_of(dev, struct cpu, dev);
45 int cpuid = dev->id;
46 int from_nid, to_nid;
47 int ret;
48
49 from_nid = cpu_to_node(cpuid);
50 if (from_nid == NUMA_NO_NODE)
51 return -ENODEV;
52
53 ret = cpu_up(cpuid);
54
55
56
57
58 to_nid = cpu_to_node(cpuid);
59 if (from_nid != to_nid)
60 change_cpu_under_node(cpu, from_nid, to_nid);
61
62 return ret;
63}
64
65static int cpu_subsys_offline(struct device *dev)
66{
67 return cpu_down(dev->id);
68}
69
70void unregister_cpu(struct cpu *cpu)
71{
72 int logical_cpu = cpu->dev.id;
73
74 unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
75
76 device_unregister(&cpu->dev);
77 per_cpu(cpu_sys_devices, logical_cpu) = NULL;
78 return;
79}
80
81#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
82static ssize_t cpu_probe_store(struct device *dev,
83 struct device_attribute *attr,
84 const char *buf,
85 size_t count)
86{
87 ssize_t cnt;
88 int ret;
89
90 ret = lock_device_hotplug_sysfs();
91 if (ret)
92 return ret;
93
94 cnt = arch_cpu_probe(buf, count);
95
96 unlock_device_hotplug();
97 return cnt;
98}
99
100static ssize_t cpu_release_store(struct device *dev,
101 struct device_attribute *attr,
102 const char *buf,
103 size_t count)
104{
105 ssize_t cnt;
106 int ret;
107
108 ret = lock_device_hotplug_sysfs();
109 if (ret)
110 return ret;
111
112 cnt = arch_cpu_release(buf, count);
113
114 unlock_device_hotplug();
115 return cnt;
116}
117
118static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
119static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
120#endif
121
122#endif
123
124struct bus_type cpu_subsys = {
125 .name = "cpu",
126 .dev_name = "cpu",
127 .match = cpu_subsys_match,
128#ifdef CONFIG_HOTPLUG_CPU
129 .online = cpu_subsys_online,
130 .offline = cpu_subsys_offline,
131#endif
132};
133EXPORT_SYMBOL_GPL(cpu_subsys);
134
135#ifdef CONFIG_KEXEC
136#include <linux/kexec.h>
137
138static ssize_t show_crash_notes(struct device *dev, struct device_attribute *attr,
139 char *buf)
140{
141 struct cpu *cpu = container_of(dev, struct cpu, dev);
142 ssize_t rc;
143 unsigned long long addr;
144 int cpunum;
145
146 cpunum = cpu->dev.id;
147
148
149
150
151
152
153
154 addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
155 rc = sprintf(buf, "%Lx\n", addr);
156 return rc;
157}
158static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL);
159
160static ssize_t show_crash_notes_size(struct device *dev,
161 struct device_attribute *attr,
162 char *buf)
163{
164 ssize_t rc;
165
166 rc = sprintf(buf, "%zu\n", sizeof(note_buf_t));
167 return rc;
168}
169static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
170#endif
171
172
173
174
175
176struct cpu_attr {
177 struct device_attribute attr;
178 const struct cpumask *const * const map;
179};
180
181static ssize_t show_cpus_attr(struct device *dev,
182 struct device_attribute *attr,
183 char *buf)
184{
185 struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
186 int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
187
188 buf[n++] = '\n';
189 buf[n] = '\0';
190 return n;
191}
192
193#define _CPU_ATTR(name, map) \
194 { __ATTR(name, 0444, show_cpus_attr, NULL), map }
195
196
197static struct cpu_attr cpu_attrs[] = {
198 _CPU_ATTR(online, &cpu_online_mask),
199 _CPU_ATTR(possible, &cpu_possible_mask),
200 _CPU_ATTR(present, &cpu_present_mask),
201};
202
203
204
205
206static ssize_t print_cpus_kernel_max(struct device *dev,
207 struct device_attribute *attr, char *buf)
208{
209 int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
210 return n;
211}
212static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
213
214
215unsigned int total_cpus;
216
217static ssize_t print_cpus_offline(struct device *dev,
218 struct device_attribute *attr, char *buf)
219{
220 int n = 0, len = PAGE_SIZE-2;
221 cpumask_var_t offline;
222
223
224 if (!alloc_cpumask_var(&offline, GFP_KERNEL))
225 return -ENOMEM;
226 cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
227 n = cpulist_scnprintf(buf, len, offline);
228 free_cpumask_var(offline);
229
230
231 if (total_cpus && nr_cpu_ids < total_cpus) {
232 if (n && n < len)
233 buf[n++] = ',';
234
235 if (nr_cpu_ids == total_cpus-1)
236 n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids);
237 else
238 n += snprintf(&buf[n], len - n, "%d-%d",
239 nr_cpu_ids, total_cpus-1);
240 }
241
242 n += snprintf(&buf[n], len - n, "\n");
243 return n;
244}
245static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
246
247static ssize_t print_cpus_isolated(struct device *dev,
248 struct device_attribute *attr, char *buf)
249{
250 int n = 0, len = PAGE_SIZE-2;
251
252 n = cpulist_scnprintf(buf, len, cpu_isolated_map);
253
254 buf[n++] = '\n';
255 buf[n] = '\0';
256 return n;
257}
258static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);
259
260#ifdef CONFIG_NO_HZ_FULL
261static ssize_t print_cpus_nohz_full(struct device *dev,
262 struct device_attribute *attr, char *buf)
263{
264 int n = 0, len = PAGE_SIZE-2;
265
266 n = cpulist_scnprintf(buf, len, tick_nohz_full_mask);
267
268 buf[n++] = '\n';
269 buf[n] = '\0';
270 return n;
271}
272static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL);
273#endif
274
275static void cpu_device_release(struct device *dev)
276{
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292}
293
294
295
296
297
298
299
300
301
302int register_cpu(struct cpu *cpu, int num)
303{
304 int error;
305
306 cpu->node_id = cpu_to_node(num);
307 memset(&cpu->dev, 0x00, sizeof(struct device));
308 cpu->dev.id = num;
309 cpu->dev.bus = &cpu_subsys;
310 cpu->dev.release = cpu_device_release;
311 cpu->dev.offline_disabled = !cpu->hotpluggable;
312 cpu->dev.offline = !cpu_online(num);
313#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
314 cpu->dev.bus->uevent = arch_cpu_uevent;
315#endif
316 error = device_register(&cpu->dev);
317 if (!error)
318 per_cpu(cpu_sys_devices, num) = &cpu->dev;
319 if (!error)
320 register_cpu_under_node(num, cpu_to_node(num));
321
322#ifdef CONFIG_KEXEC
323 if (!error)
324 error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
325 if (!error)
326 error = device_create_file(&cpu->dev,
327 &dev_attr_crash_notes_size);
328#endif
329 return error;
330}
331
332struct device *get_cpu_device(unsigned cpu)
333{
334 if (cpu < nr_cpu_ids && cpu_possible(cpu))
335 return per_cpu(cpu_sys_devices, cpu);
336 else
337 return NULL;
338}
339EXPORT_SYMBOL_GPL(get_cpu_device);
340
341#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
342static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
343#endif
344
345static struct attribute *cpu_root_attrs[] = {
346#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
347 &dev_attr_probe.attr,
348 &dev_attr_release.attr,
349#endif
350 &cpu_attrs[0].attr.attr,
351 &cpu_attrs[1].attr.attr,
352 &cpu_attrs[2].attr.attr,
353 &dev_attr_kernel_max.attr,
354 &dev_attr_offline.attr,
355 &dev_attr_isolated.attr,
356#ifdef CONFIG_NO_HZ_FULL
357 &dev_attr_nohz_full.attr,
358#endif
359#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
360 &dev_attr_modalias.attr,
361#endif
362 NULL
363};
364
365static struct attribute_group cpu_root_attr_group = {
366 .attrs = cpu_root_attrs,
367};
368
369static const struct attribute_group *cpu_root_attr_groups[] = {
370 &cpu_root_attr_group,
371 NULL,
372};
373
374bool cpu_is_hotpluggable(unsigned cpu)
375{
376 struct device *dev = get_cpu_device(cpu);
377 return dev && container_of(dev, struct cpu, dev)->hotpluggable;
378}
379EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
380
381#ifdef CONFIG_GENERIC_CPU_DEVICES
382static DEFINE_PER_CPU(struct cpu, cpu_devices);
383#endif
384
385static void __init cpu_dev_register_generic(void)
386{
387#ifdef CONFIG_GENERIC_CPU_DEVICES
388 int i;
389
390 for_each_possible_cpu(i) {
391 if (register_cpu(&per_cpu(cpu_devices, i), i))
392 panic("Failed to register CPU device");
393 }
394#endif
395}
396
397#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
398
399ssize_t __weak cpu_show_meltdown(struct device *dev,
400 struct device_attribute *attr, char *buf)
401{
402 return sprintf(buf, "Not affected\n");
403}
404
405ssize_t __weak cpu_show_spectre_v1(struct device *dev,
406 struct device_attribute *attr, char *buf)
407{
408 return sprintf(buf, "Not affected\n");
409}
410
411ssize_t __weak cpu_show_spectre_v2(struct device *dev,
412 struct device_attribute *attr, char *buf)
413{
414 return sprintf(buf, "Not affected\n");
415}
416
417ssize_t __weak cpu_show_spec_store_bypass(struct device *dev,
418 struct device_attribute *attr, char *buf)
419{
420 return sprintf(buf, "Not affected\n");
421}
422
423ssize_t __weak cpu_show_l1tf(struct device *dev,
424 struct device_attribute *attr, char *buf)
425{
426 return sprintf(buf, "Not affected\n");
427}
428
429ssize_t __weak cpu_show_mds(struct device *dev,
430 struct device_attribute *attr, char *buf)
431{
432 return sprintf(buf, "Not affected\n");
433}
434
435ssize_t __weak cpu_show_tsx_async_abort(struct device *dev,
436 struct device_attribute *attr,
437 char *buf)
438{
439 return sprintf(buf, "Not affected\n");
440}
441
442ssize_t __weak cpu_show_itlb_multihit(struct device *dev,
443 struct device_attribute *attr, char *buf)
444{
445 return sprintf(buf, "Not affected\n");
446}
447
448static DEVICE_ATTR(meltdown, 0400, cpu_show_meltdown, NULL);
449static DEVICE_ATTR(spectre_v1, 0400, cpu_show_spectre_v1, NULL);
450static DEVICE_ATTR(spectre_v2, 0400, cpu_show_spectre_v2, NULL);
451static DEVICE_ATTR(spec_store_bypass, 0400, cpu_show_spec_store_bypass, NULL);
452static DEVICE_ATTR(l1tf, 0400, cpu_show_l1tf, NULL);
453static DEVICE_ATTR(mds, 0400, cpu_show_mds, NULL);
454static DEVICE_ATTR(tsx_async_abort, 0400, cpu_show_tsx_async_abort, NULL);
455static DEVICE_ATTR(itlb_multihit, 0400, cpu_show_itlb_multihit, NULL);
456
457static struct attribute *cpu_root_vulnerabilities_attrs[] = {
458 &dev_attr_meltdown.attr,
459 &dev_attr_spectre_v1.attr,
460 &dev_attr_spectre_v2.attr,
461 &dev_attr_spec_store_bypass.attr,
462 &dev_attr_l1tf.attr,
463 &dev_attr_mds.attr,
464 &dev_attr_tsx_async_abort.attr,
465 &dev_attr_itlb_multihit.attr,
466 NULL
467};
468
469static const struct attribute_group cpu_root_vulnerabilities_group = {
470 .name = "vulnerabilities",
471 .attrs = cpu_root_vulnerabilities_attrs,
472};
473
474static void __init cpu_register_vulnerabilities(void)
475{
476 if (sysfs_create_group(&cpu_subsys.dev_root->kobj,
477 &cpu_root_vulnerabilities_group))
478 pr_err("Unable to register CPU vulnerabilities\n");
479}
480
481#else
482static inline void cpu_register_vulnerabilities(void) { }
483#endif
484
485void __init cpu_dev_init(void)
486{
487 if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
488 panic("Failed to register CPU subsystem");
489
490 cpu_dev_register_generic();
491 cpu_register_vulnerabilities();
492}
493