hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/arch/powerpc/platforms/pseries/lparcfg.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * PowerPC64 LPAR Configuration Information Driver
34 *
....@@ -8,11 +9,6 @@
89 * seq_file updates, Copyright (c) 2004 Will Schmidt IBM Corporation.
910 * Nathan Lynch nathanl@austin.ibm.com
1011 * Added lparcfg_write, Copyright (C) 2004 Nathan Lynch IBM Corporation.
11
- *
12
- * This program is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU General Public License
14
- * as published by the Free Software Foundation; either version
15
- * 2 of the License, or (at your option) any later version.
1612 *
1713 * This driver creates a proc file at /proc/ppc64/lparcfg which contains
1814 * keyword - value pairs that specify the configuration of the partition.
....@@ -26,6 +22,7 @@
2622 #include <linux/seq_file.h>
2723 #include <linux/slab.h>
2824 #include <linux/uaccess.h>
25
+#include <linux/hugetlb.h>
2926 #include <asm/lppaca.h>
3027 #include <asm/hvcall.h>
3128 #include <asm/firmware.h>
....@@ -36,6 +33,7 @@
3633 #include <asm/vio.h>
3734 #include <asm/mmu.h>
3835 #include <asm/machdep.h>
36
+#include <asm/drmem.h>
3937
4038 #include "pseries.h"
4139
....@@ -138,6 +136,39 @@
138136 return rc;
139137 }
140138
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
+
141172 static unsigned h_pic(unsigned long *pool_idle_time,
142173 unsigned long *num_procs)
143174 {
....@@ -174,7 +205,7 @@
174205 ppp_data.active_system_procs);
175206
176207 /* pool related entries are appropriate for shared configs */
177
- if (lppaca_shared_proc(get_lppaca())) {
208
+ if (lppaca_shared_proc()) {
178209 unsigned long pool_idle_time, pool_procs;
179210
180211 seq_printf(m, "pool=%d\n", ppp_data.pool_num);
....@@ -291,6 +322,7 @@
291322 */
292323 static void parse_system_parameter_string(struct seq_file *m)
293324 {
325
+ const s32 token = rtas_token("ibm,get-system-parameter");
294326 int call_status;
295327
296328 unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
....@@ -300,16 +332,15 @@
300332 return;
301333 }
302334
303
- spin_lock(&rtas_data_buf_lock);
304
- memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
305
- call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
306
- NULL,
307
- SPLPAR_CHARACTERISTICS_TOKEN,
308
- __pa(rtas_data_buf),
309
- RTAS_DATA_BUF_SIZE);
310
- memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
311
- local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
312
- spin_unlock(&rtas_data_buf_lock);
335
+ do {
336
+ spin_lock(&rtas_data_buf_lock);
337
+ memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
338
+ call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN,
339
+ __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE);
340
+ memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
341
+ local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
342
+ spin_unlock(&rtas_data_buf_lock);
343
+ } while (rtas_busy_delay(call_status));
313344
314345 if (call_status != 0) {
315346 printk(KERN_INFO
....@@ -433,6 +464,16 @@
433464 seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
434465 }
435466
467
+static void maxmem_data(struct seq_file *m)
468
+{
469
+ unsigned long maxmem = 0;
470
+
471
+ maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size;
472
+ maxmem += hugetlb_total_pages() * PAGE_SIZE;
473
+
474
+ seq_printf(m, "MaxMem=%lu\n", maxmem);
475
+}
476
+
436477 static int pseries_lparcfg_data(struct seq_file *m, void *v)
437478 {
438479 int partition_potential_processors;
....@@ -463,6 +504,7 @@
463504 splpar_dispatch_data(m);
464505
465506 seq_printf(m, "purr=%ld\n", get_purr());
507
+ seq_printf(m, "tbr=%ld\n", mftb());
466508 } else { /* non SPLPAR case */
467509
468510 seq_printf(m, "system_active_processors=%d\n",
....@@ -478,6 +520,8 @@
478520 partition_active_processors * 100);
479521 }
480522
523
+ show_gpci_data(m);
524
+
481525 seq_printf(m, "partition_active_processors=%d\n",
482526 partition_active_processors);
483527
....@@ -485,12 +529,13 @@
485529 partition_potential_processors);
486530
487531 seq_printf(m, "shared_processor_mode=%d\n",
488
- lppaca_shared_proc(get_lppaca()));
532
+ lppaca_shared_proc());
489533
490534 #ifdef CONFIG_PPC_BOOK3S_64
491535 seq_printf(m, "slb_size=%d\n", mmu_slb_size);
492536 #endif
493537 parse_em_data(m);
538
+ maxmem_data(m);
494539
495540 return 0;
496541 }
....@@ -585,8 +630,7 @@
585630 static ssize_t lparcfg_write(struct file *file, const char __user * buf,
586631 size_t count, loff_t * off)
587632 {
588
- int kbuf_sz = 64;
589
- char kbuf[kbuf_sz];
633
+ char kbuf[64];
590634 char *tmp;
591635 u64 new_entitled, *new_entitled_ptr = &new_entitled;
592636 u8 new_weight, *new_weight_ptr = &new_weight;
....@@ -595,7 +639,7 @@
595639 if (!firmware_has_feature(FW_FEATURE_SPLPAR))
596640 return -EINVAL;
597641
598
- if (count > kbuf_sz)
642
+ if (count > sizeof(kbuf))
599643 return -EINVAL;
600644
601645 if (copy_from_user(kbuf, buf, count))
....@@ -689,12 +733,12 @@
689733 return single_open(file, lparcfg_data, NULL);
690734 }
691735
692
-static const struct file_operations lparcfg_fops = {
693
- .read = seq_read,
694
- .write = lparcfg_write,
695
- .open = lparcfg_open,
696
- .release = single_release,
697
- .llseek = seq_lseek,
736
+static const struct proc_ops lparcfg_proc_ops = {
737
+ .proc_read = seq_read,
738
+ .proc_write = lparcfg_write,
739
+ .proc_open = lparcfg_open,
740
+ .proc_release = single_release,
741
+ .proc_lseek = seq_lseek,
698742 };
699743
700744 static int __init lparcfg_init(void)
....@@ -705,7 +749,7 @@
705749 if (firmware_has_feature(FW_FEATURE_SPLPAR))
706750 mode |= 0200;
707751
708
- if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) {
752
+ if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_proc_ops)) {
709753 printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
710754 return -EIO;
711755 }