1 /*
2  * Support for dynamic reconfiguration for PCI, Memory, and CPU
3  * Hotplug and Dynamic Logical Partitioning on RPA platforms.
4  *
5  * Copyright (C) 2009 Nathan Fontenot
6  * Copyright (C) 2009 IBM Corporation
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  */
12 
13 #define pr_fmt(fmt)	"dlpar: " fmt
14 
15 #include <linux/kernel.h>
16 #include <linux/notifier.h>
17 #include <linux/spinlock.h>
18 #include <linux/cpu.h>
19 #include <linux/slab.h>
20 #include <linux/of.h>
21 
22 #include "of_helpers.h"
23 #include "offline_states.h"
24 #include "pseries.h"
25 
26 #include <asm/prom.h>
27 #include <asm/machdep.h>
28 #include <asm/uaccess.h>
29 #include <asm/rtas.h>
30 
31 struct cc_workarea {
32 	__be32	drc_index;
33 	__be32	zero;
34 	__be32	name_offset;
35 	__be32	prop_length;
36 	__be32	prop_offset;
37 };
38 
39 void dlpar_free_cc_property(struct property *prop)
40 {
41 	kfree(prop->name);
42 	kfree(prop->value);
43 	kfree(prop);
44 }
45 
46 static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
47 {
48 	struct property *prop;
49 	char *name;
50 	char *value;
51 
52 	prop = kzalloc(sizeof(*prop), GFP_KERNEL);
53 	if (!prop)
54 		return NULL;
55 
56 	name = (char *)ccwa + be32_to_cpu(ccwa->name_offset);
57 	prop->name = kstrdup(name, GFP_KERNEL);
58 
59 	prop->length = be32_to_cpu(ccwa->prop_length);
60 	value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset);
61 	prop->value = kmemdup(value, prop->length, GFP_KERNEL);
62 	if (!prop->value) {
63 		dlpar_free_cc_property(prop);
64 		return NULL;
65 	}
66 
67 	return prop;
68 }
69 
70 static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa,
71 					       const char *path)
72 {
73 	struct device_node *dn;
74 	char *name;
75 
76 	/* If parent node path is "/" advance path to NULL terminator to
77 	 * prevent double leading slashs in full_name.
78 	 */
79 	if (!path[1])
80 		path++;
81 
82 	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
83 	if (!dn)
84 		return NULL;
85 
86 	name = (char *)ccwa + be32_to_cpu(ccwa->name_offset);
87 	dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name);
88 	if (!dn->full_name) {
89 		kfree(dn);
90 		return NULL;
91 	}
92 
93 	of_node_set_flag(dn, OF_DYNAMIC);
94 	of_node_init(dn);
95 
96 	return dn;
97 }
98 
99 static void dlpar_free_one_cc_node(struct device_node *dn)
100 {
101 	struct property *prop;
102 
103 	while (dn->properties) {
104 		prop = dn->properties;
105 		dn->properties = prop->next;
106 		dlpar_free_cc_property(prop);
107 	}
108 
109 	kfree(dn->full_name);
110 	kfree(dn);
111 }
112 
113 void dlpar_free_cc_nodes(struct device_node *dn)
114 {
115 	if (dn->child)
116 		dlpar_free_cc_nodes(dn->child);
117 
118 	if (dn->sibling)
119 		dlpar_free_cc_nodes(dn->sibling);
120 
121 	dlpar_free_one_cc_node(dn);
122 }
123 
124 #define COMPLETE	0
125 #define NEXT_SIBLING    1
126 #define NEXT_CHILD      2
127 #define NEXT_PROPERTY   3
128 #define PREV_PARENT     4
129 #define MORE_MEMORY     5
130 #define CALL_AGAIN	-2
131 #define ERR_CFG_USE     -9003
132 
133 struct device_node *dlpar_configure_connector(__be32 drc_index,
134 					      struct device_node *parent)
135 {
136 	struct device_node *dn;
137 	struct device_node *first_dn = NULL;
138 	struct device_node *last_dn = NULL;
139 	struct property *property;
140 	struct property *last_property = NULL;
141 	struct cc_workarea *ccwa;
142 	char *data_buf;
143 	const char *parent_path = parent->full_name;
144 	int cc_token;
145 	int rc = -1;
146 
147 	cc_token = rtas_token("ibm,configure-connector");
148 	if (cc_token == RTAS_UNKNOWN_SERVICE)
149 		return NULL;
150 
151 	data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
152 	if (!data_buf)
153 		return NULL;
154 
155 	ccwa = (struct cc_workarea *)&data_buf[0];
156 	ccwa->drc_index = drc_index;
157 	ccwa->zero = 0;
158 
159 	do {
160 		/* Since we release the rtas_data_buf lock between configure
161 		 * connector calls we want to re-populate the rtas_data_buffer
162 		 * with the contents of the previous call.
163 		 */
164 		spin_lock(&rtas_data_buf_lock);
165 
166 		memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE);
167 		rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
168 		memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
169 
170 		spin_unlock(&rtas_data_buf_lock);
171 
172 		switch (rc) {
173 		case COMPLETE:
174 			break;
175 
176 		case NEXT_SIBLING:
177 			dn = dlpar_parse_cc_node(ccwa, parent_path);
178 			if (!dn)
179 				goto cc_error;
180 
181 			dn->parent = last_dn->parent;
182 			last_dn->sibling = dn;
183 			last_dn = dn;
184 			break;
185 
186 		case NEXT_CHILD:
187 			if (first_dn)
188 				parent_path = last_dn->full_name;
189 
190 			dn = dlpar_parse_cc_node(ccwa, parent_path);
191 			if (!dn)
192 				goto cc_error;
193 
194 			if (!first_dn) {
195 				dn->parent = parent;
196 				first_dn = dn;
197 			} else {
198 				dn->parent = last_dn;
199 				if (last_dn)
200 					last_dn->child = dn;
201 			}
202 
203 			last_dn = dn;
204 			break;
205 
206 		case NEXT_PROPERTY:
207 			property = dlpar_parse_cc_property(ccwa);
208 			if (!property)
209 				goto cc_error;
210 
211 			if (!last_dn->properties)
212 				last_dn->properties = property;
213 			else
214 				last_property->next = property;
215 
216 			last_property = property;
217 			break;
218 
219 		case PREV_PARENT:
220 			last_dn = last_dn->parent;
221 			parent_path = last_dn->parent->full_name;
222 			break;
223 
224 		case CALL_AGAIN:
225 			break;
226 
227 		case MORE_MEMORY:
228 		case ERR_CFG_USE:
229 		default:
230 			printk(KERN_ERR "Unexpected Error (%d) "
231 			       "returned from configure-connector\n", rc);
232 			goto cc_error;
233 		}
234 	} while (rc);
235 
236 cc_error:
237 	kfree(data_buf);
238 
239 	if (rc) {
240 		if (first_dn)
241 			dlpar_free_cc_nodes(first_dn);
242 
243 		return NULL;
244 	}
245 
246 	return first_dn;
247 }
248 
249 int dlpar_attach_node(struct device_node *dn)
250 {
251 	int rc;
252 
253 	dn->parent = pseries_of_derive_parent(dn->full_name);
254 	if (IS_ERR(dn->parent))
255 		return PTR_ERR(dn->parent);
256 
257 	rc = of_attach_node(dn);
258 	if (rc) {
259 		printk(KERN_ERR "Failed to add device node %s\n",
260 		       dn->full_name);
261 		return rc;
262 	}
263 
264 	of_node_put(dn->parent);
265 	return 0;
266 }
267 
268 int dlpar_detach_node(struct device_node *dn)
269 {
270 	struct device_node *child;
271 	int rc;
272 
273 	child = of_get_next_child(dn, NULL);
274 	while (child) {
275 		dlpar_detach_node(child);
276 		child = of_get_next_child(dn, child);
277 	}
278 
279 	rc = of_detach_node(dn);
280 	if (rc)
281 		return rc;
282 
283 	of_node_put(dn); /* Must decrement the refcount */
284 	return 0;
285 }
286 
287 #define DR_ENTITY_SENSE		9003
288 #define DR_ENTITY_PRESENT	1
289 #define DR_ENTITY_UNUSABLE	2
290 #define ALLOCATION_STATE	9003
291 #define ALLOC_UNUSABLE		0
292 #define ALLOC_USABLE		1
293 #define ISOLATION_STATE		9001
294 #define ISOLATE			0
295 #define UNISOLATE		1
296 
297 int dlpar_acquire_drc(u32 drc_index)
298 {
299 	int dr_status, rc;
300 
301 	rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
302 		       DR_ENTITY_SENSE, drc_index);
303 	if (rc || dr_status != DR_ENTITY_UNUSABLE)
304 		return -1;
305 
306 	rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_USABLE);
307 	if (rc)
308 		return rc;
309 
310 	rc = rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
311 	if (rc) {
312 		rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
313 		return rc;
314 	}
315 
316 	return 0;
317 }
318 
319 int dlpar_release_drc(u32 drc_index)
320 {
321 	int dr_status, rc;
322 
323 	rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
324 		       DR_ENTITY_SENSE, drc_index);
325 	if (rc || dr_status != DR_ENTITY_PRESENT)
326 		return -1;
327 
328 	rc = rtas_set_indicator(ISOLATION_STATE, drc_index, ISOLATE);
329 	if (rc)
330 		return rc;
331 
332 	rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
333 	if (rc) {
334 		rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
335 		return rc;
336 	}
337 
338 	return 0;
339 }
340 
341 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
342 
343 static int dlpar_online_cpu(struct device_node *dn)
344 {
345 	int rc = 0;
346 	unsigned int cpu;
347 	int len, nthreads, i;
348 	const __be32 *intserv;
349 	u32 thread;
350 
351 	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
352 	if (!intserv)
353 		return -EINVAL;
354 
355 	nthreads = len / sizeof(u32);
356 
357 	cpu_maps_update_begin();
358 	for (i = 0; i < nthreads; i++) {
359 		thread = be32_to_cpu(intserv[i]);
360 		for_each_present_cpu(cpu) {
361 			if (get_hard_smp_processor_id(cpu) != thread)
362 				continue;
363 			BUG_ON(get_cpu_current_state(cpu)
364 					!= CPU_STATE_OFFLINE);
365 			cpu_maps_update_done();
366 			rc = device_online(get_cpu_device(cpu));
367 			if (rc)
368 				goto out;
369 			cpu_maps_update_begin();
370 
371 			break;
372 		}
373 		if (cpu == num_possible_cpus())
374 			printk(KERN_WARNING "Could not find cpu to online "
375 			       "with physical id 0x%x\n", thread);
376 	}
377 	cpu_maps_update_done();
378 
379 out:
380 	return rc;
381 
382 }
383 
384 static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
385 {
386 	struct device_node *dn, *parent;
387 	u32 drc_index;
388 	int rc;
389 
390 	rc = kstrtou32(buf, 0, &drc_index);
391 	if (rc)
392 		return -EINVAL;
393 
394 	rc = dlpar_acquire_drc(drc_index);
395 	if (rc)
396 		return -EINVAL;
397 
398 	parent = of_find_node_by_path("/cpus");
399 	if (!parent)
400 		return -ENODEV;
401 
402 	dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
403 	of_node_put(parent);
404 	if (!dn) {
405 		dlpar_release_drc(drc_index);
406 		return -EINVAL;
407 	}
408 
409 	rc = dlpar_attach_node(dn);
410 	if (rc) {
411 		dlpar_release_drc(drc_index);
412 		dlpar_free_cc_nodes(dn);
413 		return rc;
414 	}
415 
416 	rc = dlpar_online_cpu(dn);
417 	if (rc)
418 		return rc;
419 
420 	return count;
421 }
422 
423 static int dlpar_offline_cpu(struct device_node *dn)
424 {
425 	int rc = 0;
426 	unsigned int cpu;
427 	int len, nthreads, i;
428 	const __be32 *intserv;
429 	u32 thread;
430 
431 	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
432 	if (!intserv)
433 		return -EINVAL;
434 
435 	nthreads = len / sizeof(u32);
436 
437 	cpu_maps_update_begin();
438 	for (i = 0; i < nthreads; i++) {
439 		thread = be32_to_cpu(intserv[i]);
440 		for_each_present_cpu(cpu) {
441 			if (get_hard_smp_processor_id(cpu) != thread)
442 				continue;
443 
444 			if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
445 				break;
446 
447 			if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
448 				set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
449 				cpu_maps_update_done();
450 				rc = device_offline(get_cpu_device(cpu));
451 				if (rc)
452 					goto out;
453 				cpu_maps_update_begin();
454 				break;
455 
456 			}
457 
458 			/*
459 			 * The cpu is in CPU_STATE_INACTIVE.
460 			 * Upgrade it's state to CPU_STATE_OFFLINE.
461 			 */
462 			set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
463 			BUG_ON(plpar_hcall_norets(H_PROD, thread)
464 								!= H_SUCCESS);
465 			__cpu_die(cpu);
466 			break;
467 		}
468 		if (cpu == num_possible_cpus())
469 			printk(KERN_WARNING "Could not find cpu to offline "
470 			       "with physical id 0x%x\n", thread);
471 	}
472 	cpu_maps_update_done();
473 
474 out:
475 	return rc;
476 
477 }
478 
479 static ssize_t dlpar_cpu_release(const char *buf, size_t count)
480 {
481 	struct device_node *dn;
482 	u32 drc_index;
483 	int rc;
484 
485 	dn = of_find_node_by_path(buf);
486 	if (!dn)
487 		return -EINVAL;
488 
489 	rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
490 	if (rc) {
491 		of_node_put(dn);
492 		return -EINVAL;
493 	}
494 
495 	rc = dlpar_offline_cpu(dn);
496 	if (rc) {
497 		of_node_put(dn);
498 		return -EINVAL;
499 	}
500 
501 	rc = dlpar_release_drc(drc_index);
502 	if (rc) {
503 		of_node_put(dn);
504 		return rc;
505 	}
506 
507 	rc = dlpar_detach_node(dn);
508 	if (rc) {
509 		dlpar_acquire_drc(drc_index);
510 		return rc;
511 	}
512 
513 	of_node_put(dn);
514 
515 	return count;
516 }
517 
518 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
519 
520 static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
521 {
522 	int rc;
523 
524 	/* pseries error logs are in BE format, convert to cpu type */
525 	switch (hp_elog->id_type) {
526 	case PSERIES_HP_ELOG_ID_DRC_COUNT:
527 		hp_elog->_drc_u.drc_count =
528 					be32_to_cpu(hp_elog->_drc_u.drc_count);
529 		break;
530 	case PSERIES_HP_ELOG_ID_DRC_INDEX:
531 		hp_elog->_drc_u.drc_index =
532 					be32_to_cpu(hp_elog->_drc_u.drc_index);
533 	}
534 
535 	switch (hp_elog->resource) {
536 	case PSERIES_HP_ELOG_RESOURCE_MEM:
537 		rc = dlpar_memory(hp_elog);
538 		break;
539 	default:
540 		pr_warn_ratelimited("Invalid resource (%d) specified\n",
541 				    hp_elog->resource);
542 		rc = -EINVAL;
543 	}
544 
545 	return rc;
546 }
547 
548 static ssize_t dlpar_store(struct class *class, struct class_attribute *attr,
549 			   const char *buf, size_t count)
550 {
551 	struct pseries_hp_errorlog *hp_elog;
552 	const char *arg;
553 	int rc;
554 
555 	hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL);
556 	if (!hp_elog) {
557 		rc = -ENOMEM;
558 		goto dlpar_store_out;
559 	}
560 
561 	/* Parse out the request from the user, this will be in the form
562 	 * <resource> <action> <id_type> <id>
563 	 */
564 	arg = buf;
565 	if (!strncmp(arg, "memory", 6)) {
566 		hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
567 		arg += strlen("memory ");
568 	} else {
569 		pr_err("Invalid resource specified: \"%s\"\n", buf);
570 		rc = -EINVAL;
571 		goto dlpar_store_out;
572 	}
573 
574 	if (!strncmp(arg, "add", 3)) {
575 		hp_elog->action = PSERIES_HP_ELOG_ACTION_ADD;
576 		arg += strlen("add ");
577 	} else if (!strncmp(arg, "remove", 6)) {
578 		hp_elog->action = PSERIES_HP_ELOG_ACTION_REMOVE;
579 		arg += strlen("remove ");
580 	} else {
581 		pr_err("Invalid action specified: \"%s\"\n", buf);
582 		rc = -EINVAL;
583 		goto dlpar_store_out;
584 	}
585 
586 	if (!strncmp(arg, "index", 5)) {
587 		u32 index;
588 
589 		hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
590 		arg += strlen("index ");
591 		if (kstrtou32(arg, 0, &index)) {
592 			rc = -EINVAL;
593 			pr_err("Invalid drc_index specified: \"%s\"\n", buf);
594 			goto dlpar_store_out;
595 		}
596 
597 		hp_elog->_drc_u.drc_index = cpu_to_be32(index);
598 	} else if (!strncmp(arg, "count", 5)) {
599 		u32 count;
600 
601 		hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_COUNT;
602 		arg += strlen("count ");
603 		if (kstrtou32(arg, 0, &count)) {
604 			rc = -EINVAL;
605 			pr_err("Invalid count specified: \"%s\"\n", buf);
606 			goto dlpar_store_out;
607 		}
608 
609 		hp_elog->_drc_u.drc_count = cpu_to_be32(count);
610 	} else {
611 		pr_err("Invalid id_type specified: \"%s\"\n", buf);
612 		rc = -EINVAL;
613 		goto dlpar_store_out;
614 	}
615 
616 	rc = handle_dlpar_errorlog(hp_elog);
617 
618 dlpar_store_out:
619 	kfree(hp_elog);
620 	return rc ? rc : count;
621 }
622 
623 static CLASS_ATTR(dlpar, S_IWUSR, NULL, dlpar_store);
624 
625 static int __init pseries_dlpar_init(void)
626 {
627 	int rc;
628 
629 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
630 	ppc_md.cpu_probe = dlpar_cpu_probe;
631 	ppc_md.cpu_release = dlpar_cpu_release;
632 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
633 
634 	rc = sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
635 
636 	return rc;
637 }
638 machine_device_initcall(pseries, pseries_dlpar_init);
639 
640