• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * pseries CPU Hotplug infrastructure.
4  *
5  * Split out from arch/powerpc/platforms/pseries/setup.c
6  *  arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c
7  *
8  * Peter Bergner, IBM	March 2001.
9  * Copyright (C) 2001 IBM.
10  * Dave Engebretsen, Peter Bergner, and
11  * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
12  * Plus various changes from other IBM teams...
13  *
14  * Copyright (C) 2006 Michael Ellerman, IBM Corporation
15  */
16 
17 #define pr_fmt(fmt)     "pseries-hotplug-cpu: " fmt
18 
19 #include <linux/kernel.h>
20 #include <linux/interrupt.h>
21 #include <linux/delay.h>
22 #include <linux/sched.h>	/* for idle_task_exit */
23 #include <linux/sched/hotplug.h>
24 #include <linux/cpu.h>
25 #include <linux/of.h>
26 #include <linux/slab.h>
27 #include <asm/prom.h>
28 #include <asm/rtas.h>
29 #include <asm/firmware.h>
30 #include <asm/machdep.h>
31 #include <asm/vdso_datapage.h>
32 #include <asm/xics.h>
33 #include <asm/xive.h>
34 #include <asm/plpar_wrappers.h>
35 #include <asm/topology.h>
36 
37 #include "pseries.h"
38 
39 /* This version can't take the spinlock, because it never returns */
40 static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
41 
rtas_stop_self(void)42 static void rtas_stop_self(void)
43 {
44 	static struct rtas_args args;
45 
46 	local_irq_disable();
47 
48 	BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
49 
50 	rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
51 
52 	panic("Alas, I survived.\n");
53 }
54 
pseries_cpu_offline_self(void)55 static void pseries_cpu_offline_self(void)
56 {
57 	unsigned int hwcpu = hard_smp_processor_id();
58 
59 	local_irq_disable();
60 	idle_task_exit();
61 	if (xive_enabled())
62 		xive_teardown_cpu();
63 	else
64 		xics_teardown_cpu();
65 
66 	unregister_slb_shadow(hwcpu);
67 	rtas_stop_self();
68 
69 	/* Should never get here... */
70 	BUG();
71 	for(;;);
72 }
73 
pseries_cpu_disable(void)74 static int pseries_cpu_disable(void)
75 {
76 	int cpu = smp_processor_id();
77 
78 	set_cpu_online(cpu, false);
79 	vdso_data->processorCount--;
80 
81 	/*fix boot_cpuid here*/
82 	if (cpu == boot_cpuid)
83 		boot_cpuid = cpumask_any(cpu_online_mask);
84 
85 	/* FIXME: abstract this to not be platform specific later on */
86 	if (xive_enabled())
87 		xive_smp_disable_cpu();
88 	else
89 		xics_migrate_irqs_away();
90 
91 	cleanup_cpu_mmu_context();
92 
93 	return 0;
94 }
95 
96 /*
97  * pseries_cpu_die: Wait for the cpu to die.
98  * @cpu: logical processor id of the CPU whose death we're awaiting.
99  *
100  * This function is called from the context of the thread which is performing
101  * the cpu-offline. Here we wait for long enough to allow the cpu in question
102  * to self-destroy so that the cpu-offline thread can send the CPU_DEAD
103  * notifications.
104  *
105  * OTOH, pseries_cpu_offline_self() is called by the @cpu when it wants to
106  * self-destruct.
107  */
pseries_cpu_die(unsigned int cpu)108 static void pseries_cpu_die(unsigned int cpu)
109 {
110 	int cpu_status = 1;
111 	unsigned int pcpu = get_hard_smp_processor_id(cpu);
112 	unsigned long timeout = jiffies + msecs_to_jiffies(120000);
113 
114 	while (true) {
115 		cpu_status = smp_query_cpu_stopped(pcpu);
116 		if (cpu_status == QCSS_STOPPED ||
117 		    cpu_status == QCSS_HARDWARE_ERROR)
118 			break;
119 
120 		if (time_after(jiffies, timeout)) {
121 			pr_warn("CPU %i (hwid %i) didn't die after 120 seconds\n",
122 				cpu, pcpu);
123 			timeout = jiffies + msecs_to_jiffies(120000);
124 		}
125 
126 		cond_resched();
127 	}
128 
129 	if (cpu_status == QCSS_HARDWARE_ERROR) {
130 		pr_warn("CPU %i (hwid %i) reported error while dying\n",
131 			cpu, pcpu);
132 	}
133 
134 	/* Isolation and deallocation are definitely done by
135 	 * drslot_chrp_cpu.  If they were not they would be
136 	 * done here.  Change isolate state to Isolate and
137 	 * change allocation-state to Unusable.
138 	 */
139 	paca_ptrs[cpu]->cpu_start = 0;
140 }
141 
142 /*
143  * Update cpu_present_mask and paca(s) for a new cpu node.  The wrinkle
144  * here is that a cpu device node may represent up to two logical cpus
145  * in the SMT case.  We must honor the assumption in other code that
146  * the logical ids for sibling SMT threads x and y are adjacent, such
147  * that x^1 == y and y^1 == x.
148  */
pseries_add_processor(struct device_node * np)149 static int pseries_add_processor(struct device_node *np)
150 {
151 	unsigned int cpu;
152 	cpumask_var_t candidate_mask, tmp;
153 	int err = -ENOSPC, len, nthreads, i;
154 	const __be32 *intserv;
155 
156 	intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
157 	if (!intserv)
158 		return 0;
159 
160 	zalloc_cpumask_var(&candidate_mask, GFP_KERNEL);
161 	zalloc_cpumask_var(&tmp, GFP_KERNEL);
162 
163 	nthreads = len / sizeof(u32);
164 	for (i = 0; i < nthreads; i++)
165 		cpumask_set_cpu(i, tmp);
166 
167 	cpu_maps_update_begin();
168 
169 	BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask));
170 
171 	/* Get a bitmap of unoccupied slots. */
172 	cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask);
173 	if (cpumask_empty(candidate_mask)) {
174 		/* If we get here, it most likely means that NR_CPUS is
175 		 * less than the partition's max processors setting.
176 		 */
177 		printk(KERN_ERR "Cannot add cpu %pOF; this system configuration"
178 		       " supports %d logical cpus.\n", np,
179 		       num_possible_cpus());
180 		goto out_unlock;
181 	}
182 
183 	while (!cpumask_empty(tmp))
184 		if (cpumask_subset(tmp, candidate_mask))
185 			/* Found a range where we can insert the new cpu(s) */
186 			break;
187 		else
188 			cpumask_shift_left(tmp, tmp, nthreads);
189 
190 	if (cpumask_empty(tmp)) {
191 		printk(KERN_ERR "Unable to find space in cpu_present_mask for"
192 		       " processor %pOFn with %d thread(s)\n", np,
193 		       nthreads);
194 		goto out_unlock;
195 	}
196 
197 	for_each_cpu(cpu, tmp) {
198 		BUG_ON(cpu_present(cpu));
199 		set_cpu_present(cpu, true);
200 		set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++));
201 	}
202 	err = 0;
203 out_unlock:
204 	cpu_maps_update_done();
205 	free_cpumask_var(candidate_mask);
206 	free_cpumask_var(tmp);
207 	return err;
208 }
209 
210 /*
211  * Update the present map for a cpu node which is going away, and set
212  * the hard id in the paca(s) to -1 to be consistent with boot time
213  * convention for non-present cpus.
214  */
pseries_remove_processor(struct device_node * np)215 static void pseries_remove_processor(struct device_node *np)
216 {
217 	unsigned int cpu;
218 	int len, nthreads, i;
219 	const __be32 *intserv;
220 	u32 thread;
221 
222 	intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
223 	if (!intserv)
224 		return;
225 
226 	nthreads = len / sizeof(u32);
227 
228 	cpu_maps_update_begin();
229 	for (i = 0; i < nthreads; i++) {
230 		thread = be32_to_cpu(intserv[i]);
231 		for_each_present_cpu(cpu) {
232 			if (get_hard_smp_processor_id(cpu) != thread)
233 				continue;
234 			BUG_ON(cpu_online(cpu));
235 			set_cpu_present(cpu, false);
236 			set_hard_smp_processor_id(cpu, -1);
237 			update_numa_cpu_lookup_table(cpu, -1);
238 			break;
239 		}
240 		if (cpu >= nr_cpu_ids)
241 			printk(KERN_WARNING "Could not find cpu to remove "
242 			       "with physical id 0x%x\n", thread);
243 	}
244 	cpu_maps_update_done();
245 }
246 
dlpar_offline_cpu(struct device_node * dn)247 static int dlpar_offline_cpu(struct device_node *dn)
248 {
249 	int rc = 0;
250 	unsigned int cpu;
251 	int len, nthreads, i;
252 	const __be32 *intserv;
253 	u32 thread;
254 
255 	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
256 	if (!intserv)
257 		return -EINVAL;
258 
259 	nthreads = len / sizeof(u32);
260 
261 	cpu_maps_update_begin();
262 	for (i = 0; i < nthreads; i++) {
263 		thread = be32_to_cpu(intserv[i]);
264 		for_each_present_cpu(cpu) {
265 			if (get_hard_smp_processor_id(cpu) != thread)
266 				continue;
267 
268 			if (!cpu_online(cpu))
269 				break;
270 
271 			cpu_maps_update_done();
272 			rc = device_offline(get_cpu_device(cpu));
273 			if (rc)
274 				goto out;
275 			cpu_maps_update_begin();
276 			break;
277 		}
278 		if (cpu == num_possible_cpus()) {
279 			pr_warn("Could not find cpu to offline with physical id 0x%x\n",
280 				thread);
281 		}
282 	}
283 	cpu_maps_update_done();
284 
285 out:
286 	return rc;
287 }
288 
dlpar_online_cpu(struct device_node * dn)289 static int dlpar_online_cpu(struct device_node *dn)
290 {
291 	int rc = 0;
292 	unsigned int cpu;
293 	int len, nthreads, i;
294 	const __be32 *intserv;
295 	u32 thread;
296 
297 	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
298 	if (!intserv)
299 		return -EINVAL;
300 
301 	nthreads = len / sizeof(u32);
302 
303 	cpu_maps_update_begin();
304 	for (i = 0; i < nthreads; i++) {
305 		thread = be32_to_cpu(intserv[i]);
306 		for_each_present_cpu(cpu) {
307 			if (get_hard_smp_processor_id(cpu) != thread)
308 				continue;
309 			cpu_maps_update_done();
310 			find_and_online_cpu_nid(cpu);
311 			rc = device_online(get_cpu_device(cpu));
312 			if (rc) {
313 				dlpar_offline_cpu(dn);
314 				goto out;
315 			}
316 			cpu_maps_update_begin();
317 
318 			break;
319 		}
320 		if (cpu == num_possible_cpus())
321 			printk(KERN_WARNING "Could not find cpu to online "
322 			       "with physical id 0x%x\n", thread);
323 	}
324 	cpu_maps_update_done();
325 
326 out:
327 	return rc;
328 
329 }
330 
dlpar_cpu_exists(struct device_node * parent,u32 drc_index)331 static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index)
332 {
333 	struct device_node *child = NULL;
334 	u32 my_drc_index;
335 	bool found;
336 	int rc;
337 
338 	/* Assume cpu doesn't exist */
339 	found = false;
340 
341 	for_each_child_of_node(parent, child) {
342 		rc = of_property_read_u32(child, "ibm,my-drc-index",
343 					  &my_drc_index);
344 		if (rc)
345 			continue;
346 
347 		if (my_drc_index == drc_index) {
348 			of_node_put(child);
349 			found = true;
350 			break;
351 		}
352 	}
353 
354 	return found;
355 }
356 
drc_info_valid_index(struct device_node * parent,u32 drc_index)357 static bool drc_info_valid_index(struct device_node *parent, u32 drc_index)
358 {
359 	struct property *info;
360 	struct of_drc_info drc;
361 	const __be32 *value;
362 	u32 index;
363 	int count, i, j;
364 
365 	info = of_find_property(parent, "ibm,drc-info", NULL);
366 	if (!info)
367 		return false;
368 
369 	value = of_prop_next_u32(info, NULL, &count);
370 
371 	/* First value of ibm,drc-info is number of drc-info records */
372 	if (value)
373 		value++;
374 	else
375 		return false;
376 
377 	for (i = 0; i < count; i++) {
378 		if (of_read_drc_info_cell(&info, &value, &drc))
379 			return false;
380 
381 		if (strncmp(drc.drc_type, "CPU", 3))
382 			break;
383 
384 		if (drc_index > drc.last_drc_index)
385 			continue;
386 
387 		index = drc.drc_index_start;
388 		for (j = 0; j < drc.num_sequential_elems; j++) {
389 			if (drc_index == index)
390 				return true;
391 
392 			index += drc.sequential_inc;
393 		}
394 	}
395 
396 	return false;
397 }
398 
valid_cpu_drc_index(struct device_node * parent,u32 drc_index)399 static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
400 {
401 	bool found = false;
402 	int rc, index;
403 
404 	if (of_find_property(parent, "ibm,drc-info", NULL))
405 		return drc_info_valid_index(parent, drc_index);
406 
407 	/* Note that the format of the ibm,drc-indexes array is
408 	 * the number of entries in the array followed by the array
409 	 * of drc values so we start looking at index = 1.
410 	 */
411 	index = 1;
412 	while (!found) {
413 		u32 drc;
414 
415 		rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
416 						index++, &drc);
417 
418 		if (rc)
419 			break;
420 
421 		if (drc == drc_index)
422 			found = true;
423 	}
424 
425 	return found;
426 }
427 
dlpar_cpu_add(u32 drc_index)428 static ssize_t dlpar_cpu_add(u32 drc_index)
429 {
430 	struct device_node *dn, *parent;
431 	int rc, saved_rc;
432 
433 	pr_debug("Attempting to add CPU, drc index: %x\n", drc_index);
434 
435 	parent = of_find_node_by_path("/cpus");
436 	if (!parent) {
437 		pr_warn("Failed to find CPU root node \"/cpus\"\n");
438 		return -ENODEV;
439 	}
440 
441 	if (dlpar_cpu_exists(parent, drc_index)) {
442 		of_node_put(parent);
443 		pr_warn("CPU with drc index %x already exists\n", drc_index);
444 		return -EINVAL;
445 	}
446 
447 	if (!valid_cpu_drc_index(parent, drc_index)) {
448 		of_node_put(parent);
449 		pr_warn("Cannot find CPU (drc index %x) to add.\n", drc_index);
450 		return -EINVAL;
451 	}
452 
453 	rc = dlpar_acquire_drc(drc_index);
454 	if (rc) {
455 		pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
456 			rc, drc_index);
457 		of_node_put(parent);
458 		return -EINVAL;
459 	}
460 
461 	dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
462 	if (!dn) {
463 		pr_warn("Failed call to configure-connector, drc index: %x\n",
464 			drc_index);
465 		dlpar_release_drc(drc_index);
466 		of_node_put(parent);
467 		return -EINVAL;
468 	}
469 
470 	rc = dlpar_attach_node(dn, parent);
471 
472 	/* Regardless we are done with parent now */
473 	of_node_put(parent);
474 
475 	if (rc) {
476 		saved_rc = rc;
477 		pr_warn("Failed to attach node %pOFn, rc: %d, drc index: %x\n",
478 			dn, rc, drc_index);
479 
480 		rc = dlpar_release_drc(drc_index);
481 		if (!rc)
482 			dlpar_free_cc_nodes(dn);
483 
484 		return saved_rc;
485 	}
486 
487 	rc = dlpar_online_cpu(dn);
488 	if (rc) {
489 		saved_rc = rc;
490 		pr_warn("Failed to online cpu %pOFn, rc: %d, drc index: %x\n",
491 			dn, rc, drc_index);
492 
493 		rc = dlpar_detach_node(dn);
494 		if (!rc)
495 			dlpar_release_drc(drc_index);
496 
497 		return saved_rc;
498 	}
499 
500 	pr_debug("Successfully added CPU %pOFn, drc index: %x\n", dn,
501 		 drc_index);
502 	return rc;
503 }
504 
dlpar_cpu_remove(struct device_node * dn,u32 drc_index)505 static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
506 {
507 	int rc;
508 
509 	pr_debug("Attempting to remove CPU %pOFn, drc index: %x\n",
510 		 dn, drc_index);
511 
512 	rc = dlpar_offline_cpu(dn);
513 	if (rc) {
514 		pr_warn("Failed to offline CPU %pOFn, rc: %d\n", dn, rc);
515 		return -EINVAL;
516 	}
517 
518 	rc = dlpar_release_drc(drc_index);
519 	if (rc) {
520 		pr_warn("Failed to release drc (%x) for CPU %pOFn, rc: %d\n",
521 			drc_index, dn, rc);
522 		dlpar_online_cpu(dn);
523 		return rc;
524 	}
525 
526 	rc = dlpar_detach_node(dn);
527 	if (rc) {
528 		int saved_rc = rc;
529 
530 		pr_warn("Failed to detach CPU %pOFn, rc: %d", dn, rc);
531 
532 		rc = dlpar_acquire_drc(drc_index);
533 		if (!rc)
534 			dlpar_online_cpu(dn);
535 
536 		return saved_rc;
537 	}
538 
539 	pr_debug("Successfully removed CPU, drc index: %x\n", drc_index);
540 	return 0;
541 }
542 
cpu_drc_index_to_dn(u32 drc_index)543 static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
544 {
545 	struct device_node *dn;
546 	u32 my_index;
547 	int rc;
548 
549 	for_each_node_by_type(dn, "cpu") {
550 		rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index);
551 		if (rc)
552 			continue;
553 
554 		if (my_index == drc_index)
555 			break;
556 	}
557 
558 	return dn;
559 }
560 
dlpar_cpu_remove_by_index(u32 drc_index)561 static int dlpar_cpu_remove_by_index(u32 drc_index)
562 {
563 	struct device_node *dn;
564 	int rc;
565 
566 	dn = cpu_drc_index_to_dn(drc_index);
567 	if (!dn) {
568 		pr_warn("Cannot find CPU (drc index %x) to remove\n",
569 			drc_index);
570 		return -ENODEV;
571 	}
572 
573 	rc = dlpar_cpu_remove(dn, drc_index);
574 	of_node_put(dn);
575 	return rc;
576 }
577 
find_dlpar_cpus_to_remove(u32 * cpu_drcs,int cpus_to_remove)578 static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
579 {
580 	struct device_node *dn;
581 	int cpus_found = 0;
582 	int rc;
583 
584 	/* We want to find cpus_to_remove + 1 CPUs to ensure we do not
585 	 * remove the last CPU.
586 	 */
587 	for_each_node_by_type(dn, "cpu") {
588 		cpus_found++;
589 
590 		if (cpus_found > cpus_to_remove) {
591 			of_node_put(dn);
592 			break;
593 		}
594 
595 		/* Note that cpus_found is always 1 ahead of the index
596 		 * into the cpu_drcs array, so we use cpus_found - 1
597 		 */
598 		rc = of_property_read_u32(dn, "ibm,my-drc-index",
599 					  &cpu_drcs[cpus_found - 1]);
600 		if (rc) {
601 			pr_warn("Error occurred getting drc-index for %pOFn\n",
602 				dn);
603 			of_node_put(dn);
604 			return -1;
605 		}
606 	}
607 
608 	if (cpus_found < cpus_to_remove) {
609 		pr_warn("Failed to find enough CPUs (%d of %d) to remove\n",
610 			cpus_found, cpus_to_remove);
611 	} else if (cpus_found == cpus_to_remove) {
612 		pr_warn("Cannot remove all CPUs\n");
613 	}
614 
615 	return cpus_found;
616 }
617 
dlpar_cpu_remove_by_count(u32 cpus_to_remove)618 static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
619 {
620 	u32 *cpu_drcs;
621 	int cpus_found;
622 	int cpus_removed = 0;
623 	int i, rc;
624 
625 	pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove);
626 
627 	cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL);
628 	if (!cpu_drcs)
629 		return -EINVAL;
630 
631 	cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove);
632 	if (cpus_found <= cpus_to_remove) {
633 		kfree(cpu_drcs);
634 		return -EINVAL;
635 	}
636 
637 	for (i = 0; i < cpus_to_remove; i++) {
638 		rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
639 		if (rc)
640 			break;
641 
642 		cpus_removed++;
643 	}
644 
645 	if (cpus_removed != cpus_to_remove) {
646 		pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
647 
648 		for (i = 0; i < cpus_removed; i++)
649 			dlpar_cpu_add(cpu_drcs[i]);
650 
651 		rc = -EINVAL;
652 	} else {
653 		rc = 0;
654 	}
655 
656 	kfree(cpu_drcs);
657 	return rc;
658 }
659 
find_drc_info_cpus_to_add(struct device_node * cpus,struct property * info,u32 * cpu_drcs,u32 cpus_to_add)660 static int find_drc_info_cpus_to_add(struct device_node *cpus,
661 				     struct property *info,
662 				     u32 *cpu_drcs, u32 cpus_to_add)
663 {
664 	struct of_drc_info drc;
665 	const __be32 *value;
666 	u32 count, drc_index;
667 	int cpus_found = 0;
668 	int i, j;
669 
670 	if (!info)
671 		return -1;
672 
673 	value = of_prop_next_u32(info, NULL, &count);
674 	if (value)
675 		value++;
676 
677 	for (i = 0; i < count; i++) {
678 		of_read_drc_info_cell(&info, &value, &drc);
679 		if (strncmp(drc.drc_type, "CPU", 3))
680 			break;
681 
682 		drc_index = drc.drc_index_start;
683 		for (j = 0; j < drc.num_sequential_elems; j++) {
684 			if (dlpar_cpu_exists(cpus, drc_index))
685 				continue;
686 
687 			cpu_drcs[cpus_found++] = drc_index;
688 
689 			if (cpus_found == cpus_to_add)
690 				return cpus_found;
691 
692 			drc_index += drc.sequential_inc;
693 		}
694 	}
695 
696 	return cpus_found;
697 }
698 
find_drc_index_cpus_to_add(struct device_node * cpus,u32 * cpu_drcs,u32 cpus_to_add)699 static int find_drc_index_cpus_to_add(struct device_node *cpus,
700 				      u32 *cpu_drcs, u32 cpus_to_add)
701 {
702 	int cpus_found = 0;
703 	int index, rc;
704 	u32 drc_index;
705 
706 	/* Search the ibm,drc-indexes array for possible CPU drcs to
707 	 * add. Note that the format of the ibm,drc-indexes array is
708 	 * the number of entries in the array followed by the array
709 	 * of drc values so we start looking at index = 1.
710 	 */
711 	index = 1;
712 	while (cpus_found < cpus_to_add) {
713 		rc = of_property_read_u32_index(cpus, "ibm,drc-indexes",
714 						index++, &drc_index);
715 
716 		if (rc)
717 			break;
718 
719 		if (dlpar_cpu_exists(cpus, drc_index))
720 			continue;
721 
722 		cpu_drcs[cpus_found++] = drc_index;
723 	}
724 
725 	return cpus_found;
726 }
727 
dlpar_cpu_add_by_count(u32 cpus_to_add)728 static int dlpar_cpu_add_by_count(u32 cpus_to_add)
729 {
730 	struct device_node *parent;
731 	struct property *info;
732 	u32 *cpu_drcs;
733 	int cpus_added = 0;
734 	int cpus_found;
735 	int i, rc;
736 
737 	pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
738 
739 	cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
740 	if (!cpu_drcs)
741 		return -EINVAL;
742 
743 	parent = of_find_node_by_path("/cpus");
744 	if (!parent) {
745 		pr_warn("Could not find CPU root node in device tree\n");
746 		kfree(cpu_drcs);
747 		return -1;
748 	}
749 
750 	info = of_find_property(parent, "ibm,drc-info", NULL);
751 	if (info)
752 		cpus_found = find_drc_info_cpus_to_add(parent, info, cpu_drcs, cpus_to_add);
753 	else
754 		cpus_found = find_drc_index_cpus_to_add(parent, cpu_drcs, cpus_to_add);
755 
756 	of_node_put(parent);
757 
758 	if (cpus_found < cpus_to_add) {
759 		pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
760 			cpus_found, cpus_to_add);
761 		kfree(cpu_drcs);
762 		return -EINVAL;
763 	}
764 
765 	for (i = 0; i < cpus_to_add; i++) {
766 		rc = dlpar_cpu_add(cpu_drcs[i]);
767 		if (rc)
768 			break;
769 
770 		cpus_added++;
771 	}
772 
773 	if (cpus_added < cpus_to_add) {
774 		pr_warn("CPU hot-add failed, removing any added CPUs\n");
775 
776 		for (i = 0; i < cpus_added; i++)
777 			dlpar_cpu_remove_by_index(cpu_drcs[i]);
778 
779 		rc = -EINVAL;
780 	} else {
781 		rc = 0;
782 	}
783 
784 	kfree(cpu_drcs);
785 	return rc;
786 }
787 
dlpar_cpu(struct pseries_hp_errorlog * hp_elog)788 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
789 {
790 	u32 count, drc_index;
791 	int rc;
792 
793 	count = hp_elog->_drc_u.drc_count;
794 	drc_index = hp_elog->_drc_u.drc_index;
795 
796 	lock_device_hotplug();
797 
798 	switch (hp_elog->action) {
799 	case PSERIES_HP_ELOG_ACTION_REMOVE:
800 		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
801 			rc = dlpar_cpu_remove_by_count(count);
802 		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
803 			rc = dlpar_cpu_remove_by_index(drc_index);
804 		else
805 			rc = -EINVAL;
806 		break;
807 	case PSERIES_HP_ELOG_ACTION_ADD:
808 		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
809 			rc = dlpar_cpu_add_by_count(count);
810 		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
811 			rc = dlpar_cpu_add(drc_index);
812 		else
813 			rc = -EINVAL;
814 		break;
815 	default:
816 		pr_err("Invalid action (%d) specified\n", hp_elog->action);
817 		rc = -EINVAL;
818 		break;
819 	}
820 
821 	unlock_device_hotplug();
822 	return rc;
823 }
824 
825 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
826 
dlpar_cpu_probe(const char * buf,size_t count)827 static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
828 {
829 	u32 drc_index;
830 	int rc;
831 
832 	rc = kstrtou32(buf, 0, &drc_index);
833 	if (rc)
834 		return -EINVAL;
835 
836 	rc = dlpar_cpu_add(drc_index);
837 
838 	return rc ? rc : count;
839 }
840 
dlpar_cpu_release(const char * buf,size_t count)841 static ssize_t dlpar_cpu_release(const char *buf, size_t count)
842 {
843 	struct device_node *dn;
844 	u32 drc_index;
845 	int rc;
846 
847 	dn = of_find_node_by_path(buf);
848 	if (!dn)
849 		return -EINVAL;
850 
851 	rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
852 	if (rc) {
853 		of_node_put(dn);
854 		return -EINVAL;
855 	}
856 
857 	rc = dlpar_cpu_remove(dn, drc_index);
858 	of_node_put(dn);
859 
860 	return rc ? rc : count;
861 }
862 
863 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
864 
pseries_smp_notifier(struct notifier_block * nb,unsigned long action,void * data)865 static int pseries_smp_notifier(struct notifier_block *nb,
866 				unsigned long action, void *data)
867 {
868 	struct of_reconfig_data *rd = data;
869 	int err = 0;
870 
871 	switch (action) {
872 	case OF_RECONFIG_ATTACH_NODE:
873 		err = pseries_add_processor(rd->dn);
874 		break;
875 	case OF_RECONFIG_DETACH_NODE:
876 		pseries_remove_processor(rd->dn);
877 		break;
878 	}
879 	return notifier_from_errno(err);
880 }
881 
882 static struct notifier_block pseries_smp_nb = {
883 	.notifier_call = pseries_smp_notifier,
884 };
885 
pseries_cpu_hotplug_init(void)886 static int __init pseries_cpu_hotplug_init(void)
887 {
888 	int qcss_tok;
889 
890 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
891 	ppc_md.cpu_probe = dlpar_cpu_probe;
892 	ppc_md.cpu_release = dlpar_cpu_release;
893 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
894 
895 	rtas_stop_self_token = rtas_token("stop-self");
896 	qcss_tok = rtas_token("query-cpu-stopped-state");
897 
898 	if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
899 			qcss_tok == RTAS_UNKNOWN_SERVICE) {
900 		printk(KERN_INFO "CPU Hotplug not supported by firmware "
901 				"- disabling.\n");
902 		return 0;
903 	}
904 
905 	smp_ops->cpu_offline_self = pseries_cpu_offline_self;
906 	smp_ops->cpu_disable = pseries_cpu_disable;
907 	smp_ops->cpu_die = pseries_cpu_die;
908 
909 	/* Processors can be added/removed only on LPAR */
910 	if (firmware_has_feature(FW_FEATURE_LPAR))
911 		of_reconfig_notifier_register(&pseries_smp_nb);
912 
913 	return 0;
914 }
915 machine_arch_initcall(pseries, pseries_cpu_hotplug_init);
916