tests: Add a TPM TIS I2C swtpm test
Add a test case testing the TPM TIS over I2C with swtpm. Reviewed-by: Arun Menon <armenon@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260429121743.1346635-7-stefanb@linux.ibm.com Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Stefan Berger committed
Apr 29, 2026 at 12:17 UTC
a94f1c2eff993a5cafd666eed89e59775cde28b0
4 files changed
+127
-2
tests/qtest/meson.build
+3
-2
@@ -244,7 +244,7 @@ qtests_arm = \
244
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
245
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
246
(config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : []) + \
247
- (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
247
+ (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test', 'tpm-tis-i2c-swtpm-test'] : []) + \
248
(config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] : []) + \
249
(config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
250
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) + \
@@ -263,7 +263,7 @@ qtests_aarch64 = \
263
(config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test', 'xlnx-versal-trng-test'] : []) + \
264
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test', 'bcm2835-i2c-test'] : []) + \
265
(config_all_accel.has_key('CONFIG_TCG') and \
266
- config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
266
+ config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test', 'tpm-tis-i2c-swtpm-test'] : []) + \
267
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : []) + \
268
(config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
269
(config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and
@@ -402,6 +402,7 @@ qtests = {
402
'tpm-tis-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
403
'tpm-tis-test': [io, tpmemu_files, 'tpm-tis-util.c'],
404
'tpm-tis-i2c-test': [io, tpmemu_files, 'tpm-tis-i2c-util.c', 'qtest_aspeed.c'],
405
+ 'tpm-tis-i2c-swtpm-test': [io, tpmemu_files, 'tpm-tis-i2c-util.c', 'qtest_aspeed.c'],
406
'tpm-tis-device-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
407
'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'],
408
'virtio-net-failover': test_migration_files,
tests/qtest/tpm-tis-i2c-swtpm-test.c
new
+82
@@ -0,0 +1,82 @@
1
+/*
2
+ * SPDX-License-Identifier: GPL-2.0-or-later
3
+ *
4
+ * QTest testcase for TPM TIS over I2C talking to external swtpm
5
+ *
6
+ * Copyright (c) 2018, 2026 IBM Corporation
7
+ * with parts borrowed from migration-test.c that is:
8
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
9
+ *
10
+ * Authors:
11
+ * Stefan Berger <stefanb@linux.ibm.com>
12
+ *
13
+ */
14
+
15
+#include "qemu/osdep.h"
16
+
17
+#include "libqtest.h"
18
+#include "qemu/module.h"
19
+#include "tpm-tests.h"
20
+#include "tpm-tis-i2c-util.h"
21
+#include "qtest_aspeed.h"
22
+
23
+typedef struct TestState {
24
+ char *src_tpm_path;
25
+ char *dst_tpm_path;
26
+ char *uri;
27
+ const char *machine_options;
28
+ char *ifmodel;
29
+} TestState;
30
+
31
+static void tpm_tis_i2c_swtpm_test(const void *data)
32
+{
33
+ const TestState *ts = data;
34
+
35
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_i2c_transfer,
36
+ ts->ifmodel, ts->machine_options);
37
+}
38
+
39
+static void tpm_tis_swtpm_migration_test(const void *data)
40
+{
41
+ const TestState *ts = data;
42
+
43
+ tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path,
44
+ ts->uri, tpm_tis_i2c_transfer,
45
+ ts->ifmodel, ts->machine_options);
46
+}
47
+
48
+
49
+int main(int argc, char **argv)
50
+{
51
+ int ret;
52
+ TestState ts;
53
+
54
+ ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-tis-i2c-swtpm-test.XXXXXX",
55
+ NULL);
56
+ ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-tis-i2c-swtpm-test.XXXXXX",
57
+ NULL);
58
+ ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path);
59
+ ts.machine_options = "-machine rainier-bmc -accel tcg";
60
+ ts.ifmodel = g_strdup_printf(
61
+ "tpm-tis-i2c,bus=aspeed.i2c.bus.%d,address=0x%x",
62
+ I2C_DEV_BUS_NUM, I2C_SLAVE_ADDR);
63
+
64
+ module_call_init(MODULE_INIT_QOM);
65
+ g_test_init(&argc, &argv, NULL);
66
+
67
+ aspeed_bus_addr = ast2600_i2c_calc_bus_addr(I2C_DEV_BUS_NUM);
68
+
69
+ qtest_add_data_func("/tpm/tis-i2c-swtpm/test", &ts, tpm_tis_i2c_swtpm_test);
70
+ qtest_add_data_func("/tpm/tis-i2c-swtpm-migration/test", &ts,
71
+ tpm_tis_swtpm_migration_test);
72
+ ret = g_test_run();
73
+
74
+ tpm_util_rmdir(ts.dst_tpm_path);
75
+ g_free(ts.dst_tpm_path);
76
+ tpm_util_rmdir(ts.src_tpm_path);
77
+ g_free(ts.src_tpm_path);
78
+ g_free(ts.uri);
79
+ g_free(ts.ifmodel);
80
+
81
+ return ret;
82
+}
tests/qtest/tpm-tis-i2c-util.c
+38
@@ -15,6 +15,7 @@
15
#include "libqtest-single.h"
16
#include "qtest_aspeed.h"
17
#include "tpm-tis-i2c-util.h"
18
+#include "tpm-emu.h"
19
20
uint32_t aspeed_bus_addr;
21
@@ -62,3 +63,40 @@ void tpm_tis_i2c_writel(QTestState *s, uint8_t locty, uint8_t reg, uint32_t v)
63
}
64
aspeed_i2c_writel(s, aspeed_bus_addr, I2C_SLAVE_ADDR, reg, v);
65
}
66
+
67
+void tpm_tis_i2c_transfer(QTestState *s,
68
+ const unsigned char *req, size_t req_size,
69
+ unsigned char *rsp, size_t rsp_size)
70
+{
71
+ uint32_t sts;
72
+ size_t i;
73
+
74
+ /* request use of locality 0 */
75
+ tpm_tis_i2c_writeb(s, 0, TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_REQUEST_USE);
76
+
77
+ tpm_tis_i2c_writel(s, 0, TPM_I2C_REG_STS, TPM_TIS_STS_COMMAND_READY);
78
+
79
+ /* transmit command */
80
+ for (i = 0; i < req_size; i++) {
81
+ tpm_tis_i2c_writeb(s, 0, TPM_I2C_REG_DATA_FIFO, req[i]);
82
+ }
83
+
84
+ /* start processing */
85
+ tpm_tis_i2c_writeb(s, 0, TPM_I2C_REG_STS, TPM_TIS_STS_TPM_GO);
86
+
87
+ uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
88
+ do {
89
+ sts = tpm_tis_i2c_readl(s, 0, TPM_I2C_REG_STS);
90
+ if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
91
+ break;
92
+ }
93
+ } while (g_get_monotonic_time() < end_time);
94
+
95
+ /* read response */
96
+ for (i = 0; i < rsp_size; i++) {
97
+ rsp[i] = tpm_tis_i2c_readb(s, 0, TPM_I2C_REG_DATA_FIFO);
98
+ }
99
+ /* relinquish use of locality 0 */
100
+ tpm_tis_i2c_writeb(s, 0,
101
+ TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_ACTIVE_LOCALITY);
102
+}
tests/qtest/tpm-tis-i2c-util.h
+4
@@ -27,4 +27,8 @@ uint32_t tpm_tis_i2c_readl(QTestState *s, uint8_t locty, uint8_t reg);
27
void tpm_tis_i2c_writeb(QTestState *s, uint8_t locty, uint8_t reg, uint8_t v);
28
void tpm_tis_i2c_writel(QTestState *s, uint8_t locty, uint8_t reg, uint32_t v);
29
30
+void tpm_tis_i2c_transfer(QTestState *s,
31
+ const unsigned char *req, size_t req_size,
32
+ unsigned char *rsp, size_t rsp_size);
33
+
34
#endif /* TESTS_TPM_TIS_I2C_UTIL_H */