To be able to remove tpm_tis_base_addr from test cases that do not really
need it move the tpm_util_tis_transmit() function into tpm-tis-utils.c and
rename it to tpm_tis_transmit().
Fix a locality parameter in a test case on the way.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
tests/qtest/tpm-crb-swtpm-test.c | 3 --
tests/qtest/tpm-crb-test.c | 3 --
tests/qtest/tpm-tis-device-swtpm-test.c | 5 +--
tests/qtest/tpm-tis-swtpm-test.c | 5 +--
tests/qtest/tpm-tis-util.c | 47 ++++++++++++++++++++++++-
tests/qtest/tpm-tis-util.h | 4 +++
tests/qtest/tpm-util.c | 45 -----------------------
tests/qtest/tpm-util.h | 3 --
8 files changed, 56 insertions(+), 59 deletions(-)
diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c
index 40254f762f..ffeb1c396b 100644
--- a/tests/qtest/tpm-crb-swtpm-test.c
+++ b/tests/qtest/tpm-crb-swtpm-test.c
@@ -19,9 +19,6 @@
#include "tpm-tests.h"
#include "hw/acpi/tpm.h"
-/* Not used but needed for linking */
-uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
-
typedef struct TestState {
char *src_tpm_path;
char *dst_tpm_path;
diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
index 7b94453390..396ae3f91c 100644
--- a/tests/qtest/tpm-crb-test.c
+++ b/tests/qtest/tpm-crb-test.c
@@ -19,9 +19,6 @@
#include "qemu/module.h"
#include "tpm-emu.h"
-/* Not used but needed for linking */
-uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
-
#define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
static void tpm_crb_test(const void *data)
diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c
index 8c067fddd4..517a077005 100644
--- a/tests/qtest/tpm-tis-device-swtpm-test.c
+++ b/tests/qtest/tpm-tis-device-swtpm-test.c
@@ -18,6 +18,7 @@
#include "libqtest.h"
#include "qemu/module.h"
#include "tpm-tests.h"
+#include "tpm-tis-util.h"
#include "hw/acpi/tpm.h"
uint64_t tpm_tis_base_addr = 0xc000000;
@@ -33,7 +34,7 @@ static void tpm_tis_swtpm_test(const void *data)
{
const TestState *ts = data;
- tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
"tpm-tis-device", MACHINE_OPTIONS);
}
@@ -42,7 +43,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
const TestState *ts = data;
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
- tpm_util_tis_transfer, "tpm-tis-device",
+ tpm_tis_transfer, "tpm-tis-device",
MACHINE_OPTIONS);
}
diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c
index 11539c0a52..105e42e21d 100644
--- a/tests/qtest/tpm-tis-swtpm-test.c
+++ b/tests/qtest/tpm-tis-swtpm-test.c
@@ -17,6 +17,7 @@
#include "libqtest.h"
#include "qemu/module.h"
#include "tpm-tests.h"
+#include "tpm-tis-util.h"
#include "hw/acpi/tpm.h"
uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
@@ -31,7 +32,7 @@ static void tpm_tis_swtpm_test(const void *data)
{
const TestState *ts = data;
- tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
"tpm-tis", NULL);
}
@@ -40,7 +41,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
const TestState *ts = data;
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
- tpm_util_tis_transfer, "tpm-tis", NULL);
+ tpm_tis_transfer, "tpm-tis", NULL);
}
int main(int argc, char **argv)
diff --git a/tests/qtest/tpm-tis-util.c b/tests/qtest/tpm-tis-util.c
index 939893bf01..728cd3e065 100644
--- a/tests/qtest/tpm-tis-util.c
+++ b/tests/qtest/tpm-tis-util.c
@@ -52,7 +52,7 @@ void tpm_tis_test_check_localities(const void *data)
uint32_t rid;
for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
- access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
+ access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
@@ -449,3 +449,48 @@ void tpm_tis_test_check_transmit(const void *data)
writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
}
+
+void tpm_tis_transfer(QTestState *s,
+ const unsigned char *req, size_t req_size,
+ unsigned char *rsp, size_t rsp_size)
+{
+ uint32_t sts;
+ uint16_t bcount;
+ size_t i;
+
+ /* request use of locality 0 */
+ qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
+ qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
+
+ sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
+ bcount = (sts >> 8) & 0xffff;
+ g_assert_cmpint(bcount, >=, req_size);
+
+ /* transmit command */
+ for (i = 0; i < req_size; i++) {
+ qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
+ }
+
+ /* start processing */
+ qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
+
+ uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
+ do {
+ sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
+ if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
+ break;
+ }
+ } while (g_get_monotonic_time() < end_time);
+
+ sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
+ bcount = (sts >> 8) & 0xffff;
+
+ memset(rsp, 0, rsp_size);
+ for (i = 0; i < bcount; i++) {
+ rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
+ }
+
+ /* relinquish use of locality 0 */
+ qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
+ TPM_TIS_ACCESS_ACTIVE_LOCALITY);
+}
diff --git a/tests/qtest/tpm-tis-util.h b/tests/qtest/tpm-tis-util.h
index d10efe86ae..03910a7ba7 100644
--- a/tests/qtest/tpm-tis-util.h
+++ b/tests/qtest/tpm-tis-util.h
@@ -20,4 +20,8 @@ void tpm_tis_test_check_access_reg_seize(const void *data);
void tpm_tis_test_check_access_reg_release(const void *data);
void tpm_tis_test_check_transmit(const void *data);
+void tpm_tis_transfer(QTestState *s,
+ const unsigned char *req, size_t req_size,
+ unsigned char *rsp, size_t rsp_size);
+
#endif /* TESTS_TPM_TIS_UTIL_H */
diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index a7efe2d0d2..1c0319e6e7 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -51,51 +51,6 @@ void tpm_util_crb_transfer(QTestState *s,
qtest_memread(s, raddr, rsp, rsp_size);
}
-void tpm_util_tis_transfer(QTestState *s,
- const unsigned char *req, size_t req_size,
- unsigned char *rsp, size_t rsp_size)
-{
- uint32_t sts;
- uint16_t bcount;
- size_t i;
-
- /* request use of locality 0 */
- qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
- qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
-
- sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
- bcount = (sts >> 8) & 0xffff;
- g_assert_cmpint(bcount, >=, req_size);
-
- /* transmit command */
- for (i = 0; i < req_size; i++) {
- qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
- }
-
- /* start processing */
- qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
-
- uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
- do {
- sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
- if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
- break;
- }
- } while (g_get_monotonic_time() < end_time);
-
- sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
- bcount = (sts >> 8) & 0xffff;
-
- memset(rsp, 0, rsp_size);
- for (i = 0; i < bcount; i++) {
- rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
- }
-
- /* relinquish use of locality 0 */
- qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
- TPM_TIS_ACCESS_ACTIVE_LOCALITY);
-}
-
void tpm_util_startup(QTestState *s, tx_func *tx)
{
unsigned char buffer[1024];
diff --git a/tests/qtest/tpm-util.h b/tests/qtest/tpm-util.h
index 80720afac0..0cb28dd6e5 100644
--- a/tests/qtest/tpm-util.h
+++ b/tests/qtest/tpm-util.h
@@ -27,9 +27,6 @@ typedef void (tx_func)(QTestState *s,
void tpm_util_crb_transfer(QTestState *s,
const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size);
-void tpm_util_tis_transfer(QTestState *s,
- const unsigned char *req, size_t req_size,
- unsigned char *rsp, size_t rsp_size);
void tpm_util_startup(QTestState *s, tx_func *tx);
void tpm_util_pcrextend(QTestState *s, tx_func *tx);
--
2.39.2
On 3/27/23 3:24 PM, Stefan Berger wrote:
> To be able to remove tpm_tis_base_addr from test cases that do not really
> need it move the tpm_util_tis_transmit() function into tpm-tis-utils.c and
> rename it to tpm_tis_transmit().
>
> Fix a locality parameter in a test case on the way.
>
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Ninad Palsule <ninad@linux.ibm.com>
> ---
> tests/qtest/tpm-crb-swtpm-test.c | 3 --
> tests/qtest/tpm-crb-test.c | 3 --
> tests/qtest/tpm-tis-device-swtpm-test.c | 5 +--
> tests/qtest/tpm-tis-swtpm-test.c | 5 +--
> tests/qtest/tpm-tis-util.c | 47 ++++++++++++++++++++++++-
> tests/qtest/tpm-tis-util.h | 4 +++
> tests/qtest/tpm-util.c | 45 -----------------------
> tests/qtest/tpm-util.h | 3 --
> 8 files changed, 56 insertions(+), 59 deletions(-)
>
> diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c
> index 40254f762f..ffeb1c396b 100644
> --- a/tests/qtest/tpm-crb-swtpm-test.c
> +++ b/tests/qtest/tpm-crb-swtpm-test.c
> @@ -19,9 +19,6 @@
> #include "tpm-tests.h"
> #include "hw/acpi/tpm.h"
>
> -/* Not used but needed for linking */
> -uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
> -
> typedef struct TestState {
> char *src_tpm_path;
> char *dst_tpm_path;
> diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
> index 7b94453390..396ae3f91c 100644
> --- a/tests/qtest/tpm-crb-test.c
> +++ b/tests/qtest/tpm-crb-test.c
> @@ -19,9 +19,6 @@
> #include "qemu/module.h"
> #include "tpm-emu.h"
>
> -/* Not used but needed for linking */
> -uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
> -
> #define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
>
> static void tpm_crb_test(const void *data)
> diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c
> index 8c067fddd4..517a077005 100644
> --- a/tests/qtest/tpm-tis-device-swtpm-test.c
> +++ b/tests/qtest/tpm-tis-device-swtpm-test.c
> @@ -18,6 +18,7 @@
> #include "libqtest.h"
> #include "qemu/module.h"
> #include "tpm-tests.h"
> +#include "tpm-tis-util.h"
> #include "hw/acpi/tpm.h"
>
> uint64_t tpm_tis_base_addr = 0xc000000;
> @@ -33,7 +34,7 @@ static void tpm_tis_swtpm_test(const void *data)
> {
> const TestState *ts = data;
>
> - tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
> + tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
> "tpm-tis-device", MACHINE_OPTIONS);
> }
>
> @@ -42,7 +43,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
> const TestState *ts = data;
>
> tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
> - tpm_util_tis_transfer, "tpm-tis-device",
> + tpm_tis_transfer, "tpm-tis-device",
> MACHINE_OPTIONS);
> }
>
> diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c
> index 11539c0a52..105e42e21d 100644
> --- a/tests/qtest/tpm-tis-swtpm-test.c
> +++ b/tests/qtest/tpm-tis-swtpm-test.c
> @@ -17,6 +17,7 @@
> #include "libqtest.h"
> #include "qemu/module.h"
> #include "tpm-tests.h"
> +#include "tpm-tis-util.h"
> #include "hw/acpi/tpm.h"
>
> uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
> @@ -31,7 +32,7 @@ static void tpm_tis_swtpm_test(const void *data)
> {
> const TestState *ts = data;
>
> - tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
> + tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
> "tpm-tis", NULL);
> }
>
> @@ -40,7 +41,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
> const TestState *ts = data;
>
> tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
> - tpm_util_tis_transfer, "tpm-tis", NULL);
> + tpm_tis_transfer, "tpm-tis", NULL);
> }
>
> int main(int argc, char **argv)
> diff --git a/tests/qtest/tpm-tis-util.c b/tests/qtest/tpm-tis-util.c
> index 939893bf01..728cd3e065 100644
> --- a/tests/qtest/tpm-tis-util.c
> +++ b/tests/qtest/tpm-tis-util.c
> @@ -52,7 +52,7 @@ void tpm_tis_test_check_localities(const void *data)
> uint32_t rid;
>
> for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
> - access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
> + access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
> g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
> TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
>
> @@ -449,3 +449,48 @@ void tpm_tis_test_check_transmit(const void *data)
> writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY);
> access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
> }
> +
> +void tpm_tis_transfer(QTestState *s,
> + const unsigned char *req, size_t req_size,
> + unsigned char *rsp, size_t rsp_size)
> +{
> + uint32_t sts;
> + uint16_t bcount;
> + size_t i;
> +
> + /* request use of locality 0 */
> + qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
> + qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
> +
> + sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> + bcount = (sts >> 8) & 0xffff;
> + g_assert_cmpint(bcount, >=, req_size);
> +
> + /* transmit command */
> + for (i = 0; i < req_size; i++) {
> + qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
> + }
> +
> + /* start processing */
> + qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
> +
> + uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
> + do {
> + sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> + if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
> + break;
> + }
> + } while (g_get_monotonic_time() < end_time);
> +
> + sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> + bcount = (sts >> 8) & 0xffff;
> +
> + memset(rsp, 0, rsp_size);
> + for (i = 0; i < bcount; i++) {
> + rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
> + }
> +
> + /* relinquish use of locality 0 */
> + qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
> + TPM_TIS_ACCESS_ACTIVE_LOCALITY);
> +}
> diff --git a/tests/qtest/tpm-tis-util.h b/tests/qtest/tpm-tis-util.h
> index d10efe86ae..03910a7ba7 100644
> --- a/tests/qtest/tpm-tis-util.h
> +++ b/tests/qtest/tpm-tis-util.h
> @@ -20,4 +20,8 @@ void tpm_tis_test_check_access_reg_seize(const void *data);
> void tpm_tis_test_check_access_reg_release(const void *data);
> void tpm_tis_test_check_transmit(const void *data);
>
> +void tpm_tis_transfer(QTestState *s,
> + const unsigned char *req, size_t req_size,
> + unsigned char *rsp, size_t rsp_size);
> +
> #endif /* TESTS_TPM_TIS_UTIL_H */
> diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
> index a7efe2d0d2..1c0319e6e7 100644
> --- a/tests/qtest/tpm-util.c
> +++ b/tests/qtest/tpm-util.c
> @@ -51,51 +51,6 @@ void tpm_util_crb_transfer(QTestState *s,
> qtest_memread(s, raddr, rsp, rsp_size);
> }
>
> -void tpm_util_tis_transfer(QTestState *s,
> - const unsigned char *req, size_t req_size,
> - unsigned char *rsp, size_t rsp_size)
> -{
> - uint32_t sts;
> - uint16_t bcount;
> - size_t i;
> -
> - /* request use of locality 0 */
> - qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
> - qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
> -
> - sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> - bcount = (sts >> 8) & 0xffff;
> - g_assert_cmpint(bcount, >=, req_size);
> -
> - /* transmit command */
> - for (i = 0; i < req_size; i++) {
> - qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
> - }
> -
> - /* start processing */
> - qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
> -
> - uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
> - do {
> - sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> - if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
> - break;
> - }
> - } while (g_get_monotonic_time() < end_time);
> -
> - sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
> - bcount = (sts >> 8) & 0xffff;
> -
> - memset(rsp, 0, rsp_size);
> - for (i = 0; i < bcount; i++) {
> - rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
> - }
> -
> - /* relinquish use of locality 0 */
> - qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
> - TPM_TIS_ACCESS_ACTIVE_LOCALITY);
> -}
> -
> void tpm_util_startup(QTestState *s, tx_func *tx)
> {
> unsigned char buffer[1024];
> diff --git a/tests/qtest/tpm-util.h b/tests/qtest/tpm-util.h
> index 80720afac0..0cb28dd6e5 100644
> --- a/tests/qtest/tpm-util.h
> +++ b/tests/qtest/tpm-util.h
> @@ -27,9 +27,6 @@ typedef void (tx_func)(QTestState *s,
> void tpm_util_crb_transfer(QTestState *s,
> const unsigned char *req, size_t req_size,
> unsigned char *rsp, size_t rsp_size);
> -void tpm_util_tis_transfer(QTestState *s,
> - const unsigned char *req, size_t req_size,
> - unsigned char *rsp, size_t rsp_size);
>
> void tpm_util_startup(QTestState *s, tx_func *tx);
> void tpm_util_pcrextend(QTestState *s, tx_func *tx);
© 2016 - 2026 Red Hat, Inc.