Skip to content

Commit bddccb4

Browse files
author
Mamatha Inamdar
committed
powerpc/pseries: Add ibm,get-dynamic-sensor-state RTAS call support
JIRA: https://issues.redhat.com/browse/RHEL-101838 commit 496c752 Author: Haren Myneni <haren@linux.ibm.com> Date: Wed Apr 16 15:57:40 2025 -0700 powerpc/pseries: Add ibm,get-dynamic-sensor-state RTAS call support The RTAS call ibm,get-dynamic-sensor-state is used to get the sensor state identified by the location code and the sensor token. The librtas library provides an API rtas_get_dynamic_sensor() which uses /dev/mem access for work area allocation but is restricted under system lockdown. This patch provides an interface with new ioctl PAPR_DYNAMIC_SENSOR_IOC_GET to the papr-indices character driver which executes this HCALL and copies the sensor state in the user specified ioctl buffer. Refer PAPR 7.3.19 ibm,get-dynamic-sensor-state for more information on this RTAS call. - User input parameters to the RTAS call: location code string and the sensor token Expose these interfaces to user space with a /dev/papr-indices character device using the following programming model: int fd = open("/dev/papr-indices", O_RDWR); int ret = ioctl(fd, PAPR_DYNAMIC_SENSOR_IOC_GET, struct papr_indices_io_block) - The user space specifies input parameters in papr_indices_io_block struct - Returned state for the specified sensor is copied to papr_indices_io_block.dynamic_param.state Signed-off-by: Haren Myneni <haren@linux.ibm.com> Tested-by: Sathvika Vasireddy <sv@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20250416225743.596462-6-haren@linux.ibm.com Signed-off-by: Mamatha Inamdar <minamdar@redhat.com>
1 parent e536784 commit bddccb4

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

arch/powerpc/include/asm/rtas.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ extern unsigned long rtas_rmo_buf;
339339
extern struct mutex rtas_ibm_get_vpd_lock;
340340
extern struct mutex rtas_ibm_get_indices_lock;
341341
extern struct mutex rtas_ibm_set_dynamic_indicator_lock;
342+
extern struct mutex rtas_ibm_get_dynamic_sensor_state_lock;
342343

343344
#define GLOBAL_INTERRUPT_QUEUE 9005
344345

arch/powerpc/kernel/rtas.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ EXPORT_SYMBOL(rtas_flash_term_hook);
7979
DEFINE_MUTEX(rtas_ibm_get_vpd_lock);
8080
DEFINE_MUTEX(rtas_ibm_get_indices_lock);
8181
DEFINE_MUTEX(rtas_ibm_set_dynamic_indicator_lock);
82+
DEFINE_MUTEX(rtas_ibm_get_dynamic_sensor_state_lock);
8283

8384
/* RTAS use home made raw locking instead of spin_lock_irqsave
8485
* because those can be called from within really nasty contexts
@@ -1126,6 +1127,9 @@ static struct mutex *find_rtas_mutex(int token)
11261127
if (token == rtas_token("ibm,set-dynamic-indicator"))
11271128
return &rtas_ibm_set_dynamic_indicator_lock;
11281129

1130+
if (token == rtas_token("ibm,get-dynamic-sensor-state"))
1131+
return &rtas_ibm_get_dynamic_sensor_state_lock;
1132+
11291133
return NULL;
11301134
}
11311135

arch/powerpc/platforms/pseries/papr-indices.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,67 @@ static long papr_dynamic_indicator_ioc_set(struct papr_indices_io_block __user *
371371
return ret;
372372
}
373373

374+
/**
375+
* papr_dynamic_sensor_ioc_get - ibm,get-dynamic-sensor-state RTAS Call
376+
* PAPR 2.13 7.3.19
377+
*
378+
* @ubuf: Input parameters to RTAS call such as sensor token
379+
* Copies the state in user space buffer.
380+
*
381+
*
382+
* Returns success or -errno.
383+
*/
384+
385+
static long papr_dynamic_sensor_ioc_get(struct papr_indices_io_block __user *ubuf)
386+
{
387+
struct papr_indices_io_block kbuf;
388+
struct rtas_work_area *work_area;
389+
s32 fwrc, token, ret;
390+
u32 rets;
391+
392+
token = rtas_token("ibm,get-dynamic-sensor-state");
393+
if (token == RTAS_UNKNOWN_SERVICE)
394+
return -ENOENT;
395+
396+
mutex_lock(&rtas_ibm_get_dynamic_sensor_state_lock);
397+
work_area = papr_dynamic_indice_buf_from_user(ubuf, &kbuf);
398+
if (IS_ERR(work_area)) {
399+
ret = PTR_ERR(work_area);
400+
goto out;
401+
}
402+
403+
do {
404+
fwrc = rtas_call(token, 2, 2, &rets,
405+
kbuf.dynamic_param.token,
406+
rtas_work_area_phys(work_area));
407+
} while (rtas_busy_delay(fwrc));
408+
409+
rtas_work_area_free(work_area);
410+
411+
switch (fwrc) {
412+
case 0: /* Success */
413+
if (put_user(rets, &ubuf->dynamic_param.state))
414+
ret = -EFAULT;
415+
else
416+
ret = 0;
417+
break;
418+
case RTAS_IBM_DYNAMIC_INDICE_NO_INDICATOR: /* No such indicator */
419+
ret = -EOPNOTSUPP;
420+
break;
421+
default:
422+
pr_err("unexpected ibm,get-dynamic-sensor result %d\n",
423+
fwrc);
424+
fallthrough;
425+
case RTAS_HARDWARE_ERROR: /* Hardware/platform error */
426+
ret = -EIO;
427+
break;
428+
}
429+
430+
out:
431+
mutex_unlock(&rtas_ibm_get_dynamic_sensor_state_lock);
432+
return ret;
433+
}
434+
374435
/*
375436
* Top-level ioctl handler for /dev/papr-indices.
376437
*/
@@ -384,6 +445,9 @@ static long papr_indices_dev_ioctl(struct file *filp, unsigned int ioctl,
384445
case PAPR_INDICES_IOC_GET:
385446
ret = papr_indices_create_handle(argp);
386447
break;
448+
case PAPR_DYNAMIC_SENSOR_IOC_GET:
449+
ret = papr_dynamic_sensor_ioc_get(argp);
450+
break;
387451
case PAPR_DYNAMIC_INDICATOR_IOC_SET:
388452
if (filp->f_mode & FMODE_WRITE)
389453
ret = papr_dynamic_indicator_ioc_set(argp);
@@ -416,6 +480,9 @@ static __init int papr_indices_init(void)
416480
if (!rtas_service_present("ibm,set-dynamic-indicator"))
417481
return -ENODEV;
418482

483+
if (!rtas_service_present("ibm,get-dynamic-sensor-state"))
484+
return -ENODEV;
485+
419486
return misc_register(&papr_indices_dev);
420487
}
421488
machine_device_initcall(pseries, papr_indices_init);

0 commit comments

Comments
 (0)