Blame view

drivers/base/cpu.c 14.9 KB
989d42e85   Greg Kroah-Hartman   driver core: add ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
3
   * CPU subsystem support
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   */
024f78462   Ben Hutchings   cpu: Do not retur...
5
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
  #include <linux/module.h>
  #include <linux/init.h>
f6a570333   Al Viro   [PATCH] severing ...
8
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
  #include <linux/cpu.h>
  #include <linux/topology.h>
  #include <linux/device.h>
76b67ed9d   KAMEZAWA Hiroyuki   [PATCH] node hotp...
12
  #include <linux/node.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
13
  #include <linux/gfp.h>
fad12ac8c   Thomas Renninger   CPU: Introduce AR...
14
  #include <linux/slab.h>
9f13a1fd4   Ben Hutchings   cpu: Register a g...
15
  #include <linux/percpu.h>
ac212b698   Rafael J. Wysocki   ACPI / processor:...
16
  #include <linux/acpi.h>
f86e4718f   Sudeep KarkadaNagesha   driver/core: cpu:...
17
  #include <linux/of.h>
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
18
  #include <linux/cpufeature.h>
6570a9a1c   Rik van Riel   show nohz_full cp...
19
  #include <linux/tick.h>
37efa4b41   Alex Shi   CPU / PM: expose ...
20
  #include <linux/pm_qos.h>
edb938217   Frederic Weisbecker   sched/isolation: ...
21
  #include <linux/sched/isolation.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22

a1bdc7aad   Ben Dooks   [PATCH] drivers/b...
23
  #include "base.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
25
  static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
ad74557a4   Ashok Raj   [PATCH] introduce...
26

