Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/pseries/lparcfg: convert to papr_sysparm API

/proc/powerpc/lparcfg derives the LPAR name and SPLPAR characteristics
it reports using bare calls to the RTAS ibm,get-system-parameter
function. Convert these to the higher-level papr_sysparm API, which
handles the tedious details.

While the SPLPAR string parsing code could stand to be updated, that
should be done in a separate change. It is minimally modified here to
reduce the risk of changing behavior.

Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-16-26929c8cce78@linux.ibm.com

authored by

Nathan Lynch and committed by
Michael Ellerman
fff9846b b8dc7177

+24 -80
+24 -80
arch/powerpc/platforms/pseries/lparcfg.c
··· 19 19 #include <linux/errno.h> 20 20 #include <linux/proc_fs.h> 21 21 #include <linux/init.h> 22 + #include <asm/papr-sysparm.h> 22 23 #include <linux/seq_file.h> 23 24 #include <linux/slab.h> 24 25 #include <linux/uaccess.h> ··· 313 312 } 314 313 315 314 /* 316 - * PAPR defines, in section "7.3.16 System Parameters Option", the token 55 to 317 - * read the LPAR name, and the largest output data to 4000 + 2 bytes length. 318 - */ 319 - #define SPLPAR_LPAR_NAME_TOKEN 55 320 - #define GET_SYS_PARM_BUF_SIZE 4002 321 - #if GET_SYS_PARM_BUF_SIZE > RTAS_DATA_BUF_SIZE 322 - #error "GET_SYS_PARM_BUF_SIZE is larger than RTAS_DATA_BUF_SIZE" 323 - #endif 324 - 325 - /* 326 315 * Read the lpar name using the RTAS ibm,get-system-parameter call. 327 316 * 328 317 * The name read through this call is updated if changes are made by the end ··· 323 332 */ 324 333 static int read_rtas_lpar_name(struct seq_file *m) 325 334 { 326 - int rc, len, token; 327 - union { 328 - char raw_buffer[GET_SYS_PARM_BUF_SIZE]; 329 - struct { 330 - __be16 len; 331 - char name[GET_SYS_PARM_BUF_SIZE-2]; 332 - }; 333 - } *local_buffer; 335 + struct papr_sysparm_buf *buf; 336 + int err; 334 337 335 - token = rtas_token("ibm,get-system-parameter"); 336 - if (token == RTAS_UNKNOWN_SERVICE) 337 - return -EINVAL; 338 - 339 - local_buffer = kmalloc(sizeof(*local_buffer), GFP_KERNEL); 340 - if (!local_buffer) 338 + buf = papr_sysparm_buf_alloc(); 339 + if (!buf) 341 340 return -ENOMEM; 342 341 343 - do { 344 - spin_lock(&rtas_data_buf_lock); 345 - memset(rtas_data_buf, 0, sizeof(*local_buffer)); 346 - rc = rtas_call(token, 3, 1, NULL, SPLPAR_LPAR_NAME_TOKEN, 347 - __pa(rtas_data_buf), sizeof(*local_buffer)); 348 - if (!rc) 349 - memcpy(local_buffer->raw_buffer, rtas_data_buf, 350 - sizeof(local_buffer->raw_buffer)); 351 - spin_unlock(&rtas_data_buf_lock); 352 - } while (rtas_busy_delay(rc)); 342 + err = papr_sysparm_get(PAPR_SYSPARM_LPAR_NAME, buf); 343 + if (!err) 344 + seq_printf(m, "partition_name=%s\n", buf->val); 353 345 354 - if (!rc) { 355 - /* Force end of string */ 356 - len = min((int) be16_to_cpu(local_buffer->len), 357 - (int) sizeof(local_buffer->name)-1); 358 - local_buffer->name[len] = '\0'; 359 - 360 - seq_printf(m, "partition_name=%s\n", local_buffer->name); 361 - } else 362 - rc = -ENODATA; 363 - 364 - kfree(local_buffer); 365 - return rc; 346 + papr_sysparm_buf_free(buf); 347 + return err; 366 348 } 367 349 368 350 /* ··· 361 397 pr_err_once("Error can't get the LPAR name"); 362 398 } 363 399 364 - #define SPLPAR_CHARACTERISTICS_TOKEN 20 365 400 #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) 366 401 367 402 /* ··· 371 408 */ 372 409 static void parse_system_parameter_string(struct seq_file *m) 373 410 { 374 - const s32 token = rtas_token("ibm,get-system-parameter"); 375 - int call_status; 411 + struct papr_sysparm_buf *buf; 376 412 377 - unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); 378 - if (!local_buffer) { 379 - printk(KERN_ERR "%s %s kmalloc failure at line %d\n", 380 - __FILE__, __func__, __LINE__); 413 + buf = papr_sysparm_buf_alloc(); 414 + if (!buf) 381 415 return; 382 - } 383 416 384 - do { 385 - spin_lock(&rtas_data_buf_lock); 386 - memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); 387 - call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN, 388 - __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); 389 - memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); 390 - local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; 391 - spin_unlock(&rtas_data_buf_lock); 392 - } while (rtas_busy_delay(call_status)); 393 - 394 - if (call_status != 0) { 395 - printk(KERN_INFO 396 - "%s %s Error calling get-system-parameter (0x%x)\n", 397 - __FILE__, __func__, call_status); 417 + if (papr_sysparm_get(PAPR_SYSPARM_SHARED_PROC_LPAR_ATTRS, buf)) { 418 + goto out_free; 398 419 } else { 420 + const char *local_buffer; 399 421 int splpar_strlen; 400 422 int idx, w_idx; 401 423 char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); 402 - if (!workbuffer) { 403 - printk(KERN_ERR "%s %s kmalloc failure at line %d\n", 404 - __FILE__, __func__, __LINE__); 405 - kfree(local_buffer); 406 - return; 407 - } 408 - #ifdef LPARCFG_DEBUG 409 - printk(KERN_INFO "success calling get-system-parameter\n"); 410 - #endif 411 - splpar_strlen = local_buffer[0] * 256 + local_buffer[1]; 412 - local_buffer += 2; /* step over strlen value */ 424 + 425 + if (!workbuffer) 426 + goto out_free; 427 + 428 + splpar_strlen = be16_to_cpu(buf->len); 429 + local_buffer = buf->val; 413 430 414 431 w_idx = 0; 415 432 idx = 0; ··· 423 480 kfree(workbuffer); 424 481 local_buffer -= 2; /* back up over strlen value */ 425 482 } 426 - kfree(local_buffer); 483 + out_free: 484 + papr_sysparm_buf_free(buf); 427 485 } 428 486 429 487 /* Return the number of processors in the system.