xref: /linux/arch/powerpc/platforms/pseries/lparcfg.c (revision fcb3ad4366b9c810cbb9da34c076a9a52d8aa1e0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * PowerPC64 LPAR Configuration Information Driver
4  *
5  * Dave Engebretsen engebret@us.ibm.com
6  *    Copyright (c) 2003 Dave Engebretsen
7  * Will Schmidt willschm@us.ibm.com
8  *    SPLPAR updates, Copyright (c) 2003 Will Schmidt IBM Corporation.
9  *    seq_file updates, Copyright (c) 2004 Will Schmidt IBM Corporation.
10  * Nathan Lynch nathanl@austin.ibm.com
11  *    Added lparcfg_write, Copyright (C) 2004 Nathan Lynch IBM Corporation.
12  *
13  * This driver creates a proc file at /proc/ppc64/lparcfg which contains
14  * keyword - value pairs that specify the configuration of the partition.
15  */
16 
17 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/proc_fs.h>
21 #include <linux/init.h>
22 #include <asm/papr-sysparm.h>
23 #include <linux/seq_file.h>
24 #include <linux/slab.h>
25 #include <linux/uaccess.h>
26 #include <linux/hugetlb.h>
27 #include <asm/lppaca.h>
28 #include <asm/hvcall.h>
29 #include <asm/firmware.h>
30 #include <asm/rtas.h>
31 #include <asm/time.h>
32 #include <asm/vio.h>
33 #include <asm/mmu.h>
34 #include <asm/machdep.h>
35 #include <asm/drmem.h>
36 
37 #include "pseries.h"
38 #include "vas.h"	/* pseries_vas_dlpar_cpu() */
39 
40 /*
41  * This isn't a module but we expose that to userspace
42  * via /proc so leave the definitions here
43  */
44 #define MODULE_VERS "1.9"
45 #define MODULE_NAME "lparcfg"
46 
47 /* #define LPARCFG_DEBUG */
48 
49 /*
50  * Track sum of all purrs across all processors. This is used to further
51  * calculate usage values by different applications
52  */
53 static void cpu_get_purr(void *arg)
54 {
55 	atomic64_t *sum = arg;
56 
57 	atomic64_add(mfspr(SPRN_PURR), sum);
58 }
59 
60 static unsigned long get_purr(void)
61 {
62 	atomic64_t purr = ATOMIC64_INIT(0);
63 
64 	on_each_cpu(cpu_get_purr, &purr, 1);
65 
66 	return atomic64_read(&purr);
67 }
68 
69 /*
70  * Methods used to fetch LPAR data when running on a pSeries platform.
71  */
72 
73 struct hvcall_ppp_data {
74 	u64	entitlement;
75 	u64	unallocated_entitlement;
76 	u16	group_num;
77 	u16	pool_num;
78 	u8	capped;
79 	u8	weight;
80 	u8	unallocated_weight;
81 	u16	active_procs_in_pool;
82 	u16	active_system_procs;
83 	u16	phys_platform_procs;
84 	u32	max_proc_cap_avail;
85 	u32	entitled_proc_cap_avail;
86 };
87 
88 /*
89  * H_GET_PPP hcall returns info in 4 parms.
90  *  entitled_capacity,unallocated_capacity,
91  *  aggregation, resource_capability).
92  *
93  *  R4 = Entitled Processor Capacity Percentage.
94  *  R5 = Unallocated Processor Capacity Percentage.
95  *  R6 (AABBCCDDEEFFGGHH).
96  *      XXXX - reserved (0)
97  *          XXXX - reserved (0)
98  *              XXXX - Group Number
99  *                  XXXX - Pool Number.
100  *  R7 (IIJJKKLLMMNNOOPP).
101  *      XX - reserved. (0)
102  *        XX - bit 0-6 reserved (0).   bit 7 is Capped indicator.
103  *          XX - variable processor Capacity Weight
104  *            XX - Unallocated Variable Processor Capacity Weight.
105  *              XXXX - Active processors in Physical Processor Pool.
106  *                  XXXX  - Processors active on platform.
107  *  R8 (QQQQRRRRRRSSSSSS). if ibm,partition-performance-parameters-level >= 1
108  *	XXXX - Physical platform procs allocated to virtualization.
109  *	    XXXXXX - Max procs capacity % available to the partitions pool.
110  *	          XXXXXX - Entitled procs capacity % available to the
111  *			   partitions pool.
112  */
113 static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
114 {
115 	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
116 	long rc;
117 
118 	rc = plpar_hcall9(H_GET_PPP, retbuf);
119 
120 	ppp_data->entitlement = retbuf[0];
121 	ppp_data->unallocated_entitlement = retbuf[1];
122 
123 	ppp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
124 	ppp_data->pool_num = retbuf[2] & 0xffff;
125 
126 	ppp_data->capped = (retbuf[3] >> 6 * 8) & 0x01;
127 	ppp_data->weight = (retbuf[3] >> 5 * 8) & 0xff;
128 	ppp_data->unallocated_weight = (retbuf[3] >> 4 * 8) & 0xff;
129 	ppp_data->active_procs_in_pool = (retbuf[3] >> 2 * 8) & 0xffff;
130 	ppp_data->active_system_procs = retbuf[3] & 0xffff;
131 
132 	ppp_data->phys_platform_procs = retbuf[4] >> 6 * 8;
133 	ppp_data->max_proc_cap_avail = (retbuf[4] >> 3 * 8) & 0xffffff;
134 	ppp_data->entitled_proc_cap_avail = retbuf[4] & 0xffffff;
135 
136 	return rc;
137 }
138 
139 static void show_gpci_data(struct seq_file *m)
140 {
141 	struct hv_gpci_request_buffer *buf;
142 	unsigned int affinity_score;
143 	long ret;
144 
145 	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
146 	if (buf == NULL)
147 		return;
148 
149 	/*
150 	 * Show the local LPAR's affinity score.
151 	 *
152 	 * 0xB1 selects the Affinity_Domain_Info_By_Partition subcall.
153 	 * The score is at byte 0xB in the output buffer.
154 	 */
155 	memset(&buf->params, 0, sizeof(buf->params));
156 	buf->params.counter_request = cpu_to_be32(0xB1);
157 	buf->params.starting_index = cpu_to_be32(-1);	/* local LPAR */
158 	buf->params.counter_info_version_in = 0x5;	/* v5+ for score */
159 	ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, virt_to_phys(buf),
160 				 sizeof(*buf));
161 	if (ret != H_SUCCESS) {
162 		pr_debug("hcall failed: H_GET_PERF_COUNTER_INFO: %ld, %x\n",
163 			 ret, be32_to_cpu(buf->params.detail_rc));
164 		goto out;
165 	}
166 	affinity_score = buf->bytes[0xB];
167 	seq_printf(m, "partition_affinity_score=%u\n", affinity_score);
168 out:
169 	kfree(buf);
170 }
171 
172 static long h_pic(unsigned long *pool_idle_time,
173 		  unsigned long *num_procs)
174 {
175 	long rc;
176 	unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = {0};
177 
178 	rc = plpar_hcall(H_PIC, retbuf);
179 
180 	if (pool_idle_time)
181 		*pool_idle_time = retbuf[0];
182 	if (num_procs)
183 		*num_procs = retbuf[1];
184 
185 	return rc;
186 }
187 
188 unsigned long boot_pool_idle_time;
189 
190 /*
191  * parse_ppp_data
192  * Parse out the data returned from h_get_ppp and h_pic
193  */
194 static void parse_ppp_data(struct seq_file *m)
195 {
196 	struct hvcall_ppp_data ppp_data;
197 	struct device_node *root;
198 	const __be32 *perf_level;
199 	long rc;
200 
201 	rc = h_get_ppp(&ppp_data);
202 	if (rc)
203 		return;
204 
205 	seq_printf(m, "partition_entitled_capacity=%lld\n",
206 	           ppp_data.entitlement);
207 	seq_printf(m, "group=%d\n", ppp_data.group_num);
208 	seq_printf(m, "system_active_processors=%d\n",
209 	           ppp_data.active_system_procs);
210 
211 	/* pool related entries are appropriate for shared configs */
212 	if (lppaca_shared_proc()) {
213 		unsigned long pool_idle_time, pool_procs;
214 
215 		seq_printf(m, "pool=%d\n", ppp_data.pool_num);
216 
217 		/* report pool_capacity in percentage */
218 		seq_printf(m, "pool_capacity=%d\n",
219 			   ppp_data.active_procs_in_pool * 100);
220 
221 		/* In case h_pic call is not successful, this would result in
222 		 * APP values being wrong in tools like lparstat.
223 		 */
224 
225 		if (h_pic(&pool_idle_time, &pool_procs) == H_SUCCESS) {
226 			seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
227 			seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
228 			seq_printf(m, "boot_pool_idle_time=%ld\n", boot_pool_idle_time);
229 		}
230 	}
231 
232 	seq_printf(m, "unallocated_capacity_weight=%d\n",
233 		   ppp_data.unallocated_weight);
234 	seq_printf(m, "capacity_weight=%d\n", ppp_data.weight);
235 	seq_printf(m, "capped=%d\n", ppp_data.capped);
236 	seq_printf(m, "unallocated_capacity=%lld\n",
237 		   ppp_data.unallocated_entitlement);
238 
239 	/* The last bits of information returned from h_get_ppp are only
240 	 * valid if the ibm,partition-performance-parameters-level
241 	 * property is >= 1.
242 	 */
243 	root = of_find_node_by_path("/");
244 	if (root) {
245 		perf_level = of_get_property(root,
246 				"ibm,partition-performance-parameters-level",
247 					     NULL);
248 		if (perf_level && (be32_to_cpup(perf_level) >= 1)) {
249 			seq_printf(m,
250 			    "physical_procs_allocated_to_virtualization=%d\n",
251 				   ppp_data.phys_platform_procs);
252 			seq_printf(m, "max_proc_capacity_available=%d\n",
253 				   ppp_data.max_proc_cap_avail);
254 			seq_printf(m, "entitled_proc_capacity_available=%d\n",
255 				   ppp_data.entitled_proc_cap_avail);
256 		}
257 
258 		of_node_put(root);
259 	}
260 }
261 
262 /**
263  * parse_mpp_data
264  * Parse out data returned from h_get_mpp
265  */
266 static void parse_mpp_data(struct seq_file *m)
267 {
268 	struct hvcall_mpp_data mpp_data;
269 	int rc;
270 
271 	rc = h_get_mpp(&mpp_data);
272 	if (rc)
273 		return;
274 
275 	seq_printf(m, "entitled_memory=%ld\n", mpp_data.entitled_mem);
276 
277 	if (mpp_data.mapped_mem != -1)
278 		seq_printf(m, "mapped_entitled_memory=%ld\n",
279 		           mpp_data.mapped_mem);
280 
281 	seq_printf(m, "entitled_memory_group_number=%d\n", mpp_data.group_num);
282 	seq_printf(m, "entitled_memory_pool_number=%d\n", mpp_data.pool_num);
283 
284 	seq_printf(m, "entitled_memory_weight=%d\n", mpp_data.mem_weight);
285 	seq_printf(m, "unallocated_entitled_memory_weight=%d\n",
286 	           mpp_data.unallocated_mem_weight);
287 	seq_printf(m, "unallocated_io_mapping_entitlement=%ld\n",
288 	           mpp_data.unallocated_entitlement);
289 
290 	if (mpp_data.pool_size != -1)
291 		seq_printf(m, "entitled_memory_pool_size=%ld bytes\n",
292 		           mpp_data.pool_size);
293 
294 	seq_printf(m, "entitled_memory_loan_request=%ld\n",
295 	           mpp_data.loan_request);
296 
297 	seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
298 }
299 
300 /**
301  * parse_mpp_x_data
302  * Parse out data returned from h_get_mpp_x
303  */
304 static void parse_mpp_x_data(struct seq_file *m)
305 {
306 	struct hvcall_mpp_x_data mpp_x_data;
307 
308 	if (!firmware_has_feature(FW_FEATURE_XCMO))
309 		return;
310 	if (h_get_mpp_x(&mpp_x_data))
311 		return;
312 
313 	seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes);
314 
315 	if (mpp_x_data.pool_coalesced_bytes)
316 		seq_printf(m, "pool_coalesced_bytes=%ld\n",
317 			   mpp_x_data.pool_coalesced_bytes);
318 	if (mpp_x_data.pool_purr_cycles)
319 		seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles);
320 	if (mpp_x_data.pool_spurr_cycles)
321 		seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
322 }
323 
324 /*
325  * Read the lpar name using the RTAS ibm,get-system-parameter call.
326  *
327  * The name read through this call is updated if changes are made by the end
328  * user on the hypervisor side.
329  *
330  * Some hypervisor (like Qemu) may not provide this value. In that case, a non
331  * null value is returned.
332  */
333 static int read_rtas_lpar_name(struct seq_file *m)
334 {
335 	struct papr_sysparm_buf *buf;
336 	int err;
337 
338 	buf = papr_sysparm_buf_alloc();
339 	if (!buf)
340 		return -ENOMEM;
341 
342 	err = papr_sysparm_get(PAPR_SYSPARM_LPAR_NAME, buf);
343 	if (!err)
344 		seq_printf(m, "partition_name=%s\n", buf->val);
345 
346 	papr_sysparm_buf_free(buf);
347 	return err;
348 }
349 
350 /*
351  * Read the LPAR name from the Device Tree.
352  *
353  * The value read in the DT is not updated if the end-user is touching the LPAR
354  * name on the hypervisor side.
355  */
356 static int read_dt_lpar_name(struct seq_file *m)
357 {
358 	struct device_node *root = of_find_node_by_path("/");
359 	const char *name;
360 	int ret;
361 
362 	ret = of_property_read_string(root, "ibm,partition-name", &name);
363 	of_node_put(root);
364 	if (ret)
365 		return -ENOENT;
366 
367 	seq_printf(m, "partition_name=%s\n", name);
368 	return 0;
369 }
370 
371 static void read_lpar_name(struct seq_file *m)
372 {
373 	if (read_rtas_lpar_name(m))
374 		read_dt_lpar_name(m);
375 }
376 
377 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
378 
379 /*
380  * parse_system_parameter_string()
381  * Retrieve the potential_processors, max_entitled_capacity and friends
382  * through the get-system-parameter rtas call.  Replace keyword strings as
383  * necessary.
384  */
385 static void parse_system_parameter_string(struct seq_file *m)
386 {
387 	struct papr_sysparm_buf *buf;
388 
389 	buf = papr_sysparm_buf_alloc();
390 	if (!buf)
391 		return;
392 
393 	if (papr_sysparm_get(PAPR_SYSPARM_SHARED_PROC_LPAR_ATTRS, buf)) {
394 		goto out_free;
395 	} else {
396 		const char *local_buffer;
397 		int splpar_strlen;
398 		int idx, w_idx;
399 		char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
400 
401 		if (!workbuffer)
402 			goto out_free;
403 
404 		splpar_strlen = be16_to_cpu(buf->len);
405 		local_buffer = buf->val;
406 
407 		w_idx = 0;
408 		idx = 0;
409 		while ((*local_buffer) && (idx < splpar_strlen)) {
410 			workbuffer[w_idx++] = local_buffer[idx++];
411 			if ((local_buffer[idx] == ',')
412 			    || (local_buffer[idx] == '\0')) {
413 				workbuffer[w_idx] = '\0';
414 				if (w_idx) {
415 					/* avoid the empty string */
416 					seq_printf(m, "%s\n", workbuffer);
417 				}
418 				memset(workbuffer, 0, SPLPAR_MAXLENGTH);
419 				idx++;	/* skip the comma */
420 				w_idx = 0;
421 			} else if (local_buffer[idx] == '=') {
422 				/* code here to replace workbuffer contents
423 				   with different keyword strings */
424 				if (0 == strcmp(workbuffer, "MaxEntCap")) {
425 					strcpy(workbuffer,
426 					       "partition_max_entitled_capacity");
427 					w_idx = strlen(workbuffer);
428 				}
429 				if (0 == strcmp(workbuffer, "MaxPlatProcs")) {
430 					strcpy(workbuffer,
431 					       "system_potential_processors");
432 					w_idx = strlen(workbuffer);
433 				}
434 			}
435 		}
436 		kfree(workbuffer);
437 		local_buffer -= 2;	/* back up over strlen value */
438 	}
439 out_free:
440 	papr_sysparm_buf_free(buf);
441 }
442 
443 /* Return the number of processors in the system.
444  * This function reads through the device tree and counts
445  * the virtual processors, this does not include threads.
446  */
447 static int lparcfg_count_active_processors(void)
448 {
449 	struct device_node *cpus_dn;
450 	int count = 0;
451 
452 	for_each_node_by_type(cpus_dn, "cpu") {
453 #ifdef LPARCFG_DEBUG
454 		printk(KERN_ERR "cpus_dn %p\n", cpus_dn);
455 #endif
456 		count++;
457 	}
458 	return count;
459 }
460 
461 static void pseries_cmo_data(struct seq_file *m)
462 {
463 	int cpu;
464 	unsigned long cmo_faults = 0;
465 	unsigned long cmo_fault_time = 0;
466 
467 	seq_printf(m, "cmo_enabled=%d\n", firmware_has_feature(FW_FEATURE_CMO));
468 
469 	if (!firmware_has_feature(FW_FEATURE_CMO))
470 		return;
471 
472 	for_each_possible_cpu(cpu) {
473 		cmo_faults += be64_to_cpu(lppaca_of(cpu).cmo_faults);
474 		cmo_fault_time += be64_to_cpu(lppaca_of(cpu).cmo_fault_time);
475 	}
476 
477 	seq_printf(m, "cmo_faults=%lu\n", cmo_faults);
478 	seq_printf(m, "cmo_fault_time_usec=%lu\n",
479 		   cmo_fault_time / tb_ticks_per_usec);
480 	seq_printf(m, "cmo_primary_psp=%d\n", cmo_get_primary_psp());
481 	seq_printf(m, "cmo_secondary_psp=%d\n", cmo_get_secondary_psp());
482 	seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size());
483 }
484 
485 static void splpar_dispatch_data(struct seq_file *m)
486 {
487 	int cpu;
488 	unsigned long dispatches = 0;
489 	unsigned long dispatch_dispersions = 0;
490 
491 	for_each_possible_cpu(cpu) {
492 		dispatches += be32_to_cpu(lppaca_of(cpu).yield_count);
493 		dispatch_dispersions +=
494 			be32_to_cpu(lppaca_of(cpu).dispersion_count);
495 	}
496 
497 	seq_printf(m, "dispatches=%lu\n", dispatches);
498 	seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions);
499 }
500 
501 static void parse_em_data(struct seq_file *m)
502 {
503 	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
504 
505 	if (firmware_has_feature(FW_FEATURE_LPAR) &&
506 	    plpar_hcall(H_GET_EM_PARMS, retbuf) == H_SUCCESS)
507 		seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
508 }
509 
510 static void maxmem_data(struct seq_file *m)
511 {
512 	unsigned long maxmem = 0;
513 
514 	maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size;
515 	maxmem += hugetlb_total_pages() * PAGE_SIZE;
516 
517 	seq_printf(m, "MaxMem=%lu\n", maxmem);
518 }
519 
520 static int pseries_lparcfg_data(struct seq_file *m, void *v)
521 {
522 	int partition_potential_processors;
523 	int partition_active_processors;
524 	struct device_node *rtas_node;
525 	const __be32 *lrdrp = NULL;
526 
527 	rtas_node = of_find_node_by_path("/rtas");
528 	if (rtas_node)
529 		lrdrp = of_get_property(rtas_node, "ibm,lrdr-capacity", NULL);
530 
531 	if (lrdrp == NULL) {
532 		partition_potential_processors = num_possible_cpus();
533 	} else {
534 		partition_potential_processors = be32_to_cpup(lrdrp + 4);
535 	}
536 	of_node_put(rtas_node);
537 
538 	partition_active_processors = lparcfg_count_active_processors();
539 
540 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
541 		/* this call handles the ibm,get-system-parameter contents */
542 		read_lpar_name(m);
543 		parse_system_parameter_string(m);
544 		parse_ppp_data(m);
545 		parse_mpp_data(m);
546 		parse_mpp_x_data(m);
547 		pseries_cmo_data(m);
548 		splpar_dispatch_data(m);
549 
550 		seq_printf(m, "purr=%ld\n", get_purr());
551 		seq_printf(m, "tbr=%ld\n", mftb());
552 	} else {		/* non SPLPAR case */
553 
554 		seq_printf(m, "system_active_processors=%d\n",
555 			   partition_active_processors);
556 
557 		seq_printf(m, "system_potential_processors=%d\n",
558 			   partition_potential_processors);
559 
560 		seq_printf(m, "partition_max_entitled_capacity=%d\n",
561 			   partition_potential_processors * 100);
562 
563 		seq_printf(m, "partition_entitled_capacity=%d\n",
564 			   partition_active_processors * 100);
565 	}
566 
567 	show_gpci_data(m);
568 
569 	seq_printf(m, "partition_active_processors=%d\n",
570 		   partition_active_processors);
571 
572 	seq_printf(m, "partition_potential_processors=%d\n",
573 		   partition_potential_processors);
574 
575 	seq_printf(m, "shared_processor_mode=%d\n",
576 		   lppaca_shared_proc());
577 
578 #ifdef CONFIG_PPC_64S_HASH_MMU
579 	if (!radix_enabled())
580 		seq_printf(m, "slb_size=%d\n", mmu_slb_size);
581 #endif
582 	parse_em_data(m);
583 	maxmem_data(m);
584 
585 	seq_printf(m, "security_flavor=%u\n", pseries_security_flavor);
586 
587 	return 0;
588 }
589 
590 static ssize_t update_ppp(u64 *entitlement, u8 *weight)
591 {
592 	struct hvcall_ppp_data ppp_data;
593 	u8 new_weight;
594 	u64 new_entitled;
595 	ssize_t retval;
596 
597 	/* Get our current parameters */
598 	retval = h_get_ppp(&ppp_data);
599 	if (retval)
600 		return retval;
601 
602 	if (entitlement) {
603 		new_weight = ppp_data.weight;
604 		new_entitled = *entitlement;
605 	} else if (weight) {
606 		new_weight = *weight;
607 		new_entitled = ppp_data.entitlement;
608 	} else
609 		return -EINVAL;
610 
611 	pr_debug("%s: current_entitled = %llu, current_weight = %u\n",
612 		 __func__, ppp_data.entitlement, ppp_data.weight);
613 
614 	pr_debug("%s: new_entitled = %llu, new_weight = %u\n",
615 		 __func__, new_entitled, new_weight);
616 
617 	retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight);
618 	return retval;
619 }
620 
621 /**
622  * update_mpp
623  *
624  * Update the memory entitlement and weight for the partition.  Caller must
625  * specify either a new entitlement or weight, not both, to be updated
626  * since the h_set_mpp call takes both entitlement and weight as parameters.
627  */
628 static ssize_t update_mpp(u64 *entitlement, u8 *weight)
629 {
630 	struct hvcall_mpp_data mpp_data;
631 	u64 new_entitled;
632 	u8 new_weight;
633 	ssize_t rc;
634 
635 	if (entitlement) {
636 		/* Check with vio to ensure the new memory entitlement
637 		 * can be handled.
638 		 */
639 		rc = vio_cmo_entitlement_update(*entitlement);
640 		if (rc)
641 			return rc;
642 	}
643 
644 	rc = h_get_mpp(&mpp_data);
645 	if (rc)
646 		return rc;
647 
648 	if (entitlement) {
649 		new_weight = mpp_data.mem_weight;
650 		new_entitled = *entitlement;
651 	} else if (weight) {
652 		new_weight = *weight;
653 		new_entitled = mpp_data.entitled_mem;
654 	} else
655 		return -EINVAL;
656 
657 	pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
658 	         __func__, mpp_data.entitled_mem, mpp_data.mem_weight);
659 
660 	pr_debug("%s: new_entitled = %llu, new_weight = %u\n",
661 		 __func__, new_entitled, new_weight);
662 
663 	rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight);
664 	return rc;
665 }
666 
667 /*
668  * Interface for changing system parameters (variable capacity weight
669  * and entitled capacity).  Format of input is "param_name=value";
670  * anything after value is ignored.  Valid parameters at this time are
671  * "partition_entitled_capacity" and "capacity_weight".  We use
672  * H_SET_PPP to alter parameters.
673  *
674  * This function should be invoked only on systems with
675  * FW_FEATURE_SPLPAR.
676  */
677 static ssize_t lparcfg_write(struct file *file, const char __user * buf,
678 			     size_t count, loff_t * off)
679 {
680 	char kbuf[64];
681 	char *tmp;
682 	u64 new_entitled, *new_entitled_ptr = &new_entitled;
683 	u8 new_weight, *new_weight_ptr = &new_weight;
684 	ssize_t retval;
685 
686 	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
687 		return -EINVAL;
688 
689 	if (count > sizeof(kbuf))
690 		return -EINVAL;
691 
692 	if (copy_from_user(kbuf, buf, count))
693 		return -EFAULT;
694 
695 	kbuf[count - 1] = '\0';
696 	tmp = strchr(kbuf, '=');
697 	if (!tmp)
698 		return -EINVAL;
699 
700 	*tmp++ = '\0';
701 
702 	if (!strcmp(kbuf, "partition_entitled_capacity")) {
703 		char *endp;
704 		*new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
705 		if (endp == tmp)
706 			return -EINVAL;
707 
708 		retval = update_ppp(new_entitled_ptr, NULL);
709 
710 		if (retval == H_SUCCESS || retval == H_CONSTRAINED) {
711 			/*
712 			 * The hypervisor assigns VAS resources based
713 			 * on entitled capacity for shared mode.
714 			 * Reconfig VAS windows based on DLPAR CPU events.
715 			 */
716 			if (pseries_vas_dlpar_cpu() != 0)
717 				retval = H_HARDWARE;
718 		}
719 	} else if (!strcmp(kbuf, "capacity_weight")) {
720 		char *endp;
721 		*new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
722 		if (endp == tmp)
723 			return -EINVAL;
724 
725 		retval = update_ppp(NULL, new_weight_ptr);
726 	} else if (!strcmp(kbuf, "entitled_memory")) {
727 		char *endp;
728 		*new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
729 		if (endp == tmp)
730 			return -EINVAL;
731 
732 		retval = update_mpp(new_entitled_ptr, NULL);
733 	} else if (!strcmp(kbuf, "entitled_memory_weight")) {
734 		char *endp;
735 		*new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
736 		if (endp == tmp)
737 			return -EINVAL;
738 
739 		retval = update_mpp(NULL, new_weight_ptr);
740 	} else
741 		return -EINVAL;
742 
743 	if (retval == H_SUCCESS || retval == H_CONSTRAINED) {
744 		retval = count;
745 	} else if (retval == H_BUSY) {
746 		retval = -EBUSY;
747 	} else if (retval == H_HARDWARE) {
748 		retval = -EIO;
749 	} else if (retval == H_PARAMETER) {
750 		retval = -EINVAL;
751 	}
752 
753 	return retval;
754 }
755 
756 static int lparcfg_data(struct seq_file *m, void *v)
757 {
758 	struct device_node *rootdn;
759 	const char *model = "";
760 	const char *system_id = "";
761 	const char *tmp;
762 	const __be32 *lp_index_ptr;
763 	unsigned int lp_index = 0;
764 
765 	seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);
766 
767 	rootdn = of_find_node_by_path("/");
768 	if (rootdn) {
769 		tmp = of_get_property(rootdn, "model", NULL);
770 		if (tmp)
771 			model = tmp;
772 		tmp = of_get_property(rootdn, "system-id", NULL);
773 		if (tmp)
774 			system_id = tmp;
775 		lp_index_ptr = of_get_property(rootdn, "ibm,partition-no",
776 					NULL);
777 		if (lp_index_ptr)
778 			lp_index = be32_to_cpup(lp_index_ptr);
779 		of_node_put(rootdn);
780 	}
781 	seq_printf(m, "serial_number=%s\n", system_id);
782 	seq_printf(m, "system_type=%s\n", model);
783 	seq_printf(m, "partition_id=%d\n", (int)lp_index);
784 
785 	return pseries_lparcfg_data(m, v);
786 }
787 
788 static int lparcfg_open(struct inode *inode, struct file *file)
789 {
790 	return single_open(file, lparcfg_data, NULL);
791 }
792 
793 static const struct proc_ops lparcfg_proc_ops = {
794 	.proc_read	= seq_read,
795 	.proc_write	= lparcfg_write,
796 	.proc_open	= lparcfg_open,
797 	.proc_release	= single_release,
798 	.proc_lseek	= seq_lseek,
799 };
800 
801 static int __init lparcfg_init(void)
802 {
803 	umode_t mode = 0444;
804 	long retval;
805 
806 	/* Allow writing if we have FW_FEATURE_SPLPAR */
807 	if (firmware_has_feature(FW_FEATURE_SPLPAR))
808 		mode |= 0200;
809 
810 	if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_proc_ops)) {
811 		printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
812 		return -EIO;
813 	}
814 
815 	/* If this call fails, it would result in APP values
816 	 * being wrong for since boot reports of lparstat
817 	 */
818 	retval = h_pic(&boot_pool_idle_time, NULL);
819 
820 	if (retval != H_SUCCESS)
821 		pr_debug("H_PIC failed during lparcfg init retval: %ld\n",
822 			 retval);
823 
824 	return 0;
825 }
826 machine_device_initcall(pseries, lparcfg_init);
827