ac212b698   Rafael J. Wysocki   ACPI / processor:...
27
28
29
30
31
32
33
34
  static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
  {
  	/* ACPI style match is the only one that may succeed. */
  	if (acpi_driver_match_device(dev, drv))
  		return 1;
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  #ifdef CONFIG_HOTPLUG_CPU
346404682   Yasuaki Ishimatsu   numa, cpu hotplug...
36
37
38
39
40
41
42
43
  static void change_cpu_under_node(struct cpu *cpu,
  			unsigned int from_nid, unsigned int to_nid)
  {
  	int cpuid = cpu->dev.id;
  	unregister_cpu_under_node(cpuid, from_nid);
  	register_cpu_under_node(cpuid, to_nid);
  	cpu->node_id = to_nid;
  }
eda5867b6   Mathias Krause   cpu: Remove bogus...
44
  static int cpu_subsys_online(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
46
  	struct cpu *cpu = container_of(dev, struct cpu, dev);
0902a9044   Rafael J. Wysocki   Driver core: Use ...
47
48
  	int cpuid = dev->id;
  	int from_nid, to_nid;
6dedcca61   Toshi Kani   hotplug, powerpc,...
49
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

0902a9044   Rafael J. Wysocki   Driver core: Use ...
51
  	from_nid = cpu_to_node(cpuid);
c7991b0b7   Rafael J. Wysocki   driver core / cpu...
52
  	if (from_nid == NUMA_NO_NODE)
6dedcca61   Toshi Kani   hotplug, powerpc,...
53
  		return -ENODEV;
c7991b0b7   Rafael J. Wysocki   driver core / cpu...
54

33c3736ec   Qais Yousef   cpu/hotplug: Hide...
55
  	ret = cpu_device_up(dev);
0902a9044   Rafael J. Wysocki   Driver core: Use ...
56
57
58
59
60
61
62
  	/*
  	 * When hot adding memory to memoryless node and enabling a cpu
  	 * on the node, node number of the cpu may internally change.
  	 */
  	to_nid = cpu_to_node(cpuid);
  	if (from_nid != to_nid)
  		change_cpu_under_node(cpu, from_nid, to_nid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63

0902a9044   Rafael J. Wysocki   Driver core: Use ...
64
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
  }
0902a9044   Rafael J. Wysocki   Driver core: Use ...
66
  static int cpu_subsys_offline(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  {
33c3736ec   Qais Yousef   cpu/hotplug: Hide...
68
  	return cpu_device_down(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  }
1c4e2d70a   Igor Mammedov   cpu: make sure th...
70

76b67ed9d   KAMEZAWA Hiroyuki   [PATCH] node hotp...
71
  void unregister_cpu(struct cpu *cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
  {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
73
  	int logical_cpu = cpu->dev.id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74

76b67ed9d   KAMEZAWA Hiroyuki   [PATCH] node hotp...
75
  	unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
76
  	device_unregister(&cpu->dev);
e37d05dad   Mike Travis   cpu: change cpu_s...
77
  	per_cpu(cpu_sys_devices, logical_cpu) = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
  	return;
  }
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
80
81
  
  #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
82
83
  static ssize_t cpu_probe_store(struct device *dev,
  			       struct device_attribute *attr,
67fc233f4   Stephen Rothwell   sysdev: the cpu p...
84
  			       const char *buf,
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
85
86
  			       size_t count)
  {
574b851e9   Toshi Kani   hotplug / x86: Ad...
87
88
89
90
91
92
93
94
95
96
97
  	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;
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
98
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
99
100
  static ssize_t cpu_release_store(struct device *dev,
  				 struct device_attribute *attr,
67fc233f4   Stephen Rothwell   sysdev: the cpu p...
101
  				 const char *buf,
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
102
103
  				 size_t count)
  {
574b851e9   Toshi Kani   hotplug / x86: Ad...
104
105
106
107
108
109
110
111
112
113
114
  	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;
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
115
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
116
117
  static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
  static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
12633e803   Nathan Fontenot   sysfs/cpu: Add pr...
118
  #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  #endif /* CONFIG_HOTPLUG_CPU */
0902a9044   Rafael J. Wysocki   Driver core: Use ...
120
121
122
  struct bus_type cpu_subsys = {
  	.name = "cpu",
  	.dev_name = "cpu",
ac212b698   Rafael J. Wysocki   ACPI / processor:...
123
  	.match = cpu_subsys_match,
0902a9044   Rafael J. Wysocki   Driver core: Use ...
124
125
126
127
128
129
  #ifdef CONFIG_HOTPLUG_CPU
  	.online = cpu_subsys_online,
  	.offline = cpu_subsys_offline,
  #endif
  };
  EXPORT_SYMBOL_GPL(cpu_subsys);
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
130
131
  #ifdef CONFIG_KEXEC
  #include <linux/kexec.h>
948b3edba   Joe Perches   drivers core: Mis...
132
133
  static ssize_t crash_notes_show(struct device *dev,
  				struct device_attribute *attr,
4a0b2b4db   Andi Kleen   sysdev: Pass the ...
134
  				char *buf)
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
135
  {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
136
  	struct cpu *cpu = container_of(dev, struct cpu, dev);
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
137
138
  	unsigned long long addr;
  	int cpunum;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
139
  	cpunum = cpu->dev.id;
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
140
141
142
143
144
145
146
  
  	/*
  	 * Might be reading other cpu's data based on which cpu read thread
  	 * has been scheduled. But cpu data (memory) is allocated once during
  	 * boot up and this data does not change there after. Hence this
  	 * operation should be safe. No locking required.
  	 */
3b034b0d0   Vivek Goyal   percpu: Fix kdump...
147
  	addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
948b3edba   Joe Perches   drivers core: Mis...
148
149
150
  
  	return sysfs_emit(buf, "%llx
  ", addr);
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
151
  }
948b3edba   Joe Perches   drivers core: Mis...
152
  static DEVICE_ATTR_ADMIN_RO(crash_notes);
eca4549f5   Zhang Yanfei   sysfs: Add crash_...
153

948b3edba   Joe Perches   drivers core: Mis...
154
  static ssize_t crash_notes_size_show(struct device *dev,
eca4549f5   Zhang Yanfei   sysfs: Add crash_...
155
156
157
  				     struct device_attribute *attr,
  				     char *buf)
  {
948b3edba   Joe Perches   drivers core: Mis...
158
159
  	return sysfs_emit(buf, "%zu
  ", sizeof(note_buf_t));
eca4549f5   Zhang Yanfei   sysfs: Add crash_...
160
  }
948b3edba   Joe Perches   drivers core: Mis...
161
  static DEVICE_ATTR_ADMIN_RO(crash_notes_size);
c055da9fb   Igor Mammedov   cpu: fix "crash_n...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  
  static struct attribute *crash_note_cpu_attrs[] = {
  	&dev_attr_crash_notes.attr,
  	&dev_attr_crash_notes_size.attr,
  	NULL
  };
  
  static struct attribute_group crash_note_cpu_attr_group = {
  	.attrs = crash_note_cpu_attrs,
  };
  #endif
  
  static const struct attribute_group *common_cpu_attr_groups[] = {
  #ifdef CONFIG_KEXEC
  	&crash_note_cpu_attr_group,
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
177
  #endif
c055da9fb   Igor Mammedov   cpu: fix "crash_n...
178
179
  	NULL
  };
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
180

1c4e2d70a   Igor Mammedov   cpu: make sure th...
181
182
183
184
  static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
  #ifdef CONFIG_KEXEC
  	&crash_note_cpu_attr_group,
  #endif
1c4e2d70a   Igor Mammedov   cpu: make sure th...
185
186
  	NULL
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
  /*
9d1fe3236   Mike Travis   cpumask: add show...
188
189
   * Print cpu online, possible, present, and system maps
   */
265d2e2e3   Andi Kleen   sysdev: Convert c...
190
191
  
  struct cpu_attr {
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
192
  	struct device_attribute attr;
848e23915   Rasmus Villemoes   drivers/base/cpu....
193
  	const struct cpumask *const map;
265d2e2e3   Andi Kleen   sysdev: Convert c...
194
  };
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
195
196
  static ssize_t show_cpus_attr(struct device *dev,
  			      struct device_attribute *attr,
265d2e2e3   Andi Kleen   sysdev: Convert c...
197
  			      char *buf)
9d1fe3236   Mike Travis   cpumask: add show...
198
  {
265d2e2e3   Andi Kleen   sysdev: Convert c...
199
  	struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
9d1fe3236   Mike Travis   cpumask: add show...
200

848e23915   Rasmus Villemoes   drivers/base/cpu....
201
  	return cpumap_print_to_pagebuf(true, buf, ca->map);
9d1fe3236   Mike Travis   cpumask: add show...
202
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
203
204
  #define _CPU_ATTR(name, map) \
  	{ __ATTR(name, 0444, show_cpus_attr, NULL), map }
9d1fe3236   Mike Travis   cpumask: add show...
205

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
206
  /* Keep in sync with cpu_subsys_attrs */
265d2e2e3   Andi Kleen   sysdev: Convert c...
207
  static struct cpu_attr cpu_attrs[] = {
848e23915   Rasmus Villemoes   drivers/base/cpu....
208
209
210
  	_CPU_ATTR(online, &__cpu_online_mask),
  	_CPU_ATTR(possible, &__cpu_possible_mask),
  	_CPU_ATTR(present, &__cpu_present_mask),
265d2e2e3   Andi Kleen   sysdev: Convert c...
211
  };
9d1fe3236   Mike Travis   cpumask: add show...
212

e057d7aea   Mike Travis   cpumask: add sysf...
213
214
215
  /*
   * Print values for NR_CPUS and offlined cpus
   */
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
216
217
  static ssize_t print_cpus_kernel_max(struct device *dev,
  				     struct device_attribute *attr, char *buf)
e057d7aea   Mike Travis   cpumask: add sysf...
218
  {
aa838896d   Joe Perches   drivers core: Use...
219
220
  	return sysfs_emit(buf, "%d
  ", NR_CPUS - 1);
e057d7aea   Mike Travis   cpumask: add sysf...
221
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
222
  static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
e057d7aea   Mike Travis   cpumask: add sysf...
223
224
225
  
  /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
  unsigned int total_cpus;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
226
227
  static ssize_t print_cpus_offline(struct device *dev,
  				  struct device_attribute *attr, char *buf)
e057d7aea   Mike Travis   cpumask: add sysf...
228
  {
948b3edba   Joe Perches   drivers core: Mis...
229
  	int len = 0;
e057d7aea   Mike Travis   cpumask: add sysf...
230
231
232
233
234
  	cpumask_var_t offline;
  
  	/* display offline cpus < nr_cpu_ids */
  	if (!alloc_cpumask_var(&offline, GFP_KERNEL))
  		return -ENOMEM;
cdc6e3d39   Jan Beulich   drivers/base/cpu....
235
  	cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
948b3edba   Joe Perches   drivers core: Mis...
236
  	len += sysfs_emit_at(buf, len, "%*pbl", cpumask_pr_args(offline));
e057d7aea   Mike Travis   cpumask: add sysf...
237
238
239
240
  	free_cpumask_var(offline);
  
  	/* display offline cpus >= nr_cpu_ids */
  	if (total_cpus && nr_cpu_ids < total_cpus) {
948b3edba   Joe Perches   drivers core: Mis...
241
  		len += sysfs_emit_at(buf, len, ",");
e057d7aea   Mike Travis   cpumask: add sysf...
242
243
  
  		if (nr_cpu_ids == total_cpus-1)
948b3edba   Joe Perches   drivers core: Mis...
244
  			len += sysfs_emit_at(buf, len, "%u", nr_cpu_ids);
e057d7aea   Mike Travis   cpumask: add sysf...
245
  		else
948b3edba   Joe Perches   drivers core: Mis...
246
247
  			len += sysfs_emit_at(buf, len, "%u-%d",
  					     nr_cpu_ids, total_cpus - 1);
e057d7aea   Mike Travis   cpumask: add sysf...
248
  	}
948b3edba   Joe Perches   drivers core: Mis...
249
250
251
252
  	len += sysfs_emit_at(buf, len, "
  ");
  
  	return len;
e057d7aea   Mike Travis   cpumask: add sysf...
253
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
254
  static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
e057d7aea   Mike Travis   cpumask: add sysf...
255

59f30abe9   Rik van Riel   show isolated cpu...
256
257
258
  static ssize_t print_cpus_isolated(struct device *dev,
  				  struct device_attribute *attr, char *buf)
  {
948b3edba   Joe Perches   drivers core: Mis...
259
  	int len;
edb938217   Frederic Weisbecker   sched/isolation: ...
260
  	cpumask_var_t isolated;
59f30abe9   Rik van Riel   show isolated cpu...
261

edb938217   Frederic Weisbecker   sched/isolation: ...
262
263
264
265
266
  	if (!alloc_cpumask_var(&isolated, GFP_KERNEL))
  		return -ENOMEM;
  
  	cpumask_andnot(isolated, cpu_possible_mask,
  		       housekeeping_cpumask(HK_FLAG_DOMAIN));
948b3edba   Joe Perches   drivers core: Mis...
267
268
  	len = sysfs_emit(buf, "%*pbl
  ", cpumask_pr_args(isolated));
edb938217   Frederic Weisbecker   sched/isolation: ...
269
270
  
  	free_cpumask_var(isolated);
59f30abe9   Rik van Riel   show isolated cpu...
271

948b3edba   Joe Perches   drivers core: Mis...
272
  	return len;
59f30abe9   Rik van Riel   show isolated cpu...
273
274
  }
  static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);
6570a9a1c   Rik van Riel   show nohz_full cp...
275
276
  #ifdef CONFIG_NO_HZ_FULL
  static ssize_t print_cpus_nohz_full(struct device *dev,
948b3edba   Joe Perches   drivers core: Mis...
277
  				    struct device_attribute *attr, char *buf)
6570a9a1c   Rik van Riel   show nohz_full cp...
278
  {
aa838896d   Joe Perches   drivers core: Use...
279
280
  	return sysfs_emit(buf, "%*pbl
  ", cpumask_pr_args(tick_nohz_full_mask));
6570a9a1c   Rik van Riel   show nohz_full cp...
281
282
283
  }
  static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL);
  #endif
2885e25c4   Greg Kroah-Hartman   driver core: cpu:...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  static void cpu_device_release(struct device *dev)
  {
  	/*
  	 * This is an empty function to prevent the driver core from spitting a
  	 * warning at us.  Yes, I know this is directly opposite of what the
  	 * documentation for the driver core and kobjects say, and the author
  	 * of this code has already been publically ridiculed for doing
  	 * something as foolish as this.  However, at this point in time, it is
  	 * the only way to handle the issue of statically allocated cpu
  	 * devices.  The different architectures will have their cpu device
  	 * code reworked to properly handle this in the near future, so this
  	 * function will then be changed to correctly free up the memory held
  	 * by the cpu device.
  	 *
  	 * Never copy this way of doing things, or you too will be made fun of
30a4840a4   Ralf Baechle   drivers/base/cpu....
299
  	 * on the linux-kernel list, you have been warned.
2885e25c4   Greg Kroah-Hartman   driver core: cpu:...
300
301
  	 */
  }
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
302
303
304
305
306
  #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  static ssize_t print_cpu_modalias(struct device *dev,
  				  struct device_attribute *attr,
  				  char *buf)
  {
948b3edba   Joe Perches   drivers core: Mis...
307
  	int len = 0;
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
308
  	u32 i;
948b3edba   Joe Perches   drivers core: Mis...
309
310
311
  	len += sysfs_emit_at(buf, len,
  			     "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
  			     CPU_FEATURE_TYPEVAL);
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
312
313
314
  
  	for (i = 0; i < MAX_CPU_FEATURES; i++)
  		if (cpu_have_feature(i)) {
948b3edba   Joe Perches   drivers core: Mis...
315
316
  			if (len + sizeof(",XXXX
  ") >= PAGE_SIZE) {
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
317
318
319
320
  				WARN(1, "CPU features overflow page
  ");
  				break;
  			}
948b3edba   Joe Perches   drivers core: Mis...
321
  			len += sysfs_emit_at(buf, len, ",%04X", i);
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
322
  		}
948b3edba   Joe Perches   drivers core: Mis...
323
324
325
  	len += sysfs_emit_at(buf, len, "
  ");
  	return len;
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
326
  }
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
327
328
329
330
331
332
333
334
335
336
337
338
  
  static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  {
  	char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  	if (buf) {
  		print_cpu_modalias(NULL, NULL, buf);
  		add_uevent_var(env, "MODALIAS=%s", buf);
  		kfree(buf);
  	}
  	return 0;
  }
  #endif
9d1fe3236   Mike Travis   cpumask: add show...
339
  /*
405ae7d38   Robert P. J. Day   Replace remaining...
340
   * register_cpu - Setup a sysfs device for a CPU.
72486f1f8   Siddha, Suresh B   [PATCH] i386: cha...
341
342
   * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
   *	  sysfs for this CPU.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
344
345
346
   * @num - CPU number to use when creating the device.
   *
   * Initialize and register the CPU device.
   */
a83048ebd   Paul Gortmaker   drivers: delete _...
347
  int register_cpu(struct cpu *cpu, int num)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
  {
  	int error;
76b67ed9d   KAMEZAWA Hiroyuki   [PATCH] node hotp...
350

8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
351
  	cpu->node_id = cpu_to_node(num);
29bb5d4fd   Greg Kroah-Hartman   driver-core: cpu:...
352
  	memset(&cpu->dev, 0x00, sizeof(struct device));
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
353
354
  	cpu->dev.id = num;
  	cpu->dev.bus = &cpu_subsys;
2885e25c4   Greg Kroah-Hartman   driver core: cpu:...
355
  	cpu->dev.release = cpu_device_release;
0902a9044   Rafael J. Wysocki   Driver core: Use ...
356
  	cpu->dev.offline_disabled = !cpu->hotpluggable;
1001b4d4a   Toshi Kani   CPU: Fix sysfs cp...
357
  	cpu->dev.offline = !cpu_online(num);
f86e4718f   Sudeep KarkadaNagesha   driver/core: cpu:...
358
  	cpu->dev.of_node = of_get_cpu_node(num, NULL);
2b9c1f032   Ard Biesheuvel   x86: align x86 ar...
359
  #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
360
  	cpu->dev.bus->uevent = cpu_uevent;
fad12ac8c   Thomas Renninger   CPU: Introduce AR...
361
  #endif
c055da9fb   Igor Mammedov   cpu: fix "crash_n...
362
  	cpu->dev.groups = common_cpu_attr_groups;
1c4e2d70a   Igor Mammedov   cpu: make sure th...
363
364
  	if (cpu->hotpluggable)
  		cpu->dev.groups = hotplugable_cpu_attr_groups;
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
365
  	error = device_register(&cpu->dev);
3aaba245d   Arvind Yadav   driver core: cpu:...
366
367
  	if (error) {
  		put_device(&cpu->dev);
59fffa340   Alex Shi   cpu: clean up reg...
368
  		return error;
3aaba245d   Arvind Yadav   driver core: cpu:...
369
  	}
51be5606d   Vivek Goyal   [PATCH] kdump: ex...
370

59fffa340   Alex Shi   cpu: clean up reg...
371
372
  	per_cpu(cpu_sys_devices, num) = &cpu->dev;
  	register_cpu_under_node(num, cpu_to_node(num));
0759e80b8   Rafael J. Wysocki   PM / QoS: Fix dev...
373
374
  	dev_pm_qos_expose_latency_limit(&cpu->dev,
  					PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
59fffa340   Alex Shi   cpu: clean up reg...
375
376
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
378
  struct device *get_cpu_device(unsigned cpu)
ad74557a4   Ashok Raj   [PATCH] introduce...
379
  {
e37d05dad   Mike Travis   cpu: change cpu_s...
380
381
  	if (cpu < nr_cpu_ids && cpu_possible(cpu))
  		return per_cpu(cpu_sys_devices, cpu);
ad74557a4   Ashok Raj   [PATCH] introduce...
382
383
384
  	else
  		return NULL;
  }
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
385
  EXPORT_SYMBOL_GPL(get_cpu_device);
3d52943b3   Sudeep Holla   drivers: base: ad...
386
387
388
389
  static void device_create_release(struct device *dev)
  {
  	kfree(dev);
  }
fa548d79d   Mathieu Malaterre   drivers: base: Us...
390
  __printf(4, 0)
3d52943b3   Sudeep Holla   drivers: base: ad...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  static struct device *
  __cpu_device_create(struct device *parent, void *drvdata,
  		    const struct attribute_group **groups,
  		    const char *fmt, va_list args)
  {
  	struct device *dev = NULL;
  	int retval = -ENODEV;
  
  	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  	if (!dev) {
  		retval = -ENOMEM;
  		goto error;
  	}
  
  	device_initialize(dev);
  	dev->parent = parent;
  	dev->groups = groups;
  	dev->release = device_create_release;
85945c28b   Sudeep Holla   PM / core: Add su...
409
  	device_set_pm_not_required(dev);
3d52943b3   Sudeep Holla   drivers: base: ad...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  	dev_set_drvdata(dev, drvdata);
  
  	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
  	if (retval)
  		goto error;
  
  	retval = device_add(dev);
  	if (retval)
  		goto error;
  
  	return dev;
  
  error:
  	put_device(dev);
  	return ERR_PTR(retval);
  }
  
  struct device *cpu_device_create(struct device *parent, void *drvdata,
  				 const struct attribute_group **groups,
  				 const char *fmt, ...)
  {
  	va_list vargs;
  	struct device *dev;
  
  	va_start(vargs, fmt);
  	dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs);
  	va_end(vargs);
  	return dev;
  }
  EXPORT_SYMBOL_GPL(cpu_device_create);
2b9c1f032   Ard Biesheuvel   x86: align x86 ar...
440
  #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
67bad2fdb   Ard Biesheuvel   cpu: add generic ...
441
  static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
fad12ac8c   Thomas Renninger   CPU: Introduce AR...
442
  #endif
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
443
444
445
446
447
448
449
450
451
452
  static struct attribute *cpu_root_attrs[] = {
  #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
  	&dev_attr_probe.attr,
  	&dev_attr_release.attr,
  #endif
  	&cpu_attrs[0].attr.attr,
  	&cpu_attrs[1].attr.attr,
  	&cpu_attrs[2].attr.attr,
  	&dev_attr_kernel_max.attr,
  	&dev_attr_offline.attr,
59f30abe9   Rik van Riel   show isolated cpu...
453
  	&dev_attr_isolated.attr,
6570a9a1c   Rik van Riel   show nohz_full cp...
454
455
456
  #ifdef CONFIG_NO_HZ_FULL
  	&dev_attr_nohz_full.attr,
  #endif
2b9c1f032   Ard Biesheuvel   x86: align x86 ar...
457
  #ifdef CONFIG_GENERIC_CPU_AUTOPROBE
fad12ac8c   Thomas Renninger   CPU: Introduce AR...
458
459
  	&dev_attr_modalias.attr,
  #endif
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
460
461
462
463
464
465
466
467
468
469
470
  	NULL
  };
  
  static struct attribute_group cpu_root_attr_group = {
  	.attrs = cpu_root_attrs,
  };
  
  static const struct attribute_group *cpu_root_attr_groups[] = {
  	&cpu_root_attr_group,
  	NULL,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471

2987557f5   Josh Triplett   driver-core/cpu: ...
472
473
  bool cpu_is_hotpluggable(unsigned cpu)
  {
7affca353   Linus Torvalds   Merge branch 'dri...
474
475
  	struct device *dev = get_cpu_device(cpu);
  	return dev && container_of(dev, struct cpu, dev)->hotpluggable;
2987557f5   Josh Triplett   driver-core/cpu: ...
476
477
  }
  EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
9f13a1fd4   Ben Hutchings   cpu: Register a g...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  #ifdef CONFIG_GENERIC_CPU_DEVICES
  static DEFINE_PER_CPU(struct cpu, cpu_devices);
  #endif
  
  static void __init cpu_dev_register_generic(void)
  {
  #ifdef CONFIG_GENERIC_CPU_DEVICES
  	int i;
  
  	for_each_possible_cpu(i) {
  		if (register_cpu(&per_cpu(cpu_devices, i), i))
  			panic("Failed to register CPU device");
  	}
  #endif
  }
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
493
494
495
496
497
  #ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
  
  ssize_t __weak cpu_show_meltdown(struct device *dev,
  				 struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
498
499
  	return sysfs_emit(buf, "Not affected
  ");
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
500
501
502
503
504
  }
  
  ssize_t __weak cpu_show_spectre_v1(struct device *dev,
  				   struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
505
506
  	return sysfs_emit(buf, "Not affected
  ");
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
507
508
509
510
511
  }
  
  ssize_t __weak cpu_show_spectre_v2(struct device *dev,
  				   struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
512
513
  	return sysfs_emit(buf, "Not affected
  ");
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
514
  }
c456442cd   Konrad Rzeszutek Wilk   x86/bugs: Expose ...
515
516
517
  ssize_t __weak cpu_show_spec_store_bypass(struct device *dev,
  					  struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
518
519
  	return sysfs_emit(buf, "Not affected
  ");
c456442cd   Konrad Rzeszutek Wilk   x86/bugs: Expose ...
520
  }
17dbca119   Andi Kleen   x86/speculation/l...
521
522
523
  ssize_t __weak cpu_show_l1tf(struct device *dev,
  			     struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
524
525
  	return sysfs_emit(buf, "Not affected
  ");
17dbca119   Andi Kleen   x86/speculation/l...
526
  }
8a4b06d39   Thomas Gleixner   x86/speculation/m...
527
528
529
  ssize_t __weak cpu_show_mds(struct device *dev,
  			    struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
530
531
  	return sysfs_emit(buf, "Not affected
  ");
8a4b06d39   Thomas Gleixner   x86/speculation/m...
532
  }
6608b45ac   Pawan Gupta   x86/speculation/t...
533
534
535
536
  ssize_t __weak cpu_show_tsx_async_abort(struct device *dev,
  					struct device_attribute *attr,
  					char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
537
538
  	return sysfs_emit(buf, "Not affected
  ");
6608b45ac   Pawan Gupta   x86/speculation/t...
539
  }
db4d30fbb   Vineela Tummalapalli   x86/bugs: Add ITL...
540
  ssize_t __weak cpu_show_itlb_multihit(struct device *dev,
948b3edba   Joe Perches   drivers core: Mis...
541
  				      struct device_attribute *attr, char *buf)
db4d30fbb   Vineela Tummalapalli   x86/bugs: Add ITL...
542
  {
aa838896d   Joe Perches   drivers core: Use...
543
544
  	return sysfs_emit(buf, "Not affected
  ");
db4d30fbb   Vineela Tummalapalli   x86/bugs: Add ITL...
545
  }
7e5b3c267   Mark Gross   x86/speculation: ...
546
547
548
  ssize_t __weak cpu_show_srbds(struct device *dev,
  			      struct device_attribute *attr, char *buf)
  {
aa838896d   Joe Perches   drivers core: Use...
549
550
  	return sysfs_emit(buf, "Not affected
  ");
7e5b3c267   Mark Gross   x86/speculation: ...
551
  }
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
552
553
554
  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);
c456442cd   Konrad Rzeszutek Wilk   x86/bugs: Expose ...
555
  static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL);
17dbca119   Andi Kleen   x86/speculation/l...
556
  static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);
8a4b06d39   Thomas Gleixner   x86/speculation/m...
557
  static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
6608b45ac   Pawan Gupta   x86/speculation/t...
558
  static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
db4d30fbb   Vineela Tummalapalli   x86/bugs: Add ITL...
559
  static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
7e5b3c267   Mark Gross   x86/speculation: ...
560
  static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
561
562
563
564
565
  
  static struct attribute *cpu_root_vulnerabilities_attrs[] = {
  	&dev_attr_meltdown.attr,
  	&dev_attr_spectre_v1.attr,
  	&dev_attr_spectre_v2.attr,
c456442cd   Konrad Rzeszutek Wilk   x86/bugs: Expose ...
566
  	&dev_attr_spec_store_bypass.attr,
17dbca119   Andi Kleen   x86/speculation/l...
567
  	&dev_attr_l1tf.attr,
8a4b06d39   Thomas Gleixner   x86/speculation/m...
568
  	&dev_attr_mds.attr,
6608b45ac   Pawan Gupta   x86/speculation/t...
569
  	&dev_attr_tsx_async_abort.attr,
db4d30fbb   Vineela Tummalapalli   x86/bugs: Add ITL...
570
  	&dev_attr_itlb_multihit.attr,
7e5b3c267   Mark Gross   x86/speculation: ...
571
  	&dev_attr_srbds.attr,
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  	NULL
  };
  
  static const struct attribute_group cpu_root_vulnerabilities_group = {
  	.name  = "vulnerabilities",
  	.attrs = cpu_root_vulnerabilities_attrs,
  };
  
  static void __init cpu_register_vulnerabilities(void)
  {
  	if (sysfs_create_group(&cpu_subsys.dev_root->kobj,
  			       &cpu_root_vulnerabilities_group))
  		pr_err("Unable to register CPU vulnerabilities
  ");
  }
  
  #else
  static inline void cpu_register_vulnerabilities(void) { }
  #endif
024f78462   Ben Hutchings   cpu: Do not retur...
591
  void __init cpu_dev_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
  {
024f78462   Ben Hutchings   cpu: Do not retur...
593
594
  	if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
  		panic("Failed to register CPU subsystem");
8a25a2fd1   Kay Sievers   cpu: convert 'cpu...
595

9f13a1fd4   Ben Hutchings   cpu: Register a g...
596
  	cpu_dev_register_generic();
87590ce6e   Thomas Gleixner   sysfs/cpu: Add vu...
597
  	cpu_register_vulnerabilities();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
  }