Accepting request 1136886 from home:michals
- Add support for new rtas kernel interface for VPD and sysparm (jsc#PED-4541). * 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch * 0002-librtas-move-VPD-code-into-separate-module.patch * 0003-librtas-move-system-parameter-code-to-separate-modul.patch * 0004-librtas-vendor-papr-miscdev.h.patch * 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch * 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch * link-lpthread.patch * tests: activate-firmware-regress vpdupdate-regress OBS-URL: https://build.opensuse.org/request/show/1136886 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/librtas?expand=0&rev=67
This commit is contained in:
parent
1d05bfa7fe
commit
6320ffa20b
@ -0,0 +1,79 @@
|
|||||||
|
From 0d48bdca32cbf7a83bcaa5a27e3454d24055e0cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Sat, 12 Aug 2023 12:41:36 -0500
|
||||||
|
Subject: [PATCH 1/6] librtas: expose low-level RTAS call APIs internally
|
||||||
|
|
||||||
|
Make these functions available outside of syscall_calls.c, marking
|
||||||
|
them hidden so that they aren't exposed in the library ABI.
|
||||||
|
|
||||||
|
The implementations of librtas APIs will move into separate C files as
|
||||||
|
they gain support for new interfaces offered by the kernel.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
librtas_src/internal.h | 5 +++++
|
||||||
|
librtas_src/syscall_calls.c | 11 ++++++-----
|
||||||
|
2 files changed, 11 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/librtas_src/internal.h b/librtas_src/internal.h
|
||||||
|
index 3b6ba88..97411d3 100644
|
||||||
|
--- a/librtas_src/internal.h
|
||||||
|
+++ b/librtas_src/internal.h
|
||||||
|
@@ -52,6 +52,11 @@ int read_entire_file(int fd, char **buf, size_t *len);
|
||||||
|
int rtas_token(const char *call_name);
|
||||||
|
int sanity_check(void);
|
||||||
|
|
||||||
|
+#define CALL_AGAIN 1
|
||||||
|
+unsigned int handle_delay(int status, uint64_t * elapsed);
|
||||||
|
+int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...);
|
||||||
|
+int rtas_call(const char *name, int ninputs, int nrets, ...);
|
||||||
|
+
|
||||||
|
#define BITS32_LO(_num) (uint32_t) (_num & 0xffffffffll)
|
||||||
|
#define BITS32_HI(_num) (uint32_t) (_num >> 32)
|
||||||
|
#define BITS64(_high, _low) (uint64_t) (((uint64_t) _high << 32) | _low)
|
||||||
|
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||||
|
index 1e09217..eabc5ea 100644
|
||||||
|
--- a/librtas_src/syscall_calls.c
|
||||||
|
+++ b/librtas_src/syscall_calls.c
|
||||||
|
@@ -32,8 +32,6 @@
|
||||||
|
#include "internal.h"
|
||||||
|
#include "librtas.h"
|
||||||
|
|
||||||
|
-#define CALL_AGAIN 1
|
||||||
|
-
|
||||||
|
int dbg_lvl = 0;
|
||||||
|
static uint64_t rtas_timeout_ms;
|
||||||
|
|
||||||
|
@@ -65,7 +63,8 @@ int sanity_check(void)
|
||||||
|
* CALL_AGAIN if the status is delay related
|
||||||
|
* RTAS_TIMEOUT if the requested timeout has been exceeded
|
||||||
|
*/
|
||||||
|
-static unsigned int handle_delay(int status, uint64_t * elapsed)
|
||||||
|
+__attribute__((visibility("hidden")))
|
||||||
|
+unsigned int handle_delay(int status, uint64_t * elapsed)
|
||||||
|
{
|
||||||
|
int order = status - EXTENDED_DELAY_MIN;
|
||||||
|
unsigned long ms = 0;
|
||||||
|
@@ -213,7 +212,8 @@ static int _rtas_call(int delay_handling, int token, int ninputs,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||||
|
+__attribute__((visibility("hidden")))
|
||||||
|
+int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int rc, token;
|
||||||
|
@@ -229,7 +229,8 @@ static int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int rtas_call(const char *name, int ninputs, int nrets, ...)
|
||||||
|
+__attribute__((visibility("hidden")))
|
||||||
|
+int rtas_call(const char *name, int ninputs, int nrets, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int rc, token;
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
197
0002-librtas-move-VPD-code-into-separate-module.patch
Normal file
197
0002-librtas-move-VPD-code-into-separate-module.patch
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
From 12a2764fd7efe7c52b53579a67edb641d662f54f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Sat, 12 Aug 2023 12:44:38 -0500
|
||||||
|
Subject: [PATCH 2/6] librtas: move VPD code into separate module
|
||||||
|
|
||||||
|
This code will gain the ability to retrieve VPD using a different
|
||||||
|
interface exposed by newer kernels. This will be a lot of additional
|
||||||
|
code, so move it out of syscall_calls.c.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 1 +
|
||||||
|
librtas_src/syscall_calls.c | 67 ------------------------------
|
||||||
|
librtas_src/vpd.c | 81 +++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 82 insertions(+), 67 deletions(-)
|
||||||
|
create mode 100644 librtas_src/vpd.c
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index c4bf09d..37df243 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -28,6 +28,7 @@ LIBRTAS_LIBRARY_VERSION = $(LIBRTAS_CURRENT):$(LIBRTAS_REVISION):$(LIBRTAS_AGE)
|
||||||
|
lib_LTLIBRARIES += librtas.la
|
||||||
|
librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION)
|
||||||
|
librtas_la_SOURCES = \
|
||||||
|
+ librtas_src/vpd.c \
|
||||||
|
librtas_src/ofdt.c \
|
||||||
|
librtas_src/syscall_calls.c \
|
||||||
|
librtas_src/syscall_rmo.c
|
||||||
|
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||||
|
index eabc5ea..05f3c7c 100644
|
||||||
|
--- a/librtas_src/syscall_calls.c
|
||||||
|
+++ b/librtas_src/syscall_calls.c
|
||||||
|
@@ -753,73 +753,6 @@ int rtas_get_time(uint32_t *year, uint32_t *month, uint32_t *day,
|
||||||
|
return rc ? rc : status;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * rtas_get_vpd
|
||||||
|
- * @brief Interface to the ibm,get-vpd rtas call
|
||||||
|
- *
|
||||||
|
- * @param loc_code location code
|
||||||
|
- * @param workarea additional args to rtas call
|
||||||
|
- * @param size
|
||||||
|
- * @param sequence
|
||||||
|
- * @param seq_next
|
||||||
|
- * @param bytes_ret
|
||||||
|
- * @return 0 on success, !0 otherwise
|
||||||
|
- */
|
||||||
|
-int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||||
|
- unsigned int sequence, unsigned int *seq_next,
|
||||||
|
- unsigned int *bytes_ret)
|
||||||
|
-{
|
||||||
|
- uint32_t kernbuf_pa;
|
||||||
|
- uint32_t loc_pa = 0;
|
||||||
|
- uint32_t rmo_pa = 0;
|
||||||
|
- uint64_t elapsed = 0;
|
||||||
|
- void *kernbuf;
|
||||||
|
- void *rmobuf;
|
||||||
|
- void *locbuf;
|
||||||
|
- int rc, status;
|
||||||
|
-
|
||||||
|
- rc = sanity_check();
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
- rc = rtas_get_rmo_buffer(size + WORK_AREA_SIZE, &rmobuf, &rmo_pa);
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
- kernbuf = rmobuf + WORK_AREA_SIZE;
|
||||||
|
- kernbuf_pa = rmo_pa + WORK_AREA_SIZE;
|
||||||
|
- locbuf = rmobuf;
|
||||||
|
- loc_pa = rmo_pa;
|
||||||
|
-
|
||||||
|
- /* If user didn't set loc_code, copy a NULL string */
|
||||||
|
- strncpy(locbuf, loc_code ? loc_code : "", WORK_AREA_SIZE);
|
||||||
|
-
|
||||||
|
- *seq_next = htobe32(sequence);
|
||||||
|
- do {
|
||||||
|
- sequence = *seq_next;
|
||||||
|
- rc = rtas_call_no_delay("ibm,get-vpd", 4, 3, htobe32(loc_pa),
|
||||||
|
- htobe32(kernbuf_pa), htobe32(size),
|
||||||
|
- sequence, &status, seq_next,
|
||||||
|
- bytes_ret);
|
||||||
|
- if (rc < 0)
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- rc = handle_delay(status, &elapsed);
|
||||||
|
- } while (rc == CALL_AGAIN);
|
||||||
|
-
|
||||||
|
- if (rc == 0)
|
||||||
|
- memcpy(workarea, kernbuf, size);
|
||||||
|
-
|
||||||
|
- (void) rtas_free_rmo_buffer(rmobuf, rmo_pa, size + WORK_AREA_SIZE);
|
||||||
|
-
|
||||||
|
- *seq_next = be32toh(*seq_next);
|
||||||
|
- *bytes_ret = be32toh(*bytes_ret);
|
||||||
|
-
|
||||||
|
- dbg("(%s, 0x%p, %zu, %u) = %d, %u, %u\n", loc_code ? loc_code : "NULL",
|
||||||
|
- workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||||
|
- return rc ? rc : status;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* rtas_lpar_perftools
|
||||||
|
* @brief Interface to the ibm,lpar-perftools rtas call
|
||||||
|
diff --git a/librtas_src/vpd.c b/librtas_src/vpd.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..b2689fb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librtas_src/vpd.c
|
||||||
|
@@ -0,0 +1,81 @@
|
||||||
|
+// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
+
|
||||||
|
+// Support for accessing IBM Power systems Vital Product Data (VPD)
|
||||||
|
+// via the rtas() syscall.
|
||||||
|
+
|
||||||
|
+#include <endian.h>
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+#include <linux/unistd.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/syscall.h>
|
||||||
|
+
|
||||||
|
+#include "internal.h"
|
||||||
|
+#include "librtas.h"
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * rtas_get_vpd
|
||||||
|
+ * @brief Interface to the ibm,get-vpd rtas call
|
||||||
|
+ *
|
||||||
|
+ * @param loc_code location code
|
||||||
|
+ * @param workarea additional args to rtas call
|
||||||
|
+ * @param size
|
||||||
|
+ * @param sequence
|
||||||
|
+ * @param seq_next
|
||||||
|
+ * @param bytes_ret
|
||||||
|
+ * @return 0 on success, !0 otherwise
|
||||||
|
+ */
|
||||||
|
+int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||||
|
+ unsigned int sequence, unsigned int *seq_next,
|
||||||
|
+ unsigned int *bytes_ret)
|
||||||
|
+{
|
||||||
|
+ uint32_t kernbuf_pa;
|
||||||
|
+ uint32_t loc_pa = 0;
|
||||||
|
+ uint32_t rmo_pa = 0;
|
||||||
|
+ uint64_t elapsed = 0;
|
||||||
|
+ void *kernbuf;
|
||||||
|
+ void *rmobuf;
|
||||||
|
+ void *locbuf;
|
||||||
|
+ int rc, status;
|
||||||
|
+
|
||||||
|
+ rc = sanity_check();
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ rc = rtas_get_rmo_buffer(size + WORK_AREA_SIZE, &rmobuf, &rmo_pa);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ kernbuf = rmobuf + WORK_AREA_SIZE;
|
||||||
|
+ kernbuf_pa = rmo_pa + WORK_AREA_SIZE;
|
||||||
|
+ locbuf = rmobuf;
|
||||||
|
+ loc_pa = rmo_pa;
|
||||||
|
+
|
||||||
|
+ /* If user didn't set loc_code, copy a NULL string */
|
||||||
|
+ strncpy(locbuf, loc_code ? loc_code : "", WORK_AREA_SIZE);
|
||||||
|
+
|
||||||
|
+ *seq_next = htobe32(sequence);
|
||||||
|
+ do {
|
||||||
|
+ sequence = *seq_next;
|
||||||
|
+ rc = rtas_call_no_delay("ibm,get-vpd", 4, 3, htobe32(loc_pa),
|
||||||
|
+ htobe32(kernbuf_pa), htobe32(size),
|
||||||
|
+ sequence, &status, seq_next,
|
||||||
|
+ bytes_ret);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ rc = handle_delay(status, &elapsed);
|
||||||
|
+ } while (rc == CALL_AGAIN);
|
||||||
|
+
|
||||||
|
+ if (rc == 0)
|
||||||
|
+ memcpy(workarea, kernbuf, size);
|
||||||
|
+
|
||||||
|
+ (void) rtas_free_rmo_buffer(rmobuf, rmo_pa, size + WORK_AREA_SIZE);
|
||||||
|
+
|
||||||
|
+ *seq_next = be32toh(*seq_next);
|
||||||
|
+ *bytes_ret = be32toh(*bytes_ret);
|
||||||
|
+
|
||||||
|
+ dbg("(%s, 0x%p, %zu, %u) = %d, %u, %u\n", loc_code ? loc_code : "NULL",
|
||||||
|
+ workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||||
|
+ return rc ? rc : status;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
230
0003-librtas-move-system-parameter-code-to-separate-modul.patch
Normal file
230
0003-librtas-move-system-parameter-code-to-separate-modul.patch
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
From 80dfb541257cb88519855543324478cbb0f1f1b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Mon, 25 Sep 2023 11:32:33 -0500
|
||||||
|
Subject: [PATCH 3/6] librtas: move system parameter code to separate module
|
||||||
|
|
||||||
|
This code will gain the ability to access system parameters using a
|
||||||
|
different interface exposed by newer kernels. This will involve adding
|
||||||
|
a nontrivial amount of code, so move it out of syscall_calls.c.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 3 +-
|
||||||
|
librtas_src/syscall_calls.c | 84 -----------------------------------
|
||||||
|
librtas_src/sysparm.c | 88 +++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 90 insertions(+), 85 deletions(-)
|
||||||
|
create mode 100644 librtas_src/sysparm.c
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 37df243..1385ac7 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -31,7 +31,8 @@ librtas_la_SOURCES = \
|
||||||
|
librtas_src/vpd.c \
|
||||||
|
librtas_src/ofdt.c \
|
||||||
|
librtas_src/syscall_calls.c \
|
||||||
|
- librtas_src/syscall_rmo.c
|
||||||
|
+ librtas_src/syscall_rmo.c \
|
||||||
|
+ librtas_src/sysparm.c
|
||||||
|
|
||||||
|
library_include_HEADERS += librtas_src/librtas.h
|
||||||
|
noinst_HEADERS += librtas_src/internal.h
|
||||||
|
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||||
|
index 05f3c7c..b28af2d 100644
|
||||||
|
--- a/librtas_src/syscall_calls.c
|
||||||
|
+++ b/librtas_src/syscall_calls.c
|
||||||
|
@@ -674,44 +674,6 @@ int rtas_get_sensor(int sensor, int index, int *state)
|
||||||
|
return rc ? rc : status;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * rtas_get_sysparm
|
||||||
|
- * @brief Interface to the ibm,get-system-parameter rtas call
|
||||||
|
- *
|
||||||
|
- * On successful completion the data parameter will contain the system
|
||||||
|
- * parameter results
|
||||||
|
- *
|
||||||
|
- * @param parameter system parameter to retrieve
|
||||||
|
- * @param length data buffer length
|
||||||
|
- * @param data reference to buffer to return parameter in
|
||||||
|
- * @return 0 on success, !0 otherwise
|
||||||
|
- */
|
||||||
|
-int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
-{
|
||||||
|
- uint32_t kernbuf_pa;
|
||||||
|
- void *kernbuf;
|
||||||
|
- int rc, status;
|
||||||
|
-
|
||||||
|
- rc = sanity_check();
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
- rc = rtas_get_rmo_buffer(length, &kernbuf, &kernbuf_pa);
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
- rc = rtas_call("ibm,get-system-parameter", 3, 1, htobe32(parameter),
|
||||||
|
- htobe32(kernbuf_pa), htobe32(length), &status);
|
||||||
|
-
|
||||||
|
- if (rc == 0)
|
||||||
|
- memcpy(data, kernbuf, length);
|
||||||
|
-
|
||||||
|
- (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, length);
|
||||||
|
-
|
||||||
|
- dbg("(%u, %u, %p) = %d\n", parameter, length, data, rc ? rc : status);
|
||||||
|
- return rc ? rc : status;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* rtas_get_time
|
||||||
|
* @brief Interface to get-time-of-day rtas call
|
||||||
|
@@ -1109,52 +1071,6 @@ int rtas_set_poweron_time(uint32_t year, uint32_t month, uint32_t day,
|
||||||
|
return rc ? rc : status;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * rtas_set_sysparm
|
||||||
|
- * @brief Interface to the ibm,set-system-parameter rtas call
|
||||||
|
- *
|
||||||
|
- * @param parameter
|
||||||
|
- * @param data
|
||||||
|
- * @return 0 on success, !0 otherwise
|
||||||
|
- */
|
||||||
|
-int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||||
|
-{
|
||||||
|
- uint32_t kernbuf_pa;
|
||||||
|
- void *kernbuf;
|
||||||
|
- int rc, status;
|
||||||
|
- uint16_t size;
|
||||||
|
-
|
||||||
|
- rc = sanity_check();
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
- /*
|
||||||
|
- * We have to copy the contents of @data to a RMO buffer. The
|
||||||
|
- * caller has encoded the data length in the first two bytes
|
||||||
|
- * of @data in MSB order, and we can't assume any
|
||||||
|
- * alignment. So interpret @data as:
|
||||||
|
- *
|
||||||
|
- * struct {
|
||||||
|
- * unsigned char len_msb;
|
||||||
|
- * unsigned char len_lsb;
|
||||||
|
- * char [(len_msb << 8) + len_lsb];
|
||||||
|
- * }
|
||||||
|
- */
|
||||||
|
- size = 2 + (((unsigned char)data[0] << 8) | (unsigned char)data[1]);
|
||||||
|
- rc = rtas_get_rmo_buffer(size, &kernbuf, &kernbuf_pa);
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
- memcpy(kernbuf, data, size);
|
||||||
|
-
|
||||||
|
- rc = rtas_call("ibm,set-system-parameter", 2, 1, htobe32(parameter),
|
||||||
|
- htobe32(kernbuf_pa), &status);
|
||||||
|
-
|
||||||
|
- (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, size);
|
||||||
|
-
|
||||||
|
- dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||||
|
- return rc ? rc : status;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* rtas_set_time
|
||||||
|
* @brief Interface to the set-time-of-day rtas call
|
||||||
|
diff --git a/librtas_src/sysparm.c b/librtas_src/sysparm.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..40af55e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librtas_src/sysparm.c
|
||||||
|
@@ -0,0 +1,88 @@
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include "internal.h"
|
||||||
|
+#include "librtas.h"
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * rtas_get_sysparm
|
||||||
|
+ * @brief Interface to the ibm,get-system-parameter rtas call
|
||||||
|
+ *
|
||||||
|
+ * On successful completion the data parameter will contain the system
|
||||||
|
+ * parameter results
|
||||||
|
+ *
|
||||||
|
+ * @param parameter system parameter to retrieve
|
||||||
|
+ * @param length data buffer length
|
||||||
|
+ * @param data reference to buffer to return parameter in
|
||||||
|
+ * @return 0 on success, !0 otherwise
|
||||||
|
+ */
|
||||||
|
+int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
+{
|
||||||
|
+ uint32_t kernbuf_pa;
|
||||||
|
+ void *kernbuf;
|
||||||
|
+ int rc, status;
|
||||||
|
+
|
||||||
|
+ rc = sanity_check();
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ rc = rtas_get_rmo_buffer(length, &kernbuf, &kernbuf_pa);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ rc = rtas_call("ibm,get-system-parameter", 3, 1, htobe32(parameter),
|
||||||
|
+ htobe32(kernbuf_pa), htobe32(length), &status);
|
||||||
|
+
|
||||||
|
+ if (rc == 0)
|
||||||
|
+ memcpy(data, kernbuf, length);
|
||||||
|
+
|
||||||
|
+ (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, length);
|
||||||
|
+
|
||||||
|
+ dbg("(%u, %u, %p) = %d\n", parameter, length, data, rc ? rc : status);
|
||||||
|
+ return rc ? rc : status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * rtas_set_sysparm
|
||||||
|
+ * @brief Interface to the ibm,set-system-parameter rtas call
|
||||||
|
+ *
|
||||||
|
+ * @param parameter
|
||||||
|
+ * @param data
|
||||||
|
+ * @return 0 on success, !0 otherwise
|
||||||
|
+ */
|
||||||
|
+int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||||
|
+{
|
||||||
|
+ uint32_t kernbuf_pa;
|
||||||
|
+ void *kernbuf;
|
||||||
|
+ int rc, status;
|
||||||
|
+ uint16_t size;
|
||||||
|
+
|
||||||
|
+ rc = sanity_check();
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+ /*
|
||||||
|
+ * We have to copy the contents of @data to a RMO buffer. The
|
||||||
|
+ * caller has encoded the data length in the first two bytes
|
||||||
|
+ * of @data in MSB order, and we can't assume any
|
||||||
|
+ * alignment. So interpret @data as:
|
||||||
|
+ *
|
||||||
|
+ * struct {
|
||||||
|
+ * unsigned char len_msb;
|
||||||
|
+ * unsigned char len_lsb;
|
||||||
|
+ * char [(len_msb << 8) + len_lsb];
|
||||||
|
+ * }
|
||||||
|
+ */
|
||||||
|
+ size = 2 + (((unsigned char)data[0] << 8) | (unsigned char)data[1]);
|
||||||
|
+ rc = rtas_get_rmo_buffer(size, &kernbuf, &kernbuf_pa);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ memcpy(kernbuf, data, size);
|
||||||
|
+
|
||||||
|
+ rc = rtas_call("ibm,set-system-parameter", 2, 1, htobe32(parameter),
|
||||||
|
+ htobe32(kernbuf_pa), &status);
|
||||||
|
+
|
||||||
|
+ (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, size);
|
||||||
|
+
|
||||||
|
+ dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||||
|
+ return rc ? rc : status;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
48
0004-librtas-vendor-papr-miscdev.h.patch
Normal file
48
0004-librtas-vendor-papr-miscdev.h.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From ba86b513cbed32f5cdf8840b727457688a0737fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Mon, 25 Sep 2023 11:41:22 -0500
|
||||||
|
Subject: [PATCH 4/6] librtas: vendor papr-miscdev.h
|
||||||
|
|
||||||
|
This is a common header used by other kernel uapi headers that we will
|
||||||
|
copy into the source tree.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 4 +++-
|
||||||
|
librtas_src/papr-miscdev.h | 9 +++++++++
|
||||||
|
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 librtas_src/papr-miscdev.h
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 1385ac7..d0cabfb 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -35,7 +35,9 @@ librtas_la_SOURCES = \
|
||||||
|
librtas_src/sysparm.c
|
||||||
|
|
||||||
|
library_include_HEADERS += librtas_src/librtas.h
|
||||||
|
-noinst_HEADERS += librtas_src/internal.h
|
||||||
|
+noinst_HEADERS += \
|
||||||
|
+ librtas_src/internal.h \
|
||||||
|
+ librtas_src/papr-miscdev.h
|
||||||
|
|
||||||
|
# See "Updating library version information" in the libtool manual for
|
||||||
|
# how to maintain these values. They are *not* tied to the release
|
||||||
|
diff --git a/librtas_src/papr-miscdev.h b/librtas_src/papr-miscdev.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..c0b1072
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librtas_src/papr-miscdev.h
|
||||||
|
@@ -0,0 +1,9 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||||
|
+#ifndef _UAPI_PAPR_MISCDEV_H_
|
||||||
|
+#define _UAPI_PAPR_MISCDEV_H_
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
+ PAPR_MISCDEV_IOC_ID = 0xb2,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /* _UAPI_PAPR_MISCDEV_H_ */
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
279
0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
Normal file
279
0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
From 3fffa2c147a69fac72b0159be967ecbe9c751dfb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Sat, 12 Aug 2023 13:27:39 -0500
|
||||||
|
Subject: [PATCH 5/6] librtas/vpd: prefer /dev/papr-vpd when available
|
||||||
|
|
||||||
|
Change rtas_get_vpd() to prefer the /dev/papr-vpd character device as
|
||||||
|
proposed for the kernel here:
|
||||||
|
|
||||||
|
https://lore.kernel.org/linuxppc-dev/20230822-papr-sys_rtas-vs-lockdown-v1-0-932623cf3c7b@linux.ibm.com/
|
||||||
|
|
||||||
|
On the first invocation of rtas_get_vpd(), probe for the new ABI and
|
||||||
|
initialize an internal function pointer according to the result. Use
|
||||||
|
pthread_once() to ensure that this probe step is performed atomically
|
||||||
|
and only once. It would not make sense to re-probe (and potentially
|
||||||
|
update the implementation) on every call, since the implementations
|
||||||
|
differ in the way state for the call sequence is maintained.
|
||||||
|
|
||||||
|
Assuming the new ABI is available: upon first call to rtas_get_vpd(),
|
||||||
|
open /dev/papr-vpd and obtain a file descriptor using the
|
||||||
|
PAPR_VPD_CREATE_HANDLE ioctl() command. This file descriptor is a
|
||||||
|
reference to the VPD returned from a complete ibm,get-vpd call
|
||||||
|
sequence. Subsequent calls sequentially read the VPD from the fd,
|
||||||
|
which is closed once EOF is reached.
|
||||||
|
|
||||||
|
To existing users of rtas_get_vpd(), the new implementation is
|
||||||
|
indistinguishable from the old one, with one exception:
|
||||||
|
|
||||||
|
* When using the rtas() syscall on current systems, RTAS advances the
|
||||||
|
sequence number by a fixed interval on each call in a sequence. This
|
||||||
|
is visible in the values returned in the 'seq_next' out parameter.
|
||||||
|
|
||||||
|
* When using /dev/papr-vpd, the value returned in 'seq_next' does not
|
||||||
|
change between calls; librtas treats it as a "handle" for a sequence
|
||||||
|
in progress.
|
||||||
|
|
||||||
|
In PAPR there is no meaning attached to the value returned in the
|
||||||
|
'seq_next' out parameter, and there is no requirement that it must
|
||||||
|
change or increment on each call. No user should be relying on the
|
||||||
|
behavior of this aspect of the interface to judge the status of a
|
||||||
|
sequence.
|
||||||
|
|
||||||
|
I have verified that an unmodified vpdupdate command from a distro
|
||||||
|
lsvpd package works correctly when linked to a librtas.so with this
|
||||||
|
change. This is the primary (and perhaps only) user of rtas_get_vpd().
|
||||||
|
|
||||||
|
For now, carry a copy of the kernel uapi header.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 3 +-
|
||||||
|
librtas_src/papr-vpd.h | 22 ++++++
|
||||||
|
librtas_src/vpd.c | 155 ++++++++++++++++++++++++++++++++++++-----
|
||||||
|
3 files changed, 161 insertions(+), 19 deletions(-)
|
||||||
|
create mode 100644 librtas_src/papr-vpd.h
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index d0cabfb..d3513e9 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -37,7 +37,8 @@ librtas_la_SOURCES = \
|
||||||
|
library_include_HEADERS += librtas_src/librtas.h
|
||||||
|
noinst_HEADERS += \
|
||||||
|
librtas_src/internal.h \
|
||||||
|
- librtas_src/papr-miscdev.h
|
||||||
|
+ librtas_src/papr-miscdev.h \
|
||||||
|
+ librtas_src/papr-vpd.h
|
||||||
|
|
||||||
|
# See "Updating library version information" in the libtool manual for
|
||||||
|
# how to maintain these values. They are *not* tied to the release
|
||||||
|
diff --git a/librtas_src/papr-vpd.h b/librtas_src/papr-vpd.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..b57cf30
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librtas_src/papr-vpd.h
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||||
|
+#ifndef _UAPI_PAPR_VPD_H_
|
||||||
|
+#define _UAPI_PAPR_VPD_H_
|
||||||
|
+
|
||||||
|
+#include <asm/ioctl.h>
|
||||||
|
+#include "papr-miscdev.h"
|
||||||
|
+
|
||||||
|
+struct papr_location_code {
|
||||||
|
+ /*
|
||||||
|
+ * PAPR+ 12.3.2.4 Converged Location Code Rules - Length
|
||||||
|
+ * Restrictions. 79 characters plus nul.
|
||||||
|
+ */
|
||||||
|
+ char str[80];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * ioctl for /dev/papr-vpd. Returns a VPD handle fd corresponding to
|
||||||
|
+ * the location code.
|
||||||
|
+ */
|
||||||
|
+#define PAPR_VPD_IOC_CREATE_HANDLE _IOW(PAPR_MISCDEV_IOC_ID, 0, struct papr_location_code)
|
||||||
|
+
|
||||||
|
+#endif /* _UAPI_PAPR_VPD_H_ */
|
||||||
|
diff --git a/librtas_src/vpd.c b/librtas_src/vpd.c
|
||||||
|
index b2689fb..544560f 100644
|
||||||
|
--- a/librtas_src/vpd.c
|
||||||
|
+++ b/librtas_src/vpd.c
|
||||||
|
@@ -1,33 +1,33 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
// Support for accessing IBM Power systems Vital Product Data (VPD)
|
||||||
|
-// via the rtas() syscall.
|
||||||
|
+// via /dev/papr-vpd or the legacy rtas() syscall.
|
||||||
|
|
||||||
|
-#include <endian.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
-#include <stdint.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <search.h>
|
||||||
|
+#include <stdarg.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "librtas.h"
|
||||||
|
+#include "papr-vpd.h"
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * rtas_get_vpd
|
||||||
|
- * @brief Interface to the ibm,get-vpd rtas call
|
||||||
|
- *
|
||||||
|
- * @param loc_code location code
|
||||||
|
- * @param workarea additional args to rtas call
|
||||||
|
- * @param size
|
||||||
|
- * @param sequence
|
||||||
|
- * @param seq_next
|
||||||
|
- * @param bytes_ret
|
||||||
|
- * @return 0 on success, !0 otherwise
|
||||||
|
- */
|
||||||
|
-int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||||
|
- unsigned int sequence, unsigned int *seq_next,
|
||||||
|
- unsigned int *bytes_ret)
|
||||||
|
+static int
|
||||||
|
+get_vpd_syscall_fallback(const char *loc_code, char *workarea, size_t size,
|
||||||
|
+ unsigned int sequence, unsigned int *seq_next,
|
||||||
|
+ unsigned int *bytes_ret)
|
||||||
|
{
|
||||||
|
uint32_t kernbuf_pa;
|
||||||
|
uint32_t loc_pa = 0;
|
||||||
|
@@ -79,3 +79,122 @@ int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||||
|
workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||||
|
return rc ? rc : status;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static bool get_vpd_can_use_chardev(void)
|
||||||
|
+{
|
||||||
|
+ struct stat statbuf;
|
||||||
|
+
|
||||||
|
+ if (stat("/dev/papr-vpd", &statbuf))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!S_ISCHR(statbuf.st_mode))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (close(open("/dev/papr-vpd", O_RDONLY)))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define DEVPATH "/dev/papr-vpd"
|
||||||
|
+
|
||||||
|
+static int vpd_fd_new(const char *loc_code)
|
||||||
|
+{
|
||||||
|
+ const int devfd = open(DEVPATH, O_WRONLY);
|
||||||
|
+ struct papr_location_code lc = {};
|
||||||
|
+ int fd = -1;
|
||||||
|
+
|
||||||
|
+ if (devfd < 0)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (!loc_code)
|
||||||
|
+ loc_code = "";
|
||||||
|
+
|
||||||
|
+ if (sizeof(lc.str) < strlen(loc_code))
|
||||||
|
+ goto close_devfd;
|
||||||
|
+
|
||||||
|
+ strncpy(lc.str, loc_code, sizeof(lc.str));
|
||||||
|
+ fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
|
||||||
|
+close_devfd:
|
||||||
|
+ close(devfd);
|
||||||
|
+ return fd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+get_vpd_chardev(const char *loc_code, char *workarea, size_t size,
|
||||||
|
+ unsigned int sequence, unsigned int *seq_next,
|
||||||
|
+ unsigned int *bytes_ret)
|
||||||
|
+{
|
||||||
|
+ int fd = (sequence == 1) ? vpd_fd_new(loc_code) : (int)sequence;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Ensure we return a fd > 0 in seq_next.
|
||||||
|
+ */
|
||||||
|
+ if (fd == 1) {
|
||||||
|
+ int newfd = dup(fd);
|
||||||
|
+ close(fd);
|
||||||
|
+ fd = newfd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ return -3; /* Synthesize ibm,get-vpd "parameter error" */
|
||||||
|
+
|
||||||
|
+ int rtas_status = 0;
|
||||||
|
+ ssize_t res = read(fd, workarea, size);
|
||||||
|
+ if (res < 0) {
|
||||||
|
+ rtas_status = -1; /* Synthesize ibm,get-vpd "hardware error" */
|
||||||
|
+ close(fd);
|
||||||
|
+ } else if (res == 0 || res < (ssize_t)size) {
|
||||||
|
+ rtas_status = 0; /* Done with sequence, no more data */
|
||||||
|
+ close(fd);
|
||||||
|
+ if (seq_next)
|
||||||
|
+ *seq_next = 1;
|
||||||
|
+ if (bytes_ret)
|
||||||
|
+ *bytes_ret = res;
|
||||||
|
+ } else {
|
||||||
|
+ rtas_status = 1; /* More data available, call again */
|
||||||
|
+ if (seq_next)
|
||||||
|
+ *seq_next = fd;
|
||||||
|
+ if (bytes_ret)
|
||||||
|
+ *bytes_ret = res;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return rtas_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int (*get_vpd_fn)(const char *loc_code,
|
||||||
|
+ char *workarea,
|
||||||
|
+ size_t size,
|
||||||
|
+ unsigned int sequence,
|
||||||
|
+ unsigned int *seq_next,
|
||||||
|
+ unsigned int *bytes_ret);
|
||||||
|
+
|
||||||
|
+static void get_vpd_fn_setup(void)
|
||||||
|
+{
|
||||||
|
+ get_vpd_fn = get_vpd_can_use_chardev() ?
|
||||||
|
+ get_vpd_chardev : get_vpd_syscall_fallback;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * rtas_get_vpd
|
||||||
|
+ * @brief Interface to the ibm,get-vpd rtas call
|
||||||
|
+ *
|
||||||
|
+ * @param loc_code location code
|
||||||
|
+ * @param workarea additional args to rtas call
|
||||||
|
+ * @param size
|
||||||
|
+ * @param sequence
|
||||||
|
+ * @param seq_next
|
||||||
|
+ * @param bytes_ret
|
||||||
|
+ * @return 0 on success, !0 otherwise
|
||||||
|
+ */
|
||||||
|
+int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||||
|
+ unsigned int sequence, unsigned int *seq_next,
|
||||||
|
+ unsigned int *bytes_ret)
|
||||||
|
+{
|
||||||
|
+ static pthread_once_t get_vpd_fn_once = PTHREAD_ONCE_INIT;
|
||||||
|
+
|
||||||
|
+ pthread_once(&get_vpd_fn_once, get_vpd_fn_setup);
|
||||||
|
+
|
||||||
|
+ return get_vpd_fn(loc_code, workarea, size, sequence,
|
||||||
|
+ seq_next, bytes_ret);
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
286
0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
Normal file
286
0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
From c98bf4d902821cfeb83cd6037a36a0bf208f842c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
Date: Mon, 25 Sep 2023 11:42:26 -0500
|
||||||
|
Subject: [PATCH 6/6] librtas/sysparm: prefer /dev/papr-sysparm when available
|
||||||
|
|
||||||
|
Change rtas_get_sysparm() and rtas_set_sysparm() to prefer the
|
||||||
|
/dev/papr-sysparm character device as proposed for the kernel here:
|
||||||
|
|
||||||
|
[[[ FIXME ]]]
|
||||||
|
|
||||||
|
On the first invocation of either function, probe for the new ABI and
|
||||||
|
initialize internal function pointers according to the result. Use
|
||||||
|
pthread_once() to ensure that this initialization step is performed
|
||||||
|
atomically and only once.
|
||||||
|
|
||||||
|
When /dev/papr-sysparm is available, use its PAPR_SYSPARM_IOC_GET and
|
||||||
|
PAPR_SYSPARM_IOC_SET ioctl commands to retrieve and update system
|
||||||
|
parameters. Most of the complexity of calling RTAS is handled
|
||||||
|
internally to the kernel and the ioctl follows Linux conventions,
|
||||||
|
returning 0 on success or -1 w/errno on failure. On failure,
|
||||||
|
back-convert the errno to an RTAS status value that callers will
|
||||||
|
recognize.
|
||||||
|
|
||||||
|
For now, carry a copy of the kernel uapi header.
|
||||||
|
|
||||||
|
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 1 +
|
||||||
|
librtas_src/papr-sysparm.h | 58 +++++++++++++++
|
||||||
|
librtas_src/sysparm.c | 144 ++++++++++++++++++++++++++++++++++++-
|
||||||
|
3 files changed, 201 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 librtas_src/papr-sysparm.h
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index d3513e9..29b3b76 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -38,6 +38,7 @@ library_include_HEADERS += librtas_src/librtas.h
|
||||||
|
noinst_HEADERS += \
|
||||||
|
librtas_src/internal.h \
|
||||||
|
librtas_src/papr-miscdev.h \
|
||||||
|
+ librtas_src/papr-sysparm.h \
|
||||||
|
librtas_src/papr-vpd.h
|
||||||
|
|
||||||
|
# See "Updating library version information" in the libtool manual for
|
||||||
|
diff --git a/librtas_src/papr-sysparm.h b/librtas_src/papr-sysparm.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e0c0ebb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/librtas_src/papr-sysparm.h
|
||||||
|
@@ -0,0 +1,58 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||||
|
+#ifndef _UAPI_PAPR_SYSPARM_H_
|
||||||
|
+#define _UAPI_PAPR_SYSPARM_H_
|
||||||
|
+
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+#include <asm/ioctl.h>
|
||||||
|
+#include "papr-miscdev.h"
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
+ PAPR_SYSPARM_MAX_INPUT = 1024,
|
||||||
|
+ PAPR_SYSPARM_MAX_OUTPUT = 4000,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct papr_sysparm_io_block {
|
||||||
|
+ __u32 parameter;
|
||||||
|
+ __u16 length;
|
||||||
|
+ char data[PAPR_SYSPARM_MAX_OUTPUT];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * PAPR_SYSPARM_IOC_GET - Retrieve the value of a PAPR system parameter.
|
||||||
|
+ *
|
||||||
|
+ * Uses _IOWR because of one corner case: Retrieving the value of the
|
||||||
|
+ * "OS Service Entitlement Status" parameter (60) requires the caller
|
||||||
|
+ * to supply input data (a date string) in the buffer passed to
|
||||||
|
+ * firmware. So the @length and @data of the incoming
|
||||||
|
+ * papr_sysparm_io_block are always used to initialize the work area
|
||||||
|
+ * supplied to ibm,get-system-parameter. No other parameters are known
|
||||||
|
+ * to parameterize the result this way, and callers are encouraged
|
||||||
|
+ * (but not required) to zero-initialize @length and @data in the
|
||||||
|
+ * common case.
|
||||||
|
+ *
|
||||||
|
+ * On error the contents of the ioblock are indeterminate.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * 0: Success; @length is the length of valid data in @data, not to exceed @PAPR_SYSPARM_MAX_OUTPUT.
|
||||||
|
+ * -EIO: Platform error. (-1)
|
||||||
|
+ * -EINVAL: Incorrect data length or format. (-9999)
|
||||||
|
+ * -EPERM: The calling partition is not allowed to access this parameter. (-9002)
|
||||||
|
+ * -EOPNOTSUPP: Parameter not supported on this platform (-3)
|
||||||
|
+ */
|
||||||
|
+#define PAPR_SYSPARM_IOC_GET _IOWR(PAPR_MISCDEV_IOC_ID, 1, struct papr_sysparm_io_block)
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * PAPR_SYSPARM_IOC_SET - Update the value of a PAPR system parameter.
|
||||||
|
+ *
|
||||||
|
+ * The contents of the ioblock are unchanged regardless of success.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * 0: Success; the parameter has been updated.
|
||||||
|
+ * -EIO: Platform error. (-1)
|
||||||
|
+ * -EINVAL: Incorrect data length or format. (-9999)
|
||||||
|
+ * -EPERM: The calling partition is not allowed to access this parameter. (-9002)
|
||||||
|
+ * -EOPNOTSUPP: Parameter not supported on this platform (-3)
|
||||||
|
+ */
|
||||||
|
+#define PAPR_SYSPARM_IOC_SET _IOW(PAPR_MISCDEV_IOC_ID, 2, struct papr_sysparm_io_block)
|
||||||
|
+
|
||||||
|
+#endif /* _UAPI_PAPR_SYSPARM_H_ */
|
||||||
|
diff --git a/librtas_src/sysparm.c b/librtas_src/sysparm.c
|
||||||
|
index 40af55e..b4d2054 100644
|
||||||
|
--- a/librtas_src/sysparm.c
|
||||||
|
+++ b/librtas_src/sysparm.c
|
||||||
|
@@ -1,7 +1,16 @@
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
#include "internal.h"
|
||||||
|
#include "librtas.h"
|
||||||
|
+#include "papr-sysparm.h"
|
||||||
|
+
|
||||||
|
+static const char sysparm_devpath[] = "/dev/papr-sysparm";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rtas_get_sysparm
|
||||||
|
@@ -15,7 +24,8 @@
|
||||||
|
* @param data reference to buffer to return parameter in
|
||||||
|
* @return 0 on success, !0 otherwise
|
||||||
|
*/
|
||||||
|
-int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
+static int
|
||||||
|
+get_sysparm_syscall_fallback(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
{
|
||||||
|
uint32_t kernbuf_pa;
|
||||||
|
void *kernbuf;
|
||||||
|
@@ -49,7 +59,8 @@ int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
* @param data
|
||||||
|
* @return 0 on success, !0 otherwise
|
||||||
|
*/
|
||||||
|
-int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||||
|
+static int
|
||||||
|
+set_sysparm_syscall_fallback(unsigned int parameter, char *data)
|
||||||
|
{
|
||||||
|
uint32_t kernbuf_pa;
|
||||||
|
void *kernbuf;
|
||||||
|
@@ -86,3 +97,132 @@ int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||||
|
dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||||
|
return rc ? rc : status;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static bool sysparm_can_use_chardev(void)
|
||||||
|
+{
|
||||||
|
+ struct stat statbuf;
|
||||||
|
+
|
||||||
|
+ if (stat(sysparm_devpath, &statbuf))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!S_ISCHR(statbuf.st_mode))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (close(open(sysparm_devpath, O_RDONLY)))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Only to be used when converting an actual error from a syscall.
|
||||||
|
+ */
|
||||||
|
+static int chardev_backconvert_errno(int saved_errno)
|
||||||
|
+{
|
||||||
|
+ const struct {
|
||||||
|
+ int linux_errno;
|
||||||
|
+ int rtas_status;
|
||||||
|
+ } map[] = {
|
||||||
|
+#define errno_to_status(e, s) { .linux_errno = (e), .rtas_status = (s), }
|
||||||
|
+ errno_to_status(EINVAL, -9999),
|
||||||
|
+ errno_to_status(EPERM, -9002),
|
||||||
|
+ errno_to_status(EOPNOTSUPP, -3),
|
||||||
|
+ errno_to_status(EIO, -1),
|
||||||
|
+ errno_to_status(EFAULT, -1),
|
||||||
|
+#undef errno_to_status
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); ++i)
|
||||||
|
+ if (map[i].linux_errno == saved_errno)
|
||||||
|
+ return map[i].rtas_status;
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_sysparm_chardev(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
+{
|
||||||
|
+ const int fd = open(sysparm_devpath, O_RDWR);
|
||||||
|
+ struct papr_sysparm_io_block buf = {
|
||||||
|
+ .parameter = parameter,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ /*
|
||||||
|
+ * Really shouldn't get here without misconfiguration,
|
||||||
|
+ * e.g. removal of /dev/papr-sysparm. Synthesize a
|
||||||
|
+ * hardware/platform error.
|
||||||
|
+ */
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * It might make sense to have special handling for parameter
|
||||||
|
+ * 60 (OS Service Entitlement Status), which takes input data,
|
||||||
|
+ * but librtas has never handled that one correctly. So ignore
|
||||||
|
+ * it for now and don't copy incoming data into the block we
|
||||||
|
+ * pass to PAPR_SYSPARM_IOC_GET.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ const int res = ioctl(fd, PAPR_SYSPARM_IOC_GET, &buf);
|
||||||
|
+ const int saved_errno = errno;
|
||||||
|
+ (void)close(fd);
|
||||||
|
+
|
||||||
|
+ if (res != 0)
|
||||||
|
+ return chardev_backconvert_errno(saved_errno);
|
||||||
|
+
|
||||||
|
+ const uint16_t result_size_msb = htobe16(buf.length);
|
||||||
|
+ memcpy(data, &result_size_msb, sizeof(result_size_msb));
|
||||||
|
+ length -= sizeof(result_size_msb);
|
||||||
|
+ data += sizeof(result_size_msb);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Copy no more than min(@length, sizeof(buf.data)).
|
||||||
|
+ */
|
||||||
|
+ const size_t copy_size = sizeof(buf.data) < length ?
|
||||||
|
+ sizeof(buf.data) : length;
|
||||||
|
+ memcpy(data, buf.data, copy_size);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_sysparm_chardev(unsigned int parameter, char *data)
|
||||||
|
+{
|
||||||
|
+ const int fd = open(sysparm_devpath, O_RDWR);
|
||||||
|
+ struct papr_sysparm_io_block buf = {
|
||||||
|
+ .parameter = parameter,
|
||||||
|
+ .length = (((unsigned char)data[0] << 8) | (unsigned char)data[1]),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ memcpy(buf.data, data + 2, buf.length);
|
||||||
|
+
|
||||||
|
+ const int res = ioctl(fd, PAPR_SYSPARM_IOC_SET, &buf);
|
||||||
|
+ const int saved_errno = errno;
|
||||||
|
+ (void)close(fd);
|
||||||
|
+
|
||||||
|
+ return res == 0 ? 0 : chardev_backconvert_errno(saved_errno);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int (*get_sysparm_fn)(unsigned int parameter, unsigned int length, char *data);
|
||||||
|
+static int (*set_sysparm_fn)(unsigned int parameter, char *data);
|
||||||
|
+
|
||||||
|
+static void sysparm_fn_setup(void)
|
||||||
|
+{
|
||||||
|
+ const bool use_chardev = sysparm_can_use_chardev();
|
||||||
|
+
|
||||||
|
+ get_sysparm_fn = use_chardev ?
|
||||||
|
+ get_sysparm_chardev : get_sysparm_syscall_fallback;
|
||||||
|
+ set_sysparm_fn = use_chardev ?
|
||||||
|
+ set_sysparm_chardev : set_sysparm_syscall_fallback;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static pthread_once_t sysparm_fn_setup_once = PTHREAD_ONCE_INIT;
|
||||||
|
+
|
||||||
|
+int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||||
|
+{
|
||||||
|
+ pthread_once(&sysparm_fn_setup_once, sysparm_fn_setup);
|
||||||
|
+ return get_sysparm_fn(parameter, length, data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||||
|
+{
|
||||||
|
+ pthread_once(&sysparm_fn_setup_once, sysparm_fn_setup);
|
||||||
|
+ return set_sysparm_fn(parameter, data);
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
|
|
118
activate-firmware-regress
Normal file
118
activate-firmware-regress
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Created by argbash-init v2.10.0
|
||||||
|
# ARG_OPTIONAL_SINGLE([old],[],[old librtas DSO],[/lib64/librtas.so.2])
|
||||||
|
# ARG_OPTIONAL_SINGLE([new],[],[new librtas DSO],[$PWD/.libs/librtas.so.2])
|
||||||
|
# ARG_HELP([Test the activate_firmware command against a development build of librtas])
|
||||||
|
# ARGBASH_GO()
|
||||||
|
# needed because of Argbash --> m4_ignore([
|
||||||
|
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ###
|
||||||
|
# Argbash is a bash code generator used to get arguments parsing right.
|
||||||
|
# Argbash is FREE SOFTWARE, see https://argbash.io for more info
|
||||||
|
|
||||||
|
|
||||||
|
die()
|
||||||
|
{
|
||||||
|
local _ret="${2:-1}"
|
||||||
|
test "${_PRINT_HELP:-no}" = yes && print_help >&2
|
||||||
|
echo "$1" >&2
|
||||||
|
exit "${_ret}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
begins_with_short_option()
|
||||||
|
{
|
||||||
|
local first_option all_short_options='h'
|
||||||
|
first_option="${1:0:1}"
|
||||||
|
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# THE DEFAULTS INITIALIZATION - OPTIONALS
|
||||||
|
_arg_old="/lib64/librtas.so.2"
|
||||||
|
_arg_new="$PWD/.libs/librtas.so.2"
|
||||||
|
|
||||||
|
|
||||||
|
print_help()
|
||||||
|
{
|
||||||
|
printf '%s\n' "Test the activate_firmware command against a development build of librtas"
|
||||||
|
printf 'Usage: %s [--old <arg>] [--new <arg>] [-h|--help]\n' "$0"
|
||||||
|
printf '\t%s\n' "--old: old librtas DSO (default: '/lib64/librtas.so.2')"
|
||||||
|
printf '\t%s\n' "--new: new librtas DSO (default: '$PWD/.libs/librtas.so.2')"
|
||||||
|
printf '\t%s\n' "-h, --help: Prints help"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
parse_commandline()
|
||||||
|
{
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
_key="$1"
|
||||||
|
case "$_key" in
|
||||||
|
--old)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_old="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--old=*)
|
||||||
|
_arg_old="${_key##--old=}"
|
||||||
|
;;
|
||||||
|
--new)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_new="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--new=*)
|
||||||
|
_arg_new="${_key##--new=}"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h*)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_commandline "$@"
|
||||||
|
|
||||||
|
# OTHER STUFF GENERATED BY Argbash
|
||||||
|
|
||||||
|
### END OF CODE GENERATED BY Argbash (sortof) ### ])
|
||||||
|
# [ <-- needed because of Argbash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
workdir="$(mktemp -d)"
|
||||||
|
|
||||||
|
uak_old="${workdir}/uak.old"
|
||||||
|
uak_new="${workdir}/uak.new"
|
||||||
|
|
||||||
|
preload_sanitizers=/lib64/libasan.so.8:/lib64/libubsan.so.1
|
||||||
|
|
||||||
|
export LD_PRELOAD="${preload_sanitizers}":"$_arg_old"
|
||||||
|
activate_firmware -e > "$uak_old"
|
||||||
|
|
||||||
|
export LD_PRELOAD="${preload_sanitizers}":"$_arg_new"
|
||||||
|
activate_firmware -e > "$uak_new"
|
||||||
|
|
||||||
|
export -n LSAN_OPTIONS ASAN_OPTIONS LD_PRELOAD
|
||||||
|
|
||||||
|
cmp "$uak_old" "$uak_new" || {
|
||||||
|
echo "error: Update Access Key information differs"
|
||||||
|
diff -u "$uak_old" "$uak_new"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Tested $(type -P activate_firmware) with ${_arg_old} and ${_arg_new}, no differences detected."
|
||||||
|
|
||||||
|
test -d "$workdir" && rm -fr "$workdir"
|
||||||
|
|
||||||
|
# ] <-- needed because of Argbash
|
@ -24,12 +24,22 @@ License: LGPL-2.1-or-later
|
|||||||
Group: Documentation/Other
|
Group: Documentation/Other
|
||||||
URL: https://github.com/ibm-power-utilities/librtas
|
URL: https://github.com/ibm-power-utilities/librtas
|
||||||
Source0: https://github.com/ibm-power-utilities/librtas/archive/v%{version}.tar.gz#/librtas-%{version}.tar.gz
|
Source0: https://github.com/ibm-power-utilities/librtas/archive/v%{version}.tar.gz#/librtas-%{version}.tar.gz
|
||||||
|
Source2: activate-firmware-regress
|
||||||
|
Source3: vpdupdate-regress
|
||||||
Patch0: librtas.fix_doc_path.patch
|
Patch0: librtas.fix_doc_path.patch
|
||||||
|
Patch1: 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||||
|
Patch2: 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||||
|
Patch3: 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||||
|
Patch4: 0004-librtas-vendor-papr-miscdev.h.patch
|
||||||
|
Patch5: 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||||
|
Patch6: 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||||
|
Patch7: link-lpthread.patch
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: doxygen
|
BuildRequires: doxygen
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
|
BuildRequires: pkgconfig
|
||||||
ExclusiveArch: ppc ppc64 ppc64le
|
ExclusiveArch: ppc ppc64 ppc64le
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -41,7 +51,7 @@ This package provides librtas documentation
|
|||||||
%build
|
%build
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
%configure
|
%configure
|
||||||
%make_build CFLAGS="%{optflags} -fPIC -g -I $PWD/librtasevent_src" LIB_DIR="%{_libdir}"
|
make -O V=1 VERBOSE=1 CFLAGS="%{optflags} -fPIC -g -I $PWD/librtasevent_src" LIB_DIR="%{_libdir}" %{?_smp_mflags}
|
||||||
|
|
||||||
%install
|
%install
|
||||||
rm -rf doc/*/latex
|
rm -rf doc/*/latex
|
||||||
|
@ -1,3 +1,16 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Nov 20 16:14:19 UTC 2023 - Michal Suchanek <msuchanek@suse.com>
|
||||||
|
|
||||||
|
- Add support for new rtas kernel interface for VPD and sysparm (jsc#PED-4541).
|
||||||
|
* 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||||
|
* 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||||
|
* 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||||
|
* 0004-librtas-vendor-papr-miscdev.h.patch
|
||||||
|
* 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||||
|
* 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||||
|
* link-lpthread.patch
|
||||||
|
* tests: activate-firmware-regress vpdupdate-regress
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Nov 20 14:50:54 UTC 2023 - Michal Suchanek <msuchanek@suse.com>
|
Mon Nov 20 14:50:54 UTC 2023 - Michal Suchanek <msuchanek@suse.com>
|
||||||
|
|
||||||
|
16
librtas.spec
16
librtas.spec
@ -26,10 +26,20 @@ Group: System/Libraries
|
|||||||
URL: https://github.com/ibm-power-utilities/librtas
|
URL: https://github.com/ibm-power-utilities/librtas
|
||||||
Source0: https://github.com/ibm-power-utilities/librtas/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
Source0: https://github.com/ibm-power-utilities/librtas/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
||||||
Source1: baselibs.conf
|
Source1: baselibs.conf
|
||||||
|
Source2: activate-firmware-regress
|
||||||
|
Source3: vpdupdate-regress
|
||||||
Patch0: librtas.fix_doc_path.patch
|
Patch0: librtas.fix_doc_path.patch
|
||||||
|
Patch1: 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||||
|
Patch2: 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||||
|
Patch3: 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||||
|
Patch4: 0004-librtas-vendor-papr-miscdev.h.patch
|
||||||
|
Patch5: 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||||
|
Patch6: 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||||
|
Patch7: link-lpthread.patch
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
|
BuildRequires: pkgconfig
|
||||||
ExclusiveArch: ppc ppc64 ppc64le
|
ExclusiveArch: ppc ppc64 ppc64le
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -80,16 +90,17 @@ contents of RTAS events.
|
|||||||
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects
|
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
%configure
|
%configure
|
||||||
%make_build CFLAGS="%{optflags} -fPIC -g -I $PWD/librtasevent_src" LIB_DIR="%{_libdir}"
|
make -O V=1 VERBOSE=1 CFLAGS="%{optflags} -fPIC -g -I $PWD/librtasevent_src" LIB_DIR="%{_libdir}" %{?_smp_mflags}
|
||||||
|
|
||||||
%install
|
%install
|
||||||
rm -rf doc/*/latex
|
rm -rf doc/*/latex
|
||||||
make install DESTDIR=%{buildroot} LIB_DIR="%{_libdir}"
|
make install DESTDIR=%{buildroot} LIB_DIR="%{_libdir}"
|
||||||
# documents are in -doc subpackage
|
# documents are in -doc subpackage
|
||||||
rm -rf %{buildroot}/%{_docdir}
|
rm -rf %{buildroot}%{_docdir}
|
||||||
/sbin/ldconfig -n %{buildroot}%{_libdir}
|
/sbin/ldconfig -n %{buildroot}%{_libdir}
|
||||||
chmod -x %{buildroot}%{_libdir}/*.a
|
chmod -x %{buildroot}%{_libdir}/*.a
|
||||||
find %{buildroot} -type f -name "*.la" -delete -print
|
find %{buildroot} -type f -name "*.la" -delete -print
|
||||||
|
install -v -m 755 -D -t %{buildroot}%{_docdir}/%{name} %{SOURCE2} %{SOURCE3}
|
||||||
|
|
||||||
%post -n %{name}%{sover} -p /sbin/ldconfig
|
%post -n %{name}%{sover} -p /sbin/ldconfig
|
||||||
%postun -n %{name}%{sover} -p /sbin/ldconfig
|
%postun -n %{name}%{sover} -p /sbin/ldconfig
|
||||||
@ -101,6 +112,7 @@ find %{buildroot} -type f -name "*.la" -delete -print
|
|||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%license COPYING.LESSER
|
%license COPYING.LESSER
|
||||||
|
%{_docdir}/%{name}
|
||||||
%{_libdir}/librtasevent.so
|
%{_libdir}/librtasevent.so
|
||||||
%{_libdir}/librtas.so
|
%{_libdir}/librtas.so
|
||||||
%{_includedir}/librtas.h
|
%{_includedir}/librtas.h
|
||||||
|
15
link-lpthread.patch
Normal file
15
link-lpthread.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
librtas now uses pthread_once
|
||||||
|
|
||||||
|
diff -ur librtas-2.0.5.orig/Makefile.am librtas-2.0.5/Makefile.am
|
||||||
|
--- librtas-2.0.5.orig/Makefile.am 2023-11-23 20:42:40.488274968 +0100
|
||||||
|
+++ librtas-2.0.5/Makefile.am 2023-11-23 20:46:55.600974184 +0100
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
LIBRTAS_LIBRARY_VERSION = $(LIBRTAS_CURRENT):$(LIBRTAS_REVISION):$(LIBRTAS_AGE)
|
||||||
|
|
||||||
|
lib_LTLIBRARIES += librtas.la
|
||||||
|
-librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION)
|
||||||
|
+librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION) -lpthread
|
||||||
|
librtas_la_SOURCES = \
|
||||||
|
librtas_src/vpd.c \
|
||||||
|
librtas_src/ofdt.c \
|
||||||
|
Only in librtas-2.0.5: Makefile.am~
|
145
vpdupdate-regress
Normal file
145
vpdupdate-regress
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Created by argbash-init v2.10.0
|
||||||
|
# ARG_OPTIONAL_SINGLE([old],[],[old librtas DSO],[/lib64/librtas.so.2])
|
||||||
|
# ARG_OPTIONAL_SINGLE([new],[],[new librtas DSO],[$PWD/.libs/librtas.so.2])
|
||||||
|
# ARG_HELP([Test the vpdupdate command against a development build of librtas])
|
||||||
|
# ARGBASH_GO()
|
||||||
|
# needed because of Argbash --> m4_ignore([
|
||||||
|
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ###
|
||||||
|
# Argbash is a bash code generator used to get arguments parsing right.
|
||||||
|
# Argbash is FREE SOFTWARE, see https://argbash.io for more info
|
||||||
|
|
||||||
|
|
||||||
|
die()
|
||||||
|
{
|
||||||
|
local _ret="${2:-1}"
|
||||||
|
test "${_PRINT_HELP:-no}" = yes && print_help >&2
|
||||||
|
echo "$1" >&2
|
||||||
|
exit "${_ret}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
begins_with_short_option()
|
||||||
|
{
|
||||||
|
local first_option all_short_options='h'
|
||||||
|
first_option="${1:0:1}"
|
||||||
|
test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# THE DEFAULTS INITIALIZATION - OPTIONALS
|
||||||
|
_arg_old="/lib64/librtas.so.2"
|
||||||
|
_arg_new="$PWD/.libs/librtas.so.2"
|
||||||
|
|
||||||
|
|
||||||
|
print_help()
|
||||||
|
{
|
||||||
|
printf '%s\n' "Test the vpdupdate command against a development build of librtas"
|
||||||
|
printf 'Usage: %s [--old <arg>] [--new <arg>] [-h|--help]\n' "$0"
|
||||||
|
printf '\t%s\n' "--old: old librtas DSO (default: '/lib64/librtas.so.2')"
|
||||||
|
printf '\t%s\n' "--new: new librtas DSO (default: '$PWD/.libs/librtas.so.2')"
|
||||||
|
printf '\t%s\n' "-h, --help: Prints help"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
parse_commandline()
|
||||||
|
{
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
_key="$1"
|
||||||
|
case "$_key" in
|
||||||
|
--old)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_old="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--old=*)
|
||||||
|
_arg_old="${_key##--old=}"
|
||||||
|
;;
|
||||||
|
--new)
|
||||||
|
test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
|
||||||
|
_arg_new="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--new=*)
|
||||||
|
_arg_new="${_key##--new=}"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h*)
|
||||||
|
print_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_commandline "$@"
|
||||||
|
|
||||||
|
# OTHER STUFF GENERATED BY Argbash
|
||||||
|
|
||||||
|
### END OF CODE GENERATED BY Argbash (sortof) ### ])
|
||||||
|
# [ <-- needed because of Argbash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
workdir="$(mktemp -d)"
|
||||||
|
chmod 0775 "$workdir" # vpdupdate refuses to create the db without this?
|
||||||
|
|
||||||
|
# vpdupdate unlinks files in the same directory as the target named
|
||||||
|
# vpd.db*, use separate directories
|
||||||
|
vpd_db_old="${workdir}/old/vpd.db"
|
||||||
|
vpd_db_new="${workdir}/new/vpd.db"
|
||||||
|
|
||||||
|
# Interested in detecting leaks from within librtas, but not vpd code.
|
||||||
|
leak_suppressions="${workdir}/suppressions.txt"
|
||||||
|
cat > "$leak_suppressions" <<EOF
|
||||||
|
leak:^lsvpd::SysFSTreeCollector::
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ASAN_OPTIONS=alloc_dealloc_mismatch=0 is for new[]/delete
|
||||||
|
# mismatches in vpdupdate code.
|
||||||
|
export LSAN_OPTIONS="suppressions=$leak_suppressions"
|
||||||
|
export ASAN_OPTIONS=alloc_dealloc_mismatch=0
|
||||||
|
|
||||||
|
preload_sanitizers=/lib64/libasan.so.8:/lib64/libubsan.so.1
|
||||||
|
|
||||||
|
export LD_PRELOAD="${preload_sanitizers}":"$_arg_old"
|
||||||
|
vpdupdate -p "$vpd_db_old"
|
||||||
|
test -s "$vpd_db_old" || {
|
||||||
|
echo "error: VPD database ${vpd_db_old} is empty!?"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export LD_PRELOAD="${preload_sanitizers}":"$_arg_new"
|
||||||
|
vpdupdate -p "$vpd_db_new"
|
||||||
|
test -s "$vpd_db_new" || {
|
||||||
|
echo "error: VPD database ${vpd_db_new} is empty!?"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export -n LSAN_OPTIONS ASAN_OPTIONS LD_PRELOAD
|
||||||
|
|
||||||
|
cmp "$vpd_db_old" "$vpd_db_new" || {
|
||||||
|
echo "error: VPD database ${vpd_db_old} differs from ${vpd_db_new}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
sizes="${workdir}/sizes"
|
||||||
|
sums="${workdir}/sums"
|
||||||
|
du -h "$vpd_db_old" "$vpd_db_new" > "$sizes"
|
||||||
|
md5sum "$vpd_db_old" "$vpd_db_new" > "$sums"
|
||||||
|
join -j 2 "$sizes" "$sums"
|
||||||
|
|
||||||
|
echo "Tested $(type -P vpdupdate) with ${_arg_old} and ${_arg_new}, no differences detected."
|
||||||
|
|
||||||
|
test -d "$workdir" && rm -fr "$workdir"
|
||||||
|
|
||||||
|
# ] <-- needed because of Argbash
|
Loading…
Reference in New Issue
Block a user