@samitouri / QOSamiQemu / commits / a94f1c2eff

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 */