• 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 	update_numa_distance(dn);
488 
489 	rc = dlpar_online_cpu(dn);
490 	if (rc) {
491 		saved_rc = rc;
492 		pr_warn("Failed to online cpu %pOFn, rc: %d, drc index: %x\n",
493 			dn, rc, drc_index);
494 
495 		rc = dlpar_detach_node(dn);
496 		if (!rc)
497 			dlpar_release_drc(drc_index);
498 
499 		return saved_rc;
500 	}
501 
502 	pr_debug("Successfully added CPU %pOFn, drc index: %x\n", dn,
503 		 drc_index);
504 	return rc;
505 }
506 
dlpar_cpu_remove(struct device_node * dn,u32 drc_index)507 static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
508 {
509 	int rc;
510 
511 	pr_debug("Attempting to remove CPU %pOFn, drc index: %x\n",
512 		 dn, drc_index);
513 
514 	rc = dlpar_offline_cpu(dn);
515 	if (rc) {
516 		pr_warn("Failed to offline CPU %pOFn, rc: %d\n", dn, rc);
517 		return -EINVAL;
518 	}
519 
520 	rc = dlpar_release_drc(drc_index);
521 	if (rc) {
522 		pr_warn("Failed to release drc (%x) for CPU %pOFn, rc: %d\n",
523 			drc_index, dn, rc);
524 		dlpar_online_cpu(dn);
525 		return rc;
526 	}
527 
528 	rc = dlpar_detach_node(dn);
529 	if (rc) {
530 		int saved_rc = rc;
531 
532 		pr_warn("Failed to detach CPU %pOFn, rc: %d", dn, rc);
533 
534 		rc = dlpar_acquire_drc(drc_index);
535 		if (!rc)
536 			dlpar_online_cpu(dn);
537 
538 		return saved_rc;
539 	}
540 
541 	pr_debug("Successfully removed CPU, drc index: %x\n", drc_index);
542 	return 0;
543 }
544 
cpu_drc_index_to_dn(u32 drc_index)545 static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
546 {
547 	struct device_node *dn;
548 	u32 my_index;
549 	int rc;
550 
551 	for_each_node_by_type(dn, "cpu") {
552 		rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index);
553 		if (rc)
554 			continue;
555 
556 		if (my_index == drc_index)
557 			break;
558 	}
559 
560 	return dn;
561 }
562 
dlpar_cpu_remove_by_index(u32 drc_index)563 static int dlpar_cpu_remove_by_index(u32 drc_index)
564 {
565 	struct device_node *dn;
566 	int rc;
567 
568 	dn = cpu_drc_index_to_dn(drc_index);
569 	if (!dn) {
570 		pr_warn("Cannot find CPU (drc index %x) to remove\n",
571 			drc_index);
572 		return -ENODEV;
573 	}
574 
575 	rc = dlpar_cpu_remove(dn, drc_index);
576 	of_node_put(dn);
577 	return rc;
578 }
579 
find_dlpar_cpus_to_remove(u32 * cpu_drcs,int cpus_to_remove)580 static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
581 {
582 	struct device_node *dn;
583 	int cpus_found = 0;
584 	int rc;
585 
586 	/* We want to find cpus_to_remove + 1 CPUs to ensure we do not
587 	 * remove the last CPU.
588 	 */
589 	for_each_node_by_type(dn, "cpu") {
590 		cpus_found++;
591 
592 		if (cpus_found > cpus_to_remove) {
593 			of_node_put(dn);
594 			break;
595 		}
596 
597 		/* Note that cpus_found is always 1 ahead of the index
598 		 * into the cpu_drcs array, so we use cpus_found - 1
599 		 */
600 		rc = of_property_read_u32(dn, "ibm,my-drc-index",
601 					  &cpu_drcs[cpus_found - 1]);
602 		if (rc) {
603 			pr_warn("Error occurred getting drc-index for %pOFn\n",
604 				dn);
605 			of_node_put(dn);
606 			return -1;
607 		}
608 	}
609 
610 	if (cpus_found < cpus_to_remove) {
611 		pr_warn("Failed to find enough CPUs (%d of %d) to remove\n",
612 			cpus_found, cpus_to_remove);
613 	} else if (cpus_found == cpus_to_remove) {
614 		pr_warn("Cannot remove all CPUs\n");
615 	}
616 
617 	return cpus_found;
618 }
619 
dlpar_cpu_remove_by_count(u32 cpus_to_remove)620 static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
621 {
622 	u32 *cpu_drcs;
623 	int cpus_found;
624 	int cpus_removed = 0;
625 	int i, rc;
626 
627 	pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove);
628 
629 	cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL);
630 	if (!cpu_drcs)
631 		return -EINVAL;
632 
633 	cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove);
634 	if (cpus_found <= cpus_to_remove) {
635 		kfree(cpu_drcs);
636 		return -EINVAL;
637 	}
638 
639 	for (i = 0; i < cpus_to_remove; i++) {
640 		rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
641 		if (rc)
642 			break;
643 
644 		cpus_removed++;
645 	}
646 
647 	if (cpus_removed != cpus_to_remove) {
648 		pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
649 
650 		for (i = 0; i < cpus_removed; i++)
651 			dlpar_cpu_add(cpu_drcs[i]);
652 
653 		rc = -EINVAL;
654 	} else {
655 		rc = 0;
656 	}
657 
658 	kfree(cpu_drcs);
659 	return rc;
660 }
661 
find_drc_info_cpus_to_add(struct device_node * cpus,struct property * info,u32 * cpu_drcs,u32 cpus_to_add)662 static int find_drc_info_cpus_to_add(struct device_node *cpus,
663 				     struct property *info,
664 				     u32 *cpu_drcs, u32 cpus_to_add)
665 {
666 	struct of_drc_info drc;
667 	const __be32 *value;
668 	u32 count, drc_index;
669 	int cpus_found = 0;
670 	int i, j;
671 
672 	if (!info)
673 		return -1;
674 
675 	value = of_prop_next_u32(info, NULL, &count);
676 	if (value)
677 		value++;
678 
679 	for (i = 0; i < count; i++) {
680 		of_read_drc_info_cell(&info, &value, &drc);
681 		if (strncmp(drc.drc_type, "CPU", 3))
682 			break;
683 
684 		drc_index = drc.drc_index_start;
685 		for (j = 0; j < drc.num_sequential_elems; j++) {
686 			if (dlpar_cpu_exists(cpus, drc_index))
687 				continue;
688 
689 			cpu_drcs[cpus_found++] = drc_index;
690 
691 			if (cpus_found == cpus_to_add)
692 				return cpus_found;
693 
694 			drc_index += drc.sequential_inc;
695 		}
696 	}
697 
698 	return cpus_found;
699 }
700 
find_drc_index_cpus_to_add(struct device_node * cpus,u32 * cpu_drcs,u32 cpus_to_add)701 static int find_drc_index_cpus_to_add(struct device_node *cpus,
702 				      u32 *cpu_drcs, u32 cpus_to_add)
703 {
704 	int cpus_found = 0;
705 	int index, rc;
706 	u32 drc_index;
707 
708 	/* Search the ibm,drc-indexes array for possible CPU drcs to
709 	 * add. Note that the format of the ibm,drc-indexes array is
710 	 * the number of entries in the array followed by the array
711 	 * of drc values so we start looking at index = 1.
712 	 */
713 	index = 1;
714 	while (cpus_found < cpus_to_add) {
715 		rc = of_property_read_u32_index(cpus, "ibm,drc-indexes",
716 						index++, &drc_index);
717 
718 		if (rc)
719 			break;
720 
721 		if (dlpar_cpu_exists(cpus, drc_index))
722 			continue;
723 
724 		cpu_drcs[cpus_found++] = drc_index;
725 	}
726 
727 	return cpus_found;
728 }
729 
dlpar_cpu_add_by_count(u32 cpus_to_add)730 static int dlpar_cpu_add_by_count(u32 cpus_to_add)
731 {
732 	struct device_node *parent;
733 	struct property *info;
734 	u32 *cpu_drcs;
735 	int cpus_added = 0;
736 	int cpus_found;
737 	int i, rc;
738 
739 	pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
740 
741 	cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
742 	if (!cpu_drcs)
743 		return -EINVAL;
744 
745 	parent = of_find_node_by_path("/cpus");
746 	if (!parent) {
747 		pr_warn("Could not find CPU root node in device tree\n");
748 		kfree(cpu_drcs);
749 		return -1;
750 	}
751 
752 	info = of_find_property(parent, "ibm,drc-info", NULL);
753 	if (info)
754 		cpus_found = find_drc_info_cpus_to_add(parent, info, cpu_drcs, cpus_to_add);
755 	else
756 		cpus_found = find_drc_index_cpus_to_add(parent, cpu_drcs, cpus_to_add);
757 
758 	of_node_put(parent);
759 
760 	if (cpus_found < cpus_to_add) {
761 		pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
762 			cpus_found, cpus_to_add);
763 		kfree(cpu_drcs);
764 		return -EINVAL;
765 	}
766 
767 	for (i = 0; i < cpus_to_add; i++) {
768 		rc = dlpar_cpu_add(cpu_drcs[i]);
769 		if (rc)
770 			break;
771 
772 		cpus_added++;
773 	}
774 
775 	if (cpus_added < cpus_to_add) {
776 		pr_warn("CPU hot-add failed, removing any added CPUs\n");
777 
778 		for (i = 0; i < cpus_added; i++)
779 			dlpar_cpu_remove_by_index(cpu_drcs[i]);
780 
781 		rc = -EINVAL;
782 	} else {
783 		rc = 0;
784 	}
785 
786 	kfree(cpu_drcs);
787 	return rc;
788 }
789 
dlpar_cpu(struct pseries_hp_errorlog * hp_elog)790 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
791 {
792 	u32 count, drc_index;
793 	int rc;
794 
795 	count = hp_elog->_drc_u.drc_count;
796 	drc_index = hp_elog->_drc_u.drc_index;
797 
798 	lock_device_hotplug();
799 
800 	switch (hp_elog->action) {
801 	case PSERIES_HP_ELOG_ACTION_REMOVE:
802 		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
803 			rc = dlpar_cpu_remove_by_count(count);
804 		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
805 			rc = dlpar_cpu_remove_by_index(drc_index);
806 		else
807 			rc = -EINVAL;
808 		break;
809 	case PSERIES_HP_ELOG_ACTION_ADD:
810 		if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
811 			rc = dlpar_cpu_add_by_count(count);
812 		else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
813 			rc = dlpar_cpu_add(drc_index);
814 		else
815 			rc = -EINVAL;
816 		break;
817 	default:
818 		pr_err("Invalid action (%d) specified\n", hp_elog->action);
819 		rc = -EINVAL;
820 		break;
821 	}
822 
823 	unlock_device_hotplug();
824 	return rc;
825 }
826 
827 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
828 
dlpar_cpu_probe(const char * buf,size_t count)829 static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
830 {
831 	u32 drc_index;
832 	int rc;
833 
834 	rc = kstrtou32(buf, 0, &drc_index);
835 	if (rc)
836 		return -EINVAL;
837 
838 	rc = dlpar_cpu_add(drc_index);
839 
840 	return rc ? rc : count;
841 }
842 
dlpar_cpu_release(const char * buf,size_t count)843 static ssize_t dlpar_cpu_release(const char *buf, size_t count)
844 {
845 	struct device_node *dn;
846 	u32 drc_index;
847 	int rc;
848 
849 	dn = of_find_node_by_path(buf);
850 	if (!dn)
851 		return -EINVAL;
852 
853 	rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
854 	if (rc) {
855 		of_node_put(dn);
856 		return -EINVAL;
857 	}
858 
859 	rc = dlpar_cpu_remove(dn, drc_index);
860 	of_node_put(dn);
861 
862 	return rc ? rc : count;
863 }
864 
865 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
866 
pseries_smp_notifier(struct notifier_block * nb,unsigned long action,void * data)867 static int pseries_smp_notifier(struct notifier_block *nb,
868 				unsigned long action, void *data)
869 {
870 	struct of_reconfig_data *rd = data;
871 	int err = 0;
872 
873 	switch (action) {
874 	case OF_RECONFIG_ATTACH_NODE:
875 		err = pseries_add_processor(rd->dn);
876 		break;
877 	case OF_RECONFIG_DETACH_NODE:
878 		pseries_remove_processor(rd->dn);
879 		break;
880 	}
881 	return notifier_from_errno(err);
882 }
883 
884 static struct notifier_block pseries_smp_nb = {
885 	.notifier_call = pseries_smp_notifier,
886 };
887 
pseries_cpu_hotplug_init(void)888 static int __init pseries_cpu_hotplug_init(void)
889 {
890 	int qcss_tok;
891 
892 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
893 	ppc_md.cpu_probe = dlpar_cpu_probe;
894 	ppc_md.cpu_release = dlpar_cpu_release;
895 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
896 
897 	rtas_stop_self_token = rtas_token("stop-self");
898 	qcss_tok = rtas_token("query-cpu-stopped-state");
899 
900 	if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
901 			qcss_tok == RTAS_UNKNOWN_SERVICE) {
902 		printk(KERN_INFO "CPU Hotplug not supported by firmware "
903 				"- disabling.\n");
904 		return 0;
905 	}
906 
907 	smp_ops->cpu_offline_self = pseries_cpu_offline_self;
908 	smp_ops->cpu_disable = pseries_cpu_disable;
909 	smp_ops->cpu_die = pseries_cpu_die;
910 
911 	/* Processors can be added/removed only on LPAR */
912 	if (firmware_has_feature(FW_FEATURE_LPAR))
913 		of_reconfig_notifier_register(&pseries_smp_nb);
914 
915 	return 0;
916 }
917 machine_arch_initcall(pseries, pseries_cpu_hotplug_init);
918