Skip to content

Commit eddaa9a

Browse files
ldu4mpe
authored andcommitted
powerpc/pseries: read the lpar name from the firmware
The LPAR name may be changed after the LPAR has been started in the HMC. In that case lparstat command is not reporting the updated value because it reads it from the device tree which is read at boot time. However this value could be read from RTAS. Adding this value in the /proc/powerpc/lparcfg output allows to read the updated value. However the hypervisor, like Qemu/KVM, may not support this RTAS parameter. In that case the value reported in lparcfg is read from the device tree and so is not updated accordingly. Signed-off-by: Laurent Dufour <[email protected]> Reviewed-by: Tyrel Datwyler <[email protected]> Reviewed-by: Nathan Lynch <[email protected]> [mpe: Drop doc-comment syntax, change RTAS/DT to lower case, use of_root to fix missing of_node_put(), use of_property_read_string()] Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent d5342fd commit eddaa9a

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

arch/powerpc/platforms/pseries/lparcfg.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,92 @@ static void parse_mpp_x_data(struct seq_file *m)
311311
seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
312312
}
313313

314+
/*
315+
* PAPR defines, in section "7.3.16 System Parameters Option", the token 55 to
316+
* read the LPAR name, and the largest output data to 4000 + 2 bytes length.
317+
*/
318+
#define SPLPAR_LPAR_NAME_TOKEN 55
319+
#define GET_SYS_PARM_BUF_SIZE 4002
320+
#if GET_SYS_PARM_BUF_SIZE > RTAS_DATA_BUF_SIZE
321+
#error "GET_SYS_PARM_BUF_SIZE is larger than RTAS_DATA_BUF_SIZE"
322+
#endif
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+
int rc, len, token;
336+
union {
337+
char raw_buffer[GET_SYS_PARM_BUF_SIZE];
338+
struct {
339+
__be16 len;
340+
char name[GET_SYS_PARM_BUF_SIZE-2];
341+
};
342+
} *local_buffer;
343+
344+
token = rtas_token("ibm,get-system-parameter");
345+
if (token == RTAS_UNKNOWN_SERVICE)
346+
return -EINVAL;
347+
348+
local_buffer = kmalloc(sizeof(*local_buffer), GFP_KERNEL);
349+
if (!local_buffer)
350+
return -ENOMEM;
351+
352+
do {
353+
spin_lock(&rtas_data_buf_lock);
354+
memset(rtas_data_buf, 0, sizeof(*local_buffer));
355+
rc = rtas_call(token, 3, 1, NULL, SPLPAR_LPAR_NAME_TOKEN,
356+
__pa(rtas_data_buf), sizeof(*local_buffer));
357+
if (!rc)
358+
memcpy(local_buffer->raw_buffer, rtas_data_buf,
359+
sizeof(local_buffer->raw_buffer));
360+
spin_unlock(&rtas_data_buf_lock);
361+
} while (rtas_busy_delay(rc));
362+
363+
if (!rc) {
364+
/* Force end of string */
365+
len = min((int) be16_to_cpu(local_buffer->len),
366+
(int) sizeof(local_buffer->name)-1);
367+
local_buffer->name[len] = '\0';
368+
369+
seq_printf(m, "partition_name=%s\n", local_buffer->name);
370+
} else
371+
rc = -ENODATA;
372+
373+
kfree(local_buffer);
374+
return rc;
375+
}
376+
377+
/*
378+
* Read the LPAR name from the Device Tree.
379+
*
380+
* The value read in the DT is not updated if the end-user is touching the LPAR
381+
* name on the hypervisor side.
382+
*/
383+
static int read_dt_lpar_name(struct seq_file *m)
384+
{
385+
const char *name;
386+
387+
if (of_property_read_string(of_root, "ibm,partition-name", &name))
388+
return -ENOENT;
389+
390+
seq_printf(m, "partition_name=%s\n", name);
391+
return 0;
392+
}
393+
394+
static void read_lpar_name(struct seq_file *m)
395+
{
396+
if (read_rtas_lpar_name(m) && read_dt_lpar_name(m))
397+
pr_err_once("Error can't get the LPAR name");
398+
}
399+
314400
#define SPLPAR_CHARACTERISTICS_TOKEN 20
315401
#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
316402

@@ -496,6 +582,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
496582

497583
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
498584
/* this call handles the ibm,get-system-parameter contents */
585+
read_lpar_name(m);
499586
parse_system_parameter_string(m);
500587
parse_ppp_data(m);
501588
parse_mpp_data(m);

0 commit comments

Comments
 (0)