aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qtest')
-rw-r--r--tests/qtest/arm-cpu-features.c13
-rw-r--r--tests/qtest/bios-tables-test.c26
-rw-r--r--tests/qtest/boot-serial-test.c2
-rw-r--r--tests/qtest/fuzz-xlnx-dp-test.c33
-rw-r--r--tests/qtest/libqos/arm-raspi2-machine.c8
-rw-r--r--tests/qtest/libqos/qgraph.h6
-rw-r--r--tests/qtest/libqos/qgraph_internal.h2
-rw-r--r--tests/qtest/meson.build1
-rw-r--r--tests/qtest/tpm-crb-test.c5
-rw-r--r--tests/qtest/tpm-emu.c62
-rw-r--r--tests/qtest/tpm-emu.h20
-rw-r--r--tests/qtest/tpm-tis-device-test.c3
-rw-r--r--tests/qtest/tpm-tis-test.c3
-rw-r--r--tests/qtest/tpm-tis-util.c2
14 files changed, 153 insertions, 33 deletions
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index 8252b85..90a87f0 100644
--- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c
@@ -473,6 +473,19 @@ static void test_query_cpu_model_expansion(const void *data)
assert_has_feature_enabled(qts, "cortex-a57", "pmu");
assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
+ assert_has_feature_enabled(qts, "a64fx", "pmu");
+ assert_has_feature_enabled(qts, "a64fx", "aarch64");
+ /*
+ * A64FX does not support any other vector lengths besides those
+ * that are enabled by default(128bit, 256bits, 512bit).
+ */
+ assert_has_feature_enabled(qts, "a64fx", "sve");
+ assert_sve_vls(qts, "a64fx", 0xb, NULL);
+ assert_error(qts, "a64fx", "cannot enable sve384",
+ "{ 'sve384': true }");
+ assert_error(qts, "a64fx", "cannot enable sve640",
+ "{ 'sve640': true }");
+
sve_tests_default(qts, "max");
pauth_tests_default(qts, "max");
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 51d3a4e..4f11d03 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1092,16 +1092,16 @@ static void test_acpi_piix4_tcg_numamem(void)
uint64_t tpm_tis_base_addr;
static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
- uint64_t base)
+ uint64_t base, enum TPMVersion tpm_version)
{
-#ifdef CONFIG_TPM
gchar *tmp_dir_name = g_strdup_printf("qemu-test_acpi_%s_tcg_%s.XXXXXX",
machine, tpm_if);
char *tmp_path = g_dir_make_tmp(tmp_dir_name, NULL);
- TestState test;
+ TPMTestState test;
test_data data;
GThread *thread;
- char *args, *variant = g_strdup_printf(".%s", tpm_if);
+ const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12";
+ char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix);
tpm_tis_base_addr = base;
@@ -1113,6 +1113,7 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
g_mutex_init(&test.data_mutex);
g_cond_init(&test.data_cond);
test.data_cond_signal = false;
+ test.tpm_version = tpm_version;
thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
tpm_emu_test_wait_cond(&test);
@@ -1138,14 +1139,16 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
g_free(tmp_dir_name);
g_free(args);
free_test_data(&data);
-#else
- g_test_skip("TPM disabled");
-#endif
}
-static void test_acpi_q35_tcg_tpm_tis(void)
+static void test_acpi_q35_tcg_tpm2_tis(void)
+{
+ test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_2_0);
+}
+
+static void test_acpi_q35_tcg_tpm12_tis(void)
{
- test_acpi_tcg_tpm("q35", "tis", 0xFED40000);
+ test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_1_2);
}
static void test_acpi_tcg_dimm_pxm(const char *machine)
@@ -1516,7 +1519,10 @@ int main(int argc, char *argv[])
return ret;
}
qtest_add_func("acpi/q35/oem-fields", test_acpi_oem_fields_q35);
- qtest_add_func("acpi/q35/tpm-tis", test_acpi_q35_tcg_tpm_tis);
+ if (tpm_model_is_available("-machine q35", "tpm-tis")) {
+ qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis);
+ qtest_add_func("acpi/q35/tpm12-tis", test_acpi_q35_tcg_tpm12_tis);
+ }
qtest_add_func("acpi/piix4", test_acpi_piix4_tcg);
qtest_add_func("acpi/oem-fields", test_acpi_oem_fields_pc);
qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge);
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 96849ce..83828ba 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -173,7 +173,7 @@ static testdef_t tests[] = {
sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
{ "microblazeel", "petalogix-ml605", "", "TT",
sizeof(kernel_plml605), kernel_plml605 },
- { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
+ { "arm", "raspi2b", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
/* For hppa, force bios to output to serial by disabling graphics. */
{ "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" },
{ "aarch64", "virt", "-cpu max", "TT", sizeof(kernel_aarch64),
diff --git a/tests/qtest/fuzz-xlnx-dp-test.c b/tests/qtest/fuzz-xlnx-dp-test.c
new file mode 100644
index 0000000..69eb6c0
--- /dev/null
+++ b/tests/qtest/fuzz-xlnx-dp-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest fuzzer-generated testcase for xlnx-dp display device
+ *
+ * Copyright (c) 2021 Qiang Liu <cyruscyliu@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqtest.h"
+
+/*
+ * This used to trigger the out-of-bounds read in xlnx_dp_read
+ */
+static void test_fuzz_xlnx_dp_0x3ac(void)
+{
+ QTestState *s = qtest_init("-M xlnx-zcu102 -display none ");
+ qtest_readl(s, 0xfd4a03ac);
+ qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+ const char *arch = qtest_get_arch();
+
+ g_test_init(&argc, &argv, NULL);
+
+ if (strcmp(arch, "aarch64") == 0) {
+ qtest_add_func("fuzz/test_fuzz_xlnx_dp/3ac", test_fuzz_xlnx_dp_0x3ac);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/qtest/libqos/arm-raspi2-machine.c b/tests/qtest/libqos/arm-raspi2-machine.c
index 35bb470..09ca863 100644
--- a/tests/qtest/libqos/arm-raspi2-machine.c
+++ b/tests/qtest/libqos/arm-raspi2-machine.c
@@ -42,7 +42,7 @@ static void *raspi2_get_driver(void *object, const char *interface)
return &machine->alloc;
}
- fprintf(stderr, "%s not present in arm/raspi2\n", interface);
+ fprintf(stderr, "%s not present in arm/raspi2b\n", interface);
g_assert_not_reached();
}
@@ -53,7 +53,7 @@ static QOSGraphObject *raspi2_get_device(void *obj, const char *device)
return &machine->sdhci.obj;
}
- fprintf(stderr, "%s not present in arm/raspi2\n", device);
+ fprintf(stderr, "%s not present in arm/raspi2b\n", device);
g_assert_not_reached();
}
@@ -85,8 +85,8 @@ static void *qos_create_machine_arm_raspi2(QTestState *qts)
static void raspi2_register_nodes(void)
{
- qos_node_create_machine("arm/raspi2", qos_create_machine_arm_raspi2);
- qos_node_contains("arm/raspi2", "generic-sdhci", NULL);
+ qos_node_create_machine("arm/raspi2b", qos_create_machine_arm_raspi2);
+ qos_node_contains("arm/raspi2b", "generic-sdhci", NULL);
}
libqos_init(raspi2_register_nodes);
diff --git a/tests/qtest/libqos/qgraph.h b/tests/qtest/libqos/qgraph.h
index 5467235..871740c 100644
--- a/tests/qtest/libqos/qgraph.h
+++ b/tests/qtest/libqos/qgraph.h
@@ -252,17 +252,17 @@ void qos_node_create_driver_named(const char *name, const char *qemu_name,
* This function can be useful when there are multiple devices
* with the same node name contained in a machine/other node
*
- * For example, if ``arm/raspi2`` contains 2 ``generic-sdhci``
+ * For example, if ``arm/raspi2b`` contains 2 ``generic-sdhci``
* devices, the right commands will be:
*
* .. code::
*
- * qos_node_create_machine("arm/raspi2");
+ * qos_node_create_machine("arm/raspi2b");
* qos_node_create_driver("generic-sdhci", constructor);
* // assume rest of the fields are set NULL
* QOSGraphEdgeOptions op1 = { .edge_name = "emmc" };
* QOSGraphEdgeOptions op2 = { .edge_name = "sdcard" };
- * qos_node_contains("arm/raspi2", "generic-sdhci", &op1, &op2, NULL);
+ * qos_node_contains("arm/raspi2b", "generic-sdhci", &op1, &op2, NULL);
*
* Of course this also requires that the @container's get_device function
* should implement a case for "emmc" and "sdcard".
diff --git a/tests/qtest/libqos/qgraph_internal.h b/tests/qtest/libqos/qgraph_internal.h
index c0025f5..7d62fd1 100644
--- a/tests/qtest/libqos/qgraph_internal.h
+++ b/tests/qtest/libqos/qgraph_internal.h
@@ -230,7 +230,7 @@ void qos_graph_foreach_test_path(QOSTestCallback fn);
/**
* qos_get_machine_type(): return QEMU machine type for a machine node.
* This function requires every machine @name to be in the form
- * <arch>/<machine_name>, like "arm/raspi2" or "x86_64/pc".
+ * <arch>/<machine_name>, like "arm/raspi2b" or "x86_64/pc".
*
* The function will validate the format and return a pointer to
* @machine to <machine_name>. For example, when passed "x86_64/pc"
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 2bc3efd..757bb84 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -187,6 +187,7 @@ qtests_aarch64 = \
'numa-test',
'boot-serial-test',
'xlnx-can-test',
+ 'fuzz-xlnx-dp-test',
'migration-test']
qtests_s390x = \
diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
index ed53390..7b94453 100644
--- a/tests/qtest/tpm-crb-test.c
+++ b/tests/qtest/tpm-crb-test.c
@@ -26,7 +26,7 @@ uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
static void tpm_crb_test(const void *data)
{
- const TestState *s = data;
+ const TPMTestState *s = data;
uint32_t intfid = readl(TPM_CRB_ADDR_BASE + A_CRB_INTF_ID);
uint32_t csize = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_SIZE);
uint64_t caddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_LADDR);
@@ -145,7 +145,7 @@ int main(int argc, char **argv)
int ret;
char *args, *tmp_path = g_dir_make_tmp("qemu-tpm-crb-test.XXXXXX", NULL);
GThread *thread;
- TestState test;
+ TPMTestState test;
module_call_init(MODULE_INIT_QOM);
g_test_init(&argc, &argv, NULL);
@@ -156,6 +156,7 @@ int main(int argc, char **argv)
g_mutex_init(&test.data_mutex);
g_cond_init(&test.data_cond);
test.data_cond_signal = false;
+ test.tpm_version = TPM_VERSION_2_0;
thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
tpm_emu_test_wait_cond(&test);
diff --git a/tests/qtest/tpm-emu.c b/tests/qtest/tpm-emu.c
index 2e8eb7b..2994d1c 100644
--- a/tests/qtest/tpm-emu.c
+++ b/tests/qtest/tpm-emu.c
@@ -16,9 +16,11 @@
#include "backends/tpm/tpm_ioctl.h"
#include "io/channel-socket.h"
#include "qapi/error.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qstring.h"
#include "tpm-emu.h"
-void tpm_emu_test_wait_cond(TestState *s)
+void tpm_emu_test_wait_cond(TPMTestState *s)
{
gint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
@@ -36,7 +38,7 @@ void tpm_emu_test_wait_cond(TestState *s)
static void *tpm_emu_tpm_thread(void *data)
{
- TestState *s = data;
+ TPMTestState *s = data;
QIOChannel *ioc = s->tpm_ioc;
s->tpm_msg = g_new(struct tpm_hdr, 1);
@@ -56,9 +58,21 @@ static void *tpm_emu_tpm_thread(void *data)
s->tpm_msg->code = be32_to_cpu(s->tpm_msg->code);
/* reply error */
- s->tpm_msg->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
- s->tpm_msg->len = cpu_to_be32(sizeof(struct tpm_hdr));
- s->tpm_msg->code = cpu_to_be32(TPM_RC_FAILURE);
+ switch (s->tpm_version) {
+ case TPM_VERSION_2_0:
+ s->tpm_msg->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
+ s->tpm_msg->len = cpu_to_be32(sizeof(struct tpm_hdr));
+ s->tpm_msg->code = cpu_to_be32(TPM_RC_FAILURE);
+ break;
+ case TPM_VERSION_1_2:
+ s->tpm_msg->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND);
+ s->tpm_msg->len = cpu_to_be32(sizeof(struct tpm_hdr));
+ s->tpm_msg->code = cpu_to_be32(TPM_FAIL);
+ break;
+ default:
+ g_debug("unsupport TPM version %u", s->tpm_version);
+ g_assert_not_reached();
+ }
qio_channel_write(ioc, (char *)s->tpm_msg, be32_to_cpu(s->tpm_msg->len),
&error_abort);
}
@@ -71,7 +85,7 @@ static void *tpm_emu_tpm_thread(void *data)
void *tpm_emu_ctrl_thread(void *data)
{
- TestState *s = data;
+ TPMTestState *s = data;
QIOChannelSocket *lioc = qio_channel_socket_new();
QIOChannel *ioc;
@@ -180,3 +194,39 @@ void *tpm_emu_ctrl_thread(void *data)
object_unref(OBJECT(lioc));
return NULL;
}
+
+bool tpm_model_is_available(const char *args, const char *tpm_if)
+{
+ QTestState *qts;
+ QDict *rsp_tpm;
+ bool ret = false;
+
+ qts = qtest_init(args);
+ if (!qts) {
+ return false;
+ }
+
+ rsp_tpm = qtest_qmp(qts, "{ 'execute': 'query-tpm'}");
+ if (!qdict_haskey(rsp_tpm, "error")) {
+ QDict *rsp_models = qtest_qmp(qts,
+ "{ 'execute': 'query-tpm-models'}");
+ if (qdict_haskey(rsp_models, "return")) {
+ QList *models = qdict_get_qlist(rsp_models, "return");
+ QListEntry *e;
+
+ QLIST_FOREACH_ENTRY(models, e) {
+ QString *s = qobject_to(QString, qlist_entry_obj(e));
+ const char *ename = qstring_get_str(s);
+ if (!strcmp(ename, tpm_if)) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ qobject_unref(rsp_models);
+ }
+ qobject_unref(rsp_tpm);
+ qtest_quit(qts);
+
+ return ret;
+}
diff --git a/tests/qtest/tpm-emu.h b/tests/qtest/tpm-emu.h
index 73f3bed..c33d99a 100644
--- a/tests/qtest/tpm-emu.h
+++ b/tests/qtest/tpm-emu.h
@@ -16,8 +16,13 @@
#define TPM_RC_FAILURE 0x101
#define TPM2_ST_NO_SESSIONS 0x8001
+#define TPM_FAIL 9
+#define TPM_TAG_RSP_COMMAND 0xc4
+
#include "qemu/sockets.h"
#include "io/channel.h"
+#include "sysemu/tpm.h"
+#include "libqos/libqtest.h"
struct tpm_hdr {
uint16_t tag;
@@ -26,7 +31,14 @@ struct tpm_hdr {
char buffer[];
} QEMU_PACKED;
-typedef struct TestState {
+#ifndef CONFIG_TPM
+enum TPMVersion {
+ TPM_VERSION_1_2 = 1,
+ TPM_VERSION_2_0 = 2,
+};
+#endif
+
+typedef struct TPMTestState {
GMutex data_mutex;
GCond data_cond;
bool data_cond_signal;
@@ -34,9 +46,11 @@ typedef struct TestState {
QIOChannel *tpm_ioc;
GThread *emu_tpm_thread;
struct tpm_hdr *tpm_msg;
-} TestState;
+ enum TPMVersion tpm_version;
+} TPMTestState;
-void tpm_emu_test_wait_cond(TestState *s);
+void tpm_emu_test_wait_cond(TPMTestState *s);
void *tpm_emu_ctrl_thread(void *data);
+bool tpm_model_is_available(const char *args, const char *tpm_if);
#endif /* TESTS_TPM_EMU_H */
diff --git a/tests/qtest/tpm-tis-device-test.c b/tests/qtest/tpm-tis-device-test.c
index 63ed364..3ddefb5 100644
--- a/tests/qtest/tpm-tis-device-test.c
+++ b/tests/qtest/tpm-tis-device-test.c
@@ -33,7 +33,7 @@ int main(int argc, char **argv)
{
char *tmp_path = g_dir_make_tmp("qemu-tpm-tis-device-test.XXXXXX", NULL);
GThread *thread;
- TestState test;
+ TPMTestState test;
char *args;
int ret;
@@ -46,6 +46,7 @@ int main(int argc, char **argv)
g_mutex_init(&test.data_mutex);
g_cond_init(&test.data_cond);
test.data_cond_signal = false;
+ test.tpm_version = TPM_VERSION_2_0;
thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
tpm_emu_test_wait_cond(&test);
diff --git a/tests/qtest/tpm-tis-test.c b/tests/qtest/tpm-tis-test.c
index 79ffbc9..a4a25ba 100644
--- a/tests/qtest/tpm-tis-test.c
+++ b/tests/qtest/tpm-tis-test.c
@@ -29,7 +29,7 @@ int main(int argc, char **argv)
int ret;
char *args, *tmp_path = g_dir_make_tmp("qemu-tpm-tis-test.XXXXXX", NULL);
GThread *thread;
- TestState test;
+ TPMTestState test;
module_call_init(MODULE_INIT_QOM);
g_test_init(&argc, &argv, NULL);
@@ -40,6 +40,7 @@ int main(int argc, char **argv)
g_mutex_init(&test.data_mutex);
g_cond_init(&test.data_cond);
test.data_cond_signal = false;
+ test.tpm_version = TPM_VERSION_2_0;
thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
tpm_emu_test_wait_cond(&test);
diff --git a/tests/qtest/tpm-tis-util.c b/tests/qtest/tpm-tis-util.c
index 9aff503..939893b 100644
--- a/tests/qtest/tpm-tis-util.c
+++ b/tests/qtest/tpm-tis-util.c
@@ -373,7 +373,7 @@ void tpm_tis_test_check_access_reg_release(const void *data)
*/
void tpm_tis_test_check_transmit(const void *data)
{
- const TestState *s = data;
+ const TPMTestState *s = data;
uint8_t access;
uint32_t sts;
uint16_t bcount;