summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaren Myneni <haren@linux.ibm.com>2025-04-16 15:57:40 -0700
committerMadhavan Srinivasan <maddy@linux.ibm.com>2025-04-17 11:42:29 +0530
commit496c7524dcec16d3993382db35b960f8c3955083 (patch)
treeb31963672ec10a8172a28ac57f33cdac4130a4ed
parentf60a3796f84f96d21de1a4fa2b9fd0637378f026 (diff)
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
-rw-r--r--arch/powerpc/include/asm/rtas.h1
-rw-r--r--arch/powerpc/kernel/rtas.c2
-rw-r--r--arch/powerpc/platforms/pseries/papr-indices.c67
3 files changed, 69 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 2da52f59e4c6..fcd822f0e1d7 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -517,6 +517,7 @@ extern unsigned long rtas_rmo_buf;
extern struct mutex rtas_ibm_get_vpd_lock;
extern struct mutex rtas_ibm_get_indices_lock;
extern struct mutex rtas_ibm_set_dynamic_indicator_lock;
+extern struct mutex rtas_ibm_get_dynamic_sensor_state_lock;
#define GLOBAL_INTERRUPT_QUEUE 9005
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index e497b3b95ef2..2aab71481da3 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -92,12 +92,12 @@ struct rtas_function {
* Per-function locks for sequence-based RTAS functions.
*/
static DEFINE_MUTEX(rtas_ibm_activate_firmware_lock);
-static DEFINE_MUTEX(rtas_ibm_get_dynamic_sensor_state_lock);
static DEFINE_MUTEX(rtas_ibm_lpar_perftools_lock);
static DEFINE_MUTEX(rtas_ibm_physical_attestation_lock);
DEFINE_MUTEX(rtas_ibm_get_vpd_lock);
DEFINE_MUTEX(rtas_ibm_get_indices_lock);
DEFINE_MUTEX(rtas_ibm_set_dynamic_indicator_lock);
+DEFINE_MUTEX(rtas_ibm_get_dynamic_sensor_state_lock);
static struct rtas_function rtas_function_table[] __ro_after_init = {
[RTAS_FNIDX__CHECK_EXCEPTION] = {
diff --git a/arch/powerpc/platforms/pseries/papr-indices.c b/arch/powerpc/platforms/pseries/papr-indices.c
index c46b728d5f47..3c7545591c45 100644
--- a/arch/powerpc/platforms/pseries/papr-indices.c
+++ b/arch/powerpc/platforms/pseries/papr-indices.c
@@ -371,6 +371,67 @@ out:
return ret;
}
+/**
+ * papr_dynamic_sensor_ioc_get - ibm,get-dynamic-sensor-state RTAS Call
+ * PAPR 2.13 7.3.19
+ *
+ * @ubuf: Input parameters to RTAS call such as sensor token
+ * Copies the state in user space buffer.
+ *
+ *
+ * Returns success or -errno.
+ */
+
+static long papr_dynamic_sensor_ioc_get(struct papr_indices_io_block __user *ubuf)
+{
+ struct papr_indices_io_block kbuf;
+ struct rtas_work_area *work_area;
+ s32 fwrc, token, ret;
+ u32 rets;
+
+ token = rtas_function_token(RTAS_FN_IBM_GET_DYNAMIC_SENSOR_STATE);
+ if (token == RTAS_UNKNOWN_SERVICE)
+ return -ENOENT;
+
+ mutex_lock(&rtas_ibm_get_dynamic_sensor_state_lock);
+ work_area = papr_dynamic_indice_buf_from_user(ubuf, &kbuf);
+ if (IS_ERR(work_area)) {
+ ret = PTR_ERR(work_area);
+ goto out;
+ }
+
+ do {
+ fwrc = rtas_call(token, 2, 2, &rets,
+ kbuf.dynamic_param.token,
+ rtas_work_area_phys(work_area));
+ } while (rtas_busy_delay(fwrc));
+
+ rtas_work_area_free(work_area);
+
+ switch (fwrc) {
+ case RTAS_SUCCESS:
+ if (put_user(rets, &ubuf->dynamic_param.state))
+ ret = -EFAULT;
+ else
+ ret = 0;
+ break;
+ case RTAS_IBM_DYNAMIC_INDICE_NO_INDICATOR: /* No such indicator */
+ ret = -EOPNOTSUPP;
+ break;
+ default:
+ pr_err("unexpected ibm,get-dynamic-sensor result %d\n",
+ fwrc);
+ fallthrough;
+ case RTAS_HARDWARE_ERROR: /* Hardware/platform error */
+ ret = -EIO;
+ break;
+ }
+
+out:
+ mutex_unlock(&rtas_ibm_get_dynamic_sensor_state_lock);
+ return ret;
+}
+
/*
* Top-level ioctl handler for /dev/papr-indices.
*/
@@ -384,6 +445,9 @@ static long papr_indices_dev_ioctl(struct file *filp, unsigned int ioctl,
case PAPR_INDICES_IOC_GET:
ret = papr_indices_create_handle(argp);
break;
+ case PAPR_DYNAMIC_SENSOR_IOC_GET:
+ ret = papr_dynamic_sensor_ioc_get(argp);
+ break;
case PAPR_DYNAMIC_INDICATOR_IOC_SET:
if (filp->f_mode & FMODE_WRITE)
ret = papr_dynamic_indicator_ioc_set(argp);
@@ -416,6 +480,9 @@ static __init int papr_indices_init(void)
if (!rtas_function_implemented(RTAS_FN_IBM_SET_DYNAMIC_INDICATOR))
return -ENODEV;
+ if (!rtas_function_implemented(RTAS_FN_IBM_GET_DYNAMIC_SENSOR_STATE))
+ return -ENODEV;
+
return misc_register(&papr_indices_dev);
}
machine_device_initcall(pseries, papr_indices_init);