aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/lparcfg.c121
-rw-r--r--include/asm-powerpc/hvcall.h18
2 files changed, 137 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index a0ca90ab5e39..86e5b3ed10d8 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -35,7 +35,7 @@
35#include <asm/prom.h> 35#include <asm/prom.h>
36#include <asm/vdso_datapage.h> 36#include <asm/vdso_datapage.h>
37 37
38#define MODULE_VERS "1.7" 38#define MODULE_VERS "1.8"
39#define MODULE_NAME "lparcfg" 39#define MODULE_NAME "lparcfg"
40 40
41/* #define LPARCFG_DEBUG */ 41/* #define LPARCFG_DEBUG */
@@ -129,6 +129,35 @@ static int iseries_lparcfg_data(struct seq_file *m, void *v)
129/* 129/*
130 * Methods used to fetch LPAR data when running on a pSeries platform. 130 * Methods used to fetch LPAR data when running on a pSeries platform.
131 */ 131 */
132/**
133 * h_get_mpp
134 * H_GET_MPP hcall returns info in 7 parms
135 */
136int h_get_mpp(struct hvcall_mpp_data *mpp_data)
137{
138 int rc;
139 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
140
141 rc = plpar_hcall9(H_GET_MPP, retbuf);
142
143 mpp_data->entitled_mem = retbuf[0];
144 mpp_data->mapped_mem = retbuf[1];
145
146 mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
147 mpp_data->pool_num = retbuf[2] & 0xffff;
148
149 mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
150 mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
151 mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;
152
153 mpp_data->pool_size = retbuf[4];
154 mpp_data->loan_request = retbuf[5];
155 mpp_data->backing_mem = retbuf[6];
156
157 return rc;
158}
159EXPORT_SYMBOL(h_get_mpp);
160
132/* 161/*
133 * H_GET_PPP hcall returns info in 4 parms. 162 * H_GET_PPP hcall returns info in 4 parms.
134 * entitled_capacity,unallocated_capacity, 163 * entitled_capacity,unallocated_capacity,
@@ -224,6 +253,44 @@ static void parse_ppp_data(struct seq_file *m)
224 seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated); 253 seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated);
225} 254}
226 255
256/**
257 * parse_mpp_data
258 * Parse out data returned from h_get_mpp
259 */
260static void parse_mpp_data(struct seq_file *m)
261{
262 struct hvcall_mpp_data mpp_data;
263 int rc;
264
265 rc = h_get_mpp(&mpp_data);
266 if (rc)
267 return;
268
269 seq_printf(m, "entitled_memory=%ld\n", mpp_data.entitled_mem);
270
271 if (mpp_data.mapped_mem != -1)
272 seq_printf(m, "mapped_entitled_memory=%ld\n",
273 mpp_data.mapped_mem);
274
275 seq_printf(m, "entitled_memory_group_number=%d\n", mpp_data.group_num);
276 seq_printf(m, "entitled_memory_pool_number=%d\n", mpp_data.pool_num);
277
278 seq_printf(m, "entitled_memory_weight=%d\n", mpp_data.mem_weight);
279 seq_printf(m, "unallocated_entitled_memory_weight=%d\n",
280 mpp_data.unallocated_mem_weight);
281 seq_printf(m, "unallocated_io_mapping_entitlement=%ld\n",
282 mpp_data.unallocated_entitlement);
283
284 if (mpp_data.pool_size != -1)
285 seq_printf(m, "entitled_memory_pool_size=%ld bytes\n",
286 mpp_data.pool_size);
287
288 seq_printf(m, "entitled_memory_loan_request=%ld\n",
289 mpp_data.loan_request);
290
291 seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
292}
293
227#define SPLPAR_CHARACTERISTICS_TOKEN 20 294#define SPLPAR_CHARACTERISTICS_TOKEN 20
228#define SPLPAR_MAXLENGTH 1026*(sizeof(char)) 295#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
229 296
@@ -351,6 +418,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
351 /* this call handles the ibm,get-system-parameter contents */ 418 /* this call handles the ibm,get-system-parameter contents */
352 parse_system_parameter_string(m); 419 parse_system_parameter_string(m);
353 parse_ppp_data(m); 420 parse_ppp_data(m);
421 parse_mpp_data(m);
354 422
355 seq_printf(m, "purr=%ld\n", get_purr()); 423 seq_printf(m, "purr=%ld\n", get_purr());
356 } else { /* non SPLPAR case */ 424 } else { /* non SPLPAR case */
@@ -414,6 +482,43 @@ static ssize_t update_ppp(u64 *entitlement, u8 *weight)
414 return retval; 482 return retval;
415} 483}
416 484
485/**
486 * update_mpp
487 *
488 * Update the memory entitlement and weight for the partition. Caller must
489 * specify either a new entitlement or weight, not both, to be updated
490 * since the h_set_mpp call takes both entitlement and weight as parameters.
491 */
492static ssize_t update_mpp(u64 *entitlement, u8 *weight)
493{
494 struct hvcall_mpp_data mpp_data;
495 u64 new_entitled;
496 u8 new_weight;
497 ssize_t rc;
498
499 rc = h_get_mpp(&mpp_data);
500 if (rc)
501 return rc;
502
503 if (entitlement) {
504 new_weight = mpp_data.mem_weight;
505 new_entitled = *entitlement;
506 } else if (weight) {
507 new_weight = *weight;
508 new_entitled = mpp_data.entitled_mem;
509 } else
510 return -EINVAL;
511
512 pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
513 __FUNCTION__, mpp_data.entitled_mem, mpp_data.mem_weight);
514
515 pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
516 __FUNCTION__, new_entitled, new_weight);
517
518 rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight);
519 return rc;
520}
521
417/* 522/*
418 * Interface for changing system parameters (variable capacity weight 523 * Interface for changing system parameters (variable capacity weight
419 * and entitled capacity). Format of input is "param_name=value"; 524 * and entitled capacity). Format of input is "param_name=value";
@@ -467,6 +572,20 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
467 goto out; 572 goto out;
468 573
469 retval = update_ppp(NULL, new_weight_ptr); 574 retval = update_ppp(NULL, new_weight_ptr);
575 } else if (!strcmp(kbuf, "entitled_memory")) {
576 char *endp;
577 *new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
578 if (endp == tmp)
579 goto out;
580
581 retval = update_mpp(new_entitled_ptr, NULL);
582 } else if (!strcmp(kbuf, "entitled_memory_weight")) {
583 char *endp;
584 *new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
585 if (endp == tmp)
586 goto out;
587
588 retval = update_mpp(NULL, new_weight_ptr);
470 } else 589 } else
471 goto out; 590 goto out;
472 591
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index bf6cd7cb996c..46e76456cbbd 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -210,7 +210,9 @@
210#define H_JOIN 0x298 210#define H_JOIN 0x298
211#define H_VASI_STATE 0x2A4 211#define H_VASI_STATE 0x2A4
212#define H_ENABLE_CRQ 0x2B0 212#define H_ENABLE_CRQ 0x2B0
213#define MAX_HCALL_OPCODE H_ENABLE_CRQ 213#define H_SET_MPP 0x2D0
214#define H_GET_MPP 0x2D4
215#define MAX_HCALL_OPCODE H_GET_MPP
214 216
215#ifndef __ASSEMBLY__ 217#ifndef __ASSEMBLY__
216 218
@@ -270,6 +272,20 @@ struct hcall_stats {
270}; 272};
271#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1) 273#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
272 274
275struct hvcall_mpp_data {
276 unsigned long entitled_mem;
277 unsigned long mapped_mem;
278 unsigned short group_num;
279 unsigned short pool_num;
280 unsigned char mem_weight;
281 unsigned char unallocated_mem_weight;
282 unsigned long unallocated_entitlement; /* value in bytes */
283 unsigned long pool_size;
284 signed long loan_request;
285 unsigned long backing_mem;
286};
287
288int h_get_mpp(struct hvcall_mpp_data *);
273#endif /* __ASSEMBLY__ */ 289#endif /* __ASSEMBLY__ */
274#endif /* __KERNEL__ */ 290#endif /* __KERNEL__ */
275#endif /* _ASM_POWERPC_HVCALL_H */ 291#endif /* _ASM_POWERPC_HVCALL_H */