All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 36/51] tests: arm: Introduce cpu feature tests
Date: Thu, 24 Oct 2019 17:27:09 +0100	[thread overview]
Message-ID: <20191024162724.31675-37-peter.maydell@linaro.org> (raw)
In-Reply-To: <20191024162724.31675-1-peter.maydell@linaro.org>

From: Andrew Jones <drjones@redhat.com>

Now that Arm CPUs have advertised features lets add tests to ensure
we maintain their expected availability with and without KVM.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20191024121808.9612-3-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/Makefile.include   |   5 +-
 tests/arm-cpu-features.c | 240 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 244 insertions(+), 1 deletion(-)
 create mode 100644 tests/arm-cpu-features.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 09e5b410dca..d71188f251b 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -262,6 +262,7 @@ check-qtest-sparc64-$(CONFIG_ISA_TESTDEV) = tests/endianness-test$(EXESUF)
 check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
 check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
 
+check-qtest-arm-y += tests/arm-cpu-features$(EXESUF)
 check-qtest-arm-y += tests/microbit-test$(EXESUF)
 check-qtest-arm-y += tests/m25p80-test$(EXESUF)
 check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
@@ -269,7 +270,8 @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
 check-qtest-arm-y += tests/hexloader-test$(EXESUF)
 check-qtest-arm-$(CONFIG_PFLASH_CFI02) += tests/pflash-cfi02-test$(EXESUF)
 
-check-qtest-aarch64-y = tests/numa-test$(EXESUF)
+check-qtest-aarch64-y += tests/arm-cpu-features$(EXESUF)
+check-qtest-aarch64-y += tests/numa-test$(EXESUF)
 check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
 check-qtest-aarch64-y += tests/migration-test$(EXESUF)
 # TODO: once aarch64 TCG is fixed on ARM 32 bit host, make test unconditional
@@ -835,6 +837,7 @@ tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
 tests/numa-test$(EXESUF): tests/numa-test.o
 tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o
 tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y)
+tests/arm-cpu-features$(EXESUF): tests/arm-cpu-features.o
 
 tests/migration/stress$(EXESUF): tests/migration/stress.o
 	$(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"LINK","$(TARGET_DIR)$@")
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
new file mode 100644
index 00000000000..c59fcf409c8
--- /dev/null
+++ b/tests/arm-cpu-features.c
@@ -0,0 +1,240 @@
+/*
+ * Arm CPU feature test cases
+ *
+ * Copyright (c) 2019 Red Hat Inc.
+ * Authors:
+ *  Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qjson.h"
+
+#define MACHINE    "-machine virt,gic-version=max "
+#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
+                     "'arguments': { 'type': 'full', "
+#define QUERY_TAIL "}}"
+
+static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
+{
+    return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
+                          QUERY_TAIL, cpu_type);
+}
+
+static QDict *do_query(QTestState *qts, const char *cpu_type,
+                       const char *fmt, ...)
+{
+    QDict *resp;
+
+    if (fmt) {
+        QDict *args;
+        va_list ap;
+
+        va_start(ap, fmt);
+        args = qdict_from_vjsonf_nofail(fmt, ap);
+        va_end(ap);
+
+        resp = qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s, "
+                                                    "'props': %p }"
+                              QUERY_TAIL, cpu_type, args);
+    } else {
+        resp = do_query_no_props(qts, cpu_type);
+    }
+
+    return resp;
+}
+
+static const char *resp_get_error(QDict *resp)
+{
+    QDict *qdict;
+
+    g_assert(resp);
+
+    qdict = qdict_get_qdict(resp, "error");
+    if (qdict) {
+        return qdict_get_str(qdict, "desc");
+    }
+    return NULL;
+}
+
+#define assert_error(qts, cpu_type, expected_error, fmt, ...)          \
+({                                                                     \
+    QDict *_resp;                                                      \
+    const char *_error;                                                \
+                                                                       \
+    _resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__);               \
+    g_assert(_resp);                                                   \
+    _error = resp_get_error(_resp);                                    \
+    g_assert(_error);                                                  \
+    g_assert(g_str_equal(_error, expected_error));                     \
+    qobject_unref(_resp);                                              \
+})
+
+static bool resp_has_props(QDict *resp)
+{
+    QDict *qdict;
+
+    g_assert(resp);
+
+    if (!qdict_haskey(resp, "return")) {
+        return false;
+    }
+    qdict = qdict_get_qdict(resp, "return");
+
+    if (!qdict_haskey(qdict, "model")) {
+        return false;
+    }
+    qdict = qdict_get_qdict(qdict, "model");
+
+    return qdict_haskey(qdict, "props");
+}
+
+static QDict *resp_get_props(QDict *resp)
+{
+    QDict *qdict;
+
+    g_assert(resp);
+    g_assert(resp_has_props(resp));
+
+    qdict = qdict_get_qdict(resp, "return");
+    qdict = qdict_get_qdict(qdict, "model");
+    qdict = qdict_get_qdict(qdict, "props");
+    return qdict;
+}
+
+#define assert_has_feature(qts, cpu_type, feature)                     \
+({                                                                     \
+    QDict *_resp = do_query_no_props(qts, cpu_type);                   \
+    g_assert(_resp);                                                   \
+    g_assert(resp_has_props(_resp));                                   \
+    g_assert(qdict_get(resp_get_props(_resp), feature));               \
+    qobject_unref(_resp);                                              \
+})
+
+#define assert_has_not_feature(qts, cpu_type, feature)                 \
+({                                                                     \
+    QDict *_resp = do_query_no_props(qts, cpu_type);                   \
+    g_assert(_resp);                                                   \
+    g_assert(!resp_has_props(_resp) ||                                 \
+             !qdict_get(resp_get_props(_resp), feature));              \
+    qobject_unref(_resp);                                              \
+})
+
+static void assert_type_full(QTestState *qts)
+{
+    const char *error;
+    QDict *resp;
+
+    resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
+                            "'arguments': { 'type': 'static', "
+                                           "'model': { 'name': 'foo' }}}");
+    g_assert(resp);
+    error = resp_get_error(resp);
+    g_assert(error);
+    g_assert(g_str_equal(error,
+                         "The requested expansion type is not supported"));
+    qobject_unref(resp);
+}
+
+static void assert_bad_props(QTestState *qts, const char *cpu_type)
+{
+    const char *error;
+    QDict *resp;
+
+    resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
+                            "'arguments': { 'type': 'full', "
+                                           "'model': { 'name': %s, "
+                                                      "'props': false }}}",
+                     cpu_type);
+    g_assert(resp);
+    error = resp_get_error(resp);
+    g_assert(error);
+    g_assert(g_str_equal(error,
+                         "Invalid parameter type for 'props', expected: dict"));
+    qobject_unref(resp);
+}
+
+static void test_query_cpu_model_expansion(const void *data)
+{
+    QTestState *qts;
+
+    qts = qtest_init(MACHINE "-cpu max");
+
+    /* Test common query-cpu-model-expansion input validation */
+    assert_type_full(qts);
+    assert_bad_props(qts, "max");
+    assert_error(qts, "foo", "The CPU type 'foo' is not a recognized "
+                 "ARM CPU type", NULL);
+    assert_error(qts, "max", "Parameter 'not-a-prop' is unexpected",
+                 "{ 'not-a-prop': false }");
+    assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
+
+    /* Test expected feature presence/absence for some cpu types */
+    assert_has_feature(qts, "max", "pmu");
+    assert_has_feature(qts, "cortex-a15", "pmu");
+    assert_has_not_feature(qts, "cortex-a15", "aarch64");
+
+    if (g_str_equal(qtest_get_arch(), "aarch64")) {
+        assert_has_feature(qts, "max", "aarch64");
+        assert_has_feature(qts, "cortex-a57", "pmu");
+        assert_has_feature(qts, "cortex-a57", "aarch64");
+
+        /* Test that features that depend on KVM generate errors without. */
+        assert_error(qts, "max",
+                     "'aarch64' feature cannot be disabled "
+                     "unless KVM is enabled and 32-bit EL1 "
+                     "is supported",
+                     "{ 'aarch64': false }");
+    }
+
+    qtest_quit(qts);
+}
+
+static void test_query_cpu_model_expansion_kvm(const void *data)
+{
+    QTestState *qts;
+
+    qts = qtest_init(MACHINE "-accel kvm -cpu host");
+
+    if (g_str_equal(qtest_get_arch(), "aarch64")) {
+        assert_has_feature(qts, "host", "aarch64");
+        assert_has_feature(qts, "host", "pmu");
+
+        assert_error(qts, "cortex-a15",
+            "We cannot guarantee the CPU type 'cortex-a15' works "
+            "with KVM on this host", NULL);
+    } else {
+        assert_has_not_feature(qts, "host", "aarch64");
+        assert_has_not_feature(qts, "host", "pmu");
+    }
+
+    qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+    bool kvm_available = false;
+
+    if (!access("/dev/kvm",  R_OK | W_OK)) {
+#if defined(HOST_AARCH64)
+        kvm_available = g_str_equal(qtest_get_arch(), "aarch64");
+#elif defined(HOST_ARM)
+        kvm_available = g_str_equal(qtest_get_arch(), "arm");
+#endif
+    }
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_data_func("/arm/query-cpu-model-expansion",
+                        NULL, test_query_cpu_model_expansion);
+
+    if (kvm_available) {
+        qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
+                            NULL, test_query_cpu_model_expansion_kvm);
+    }
+
+    return g_test_run();
+}
-- 
2.20.1



  parent reply	other threads:[~2019-10-24 17:24 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-24 16:26 [PULL 00/51] target-arm queue Peter Maydell
2019-10-24 16:26 ` [PULL 01/51] hw/gpio: Fix property accessors of the AST2600 GPIO 1.8V model Peter Maydell
2019-10-24 16:26 ` [PULL 02/51] aspeed: Add an AST2600 eval board Peter Maydell
2019-10-24 16:26 ` [PULL 03/51] target/arm: Split out rebuild_hflags_common Peter Maydell
2019-10-24 16:26 ` [PULL 04/51] target/arm: Split out rebuild_hflags_a64 Peter Maydell
2019-10-24 16:26 ` [PULL 05/51] target/arm: Split out rebuild_hflags_common_32 Peter Maydell
2019-10-24 16:26 ` [PULL 06/51] target/arm: Split arm_cpu_data_is_big_endian Peter Maydell
2019-10-24 16:26 ` [PULL 07/51] target/arm: Split out rebuild_hflags_m32 Peter Maydell
2019-10-24 16:26 ` [PULL 08/51] target/arm: Reduce tests vs M-profile in cpu_get_tb_cpu_state Peter Maydell
2019-10-24 16:26 ` [PULL 09/51] target/arm: Split out rebuild_hflags_a32 Peter Maydell
2019-10-24 16:26 ` [PULL 10/51] target/arm: Split out rebuild_hflags_aprofile Peter Maydell
2019-10-24 16:26 ` [PULL 11/51] target/arm: Hoist XSCALE_CPAR, VECLEN, VECSTRIDE in cpu_get_tb_cpu_state Peter Maydell
2019-10-24 16:26 ` [PULL 12/51] target/arm: Simplify set of PSTATE_SS " Peter Maydell
2019-10-24 16:26 ` [PULL 13/51] target/arm: Hoist computation of TBFLAG_A32.VFPEN Peter Maydell
2019-10-24 16:26 ` [PULL 14/51] target/arm: Add arm_rebuild_hflags Peter Maydell
2019-10-24 16:26 ` [PULL 15/51] target/arm: Split out arm_mmu_idx_el Peter Maydell
2019-10-24 16:26 ` [PULL 16/51] target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state Peter Maydell
2019-10-24 16:26 ` [PULL 17/51] target/arm: Add HELPER(rebuild_hflags_{a32, a64, m32}) Peter Maydell
2019-10-24 16:26 ` [PULL 18/51] target/arm: Rebuild hflags at EL changes Peter Maydell
2019-10-24 16:26 ` [PULL 19/51] target/arm: Rebuild hflags at MSR writes Peter Maydell
2019-10-24 16:26 ` [PULL 20/51] target/arm: Rebuild hflags at CPSR writes Peter Maydell
2019-10-24 16:26 ` [PULL 21/51] target/arm: Rebuild hflags at Xscale SCTLR writes Peter Maydell
2019-10-24 16:26 ` [PULL 22/51] target/arm: Rebuild hflags for M-profile Peter Maydell
2019-10-24 16:26 ` [PULL 23/51] target/arm: Rebuild hflags for M-profile NVIC Peter Maydell
2019-10-24 16:26 ` [PULL 24/51] linux-user/aarch64: Rebuild hflags for TARGET_WORDS_BIGENDIAN Peter Maydell
2019-10-24 16:26 ` [PULL 25/51] linux-user/arm: " Peter Maydell
2019-10-24 16:26 ` [PULL 26/51] target/arm: Rely on hflags correct in cpu_get_tb_cpu_state Peter Maydell
2019-10-24 16:27 ` [PULL 27/51] hw/net/fsl_etsec/etsec.c: Switch to transaction-based ptimer API Peter Maydell
2019-10-24 16:27 ` [PULL 28/51] hw/timer/xilinx_timer.c: " Peter Maydell
2019-10-24 16:27 ` [PULL 29/51] hw/dma/xilinx_axidma.c: " Peter Maydell
2019-10-24 16:27 ` [PULL 30/51] hw/timer/slavio_timer: Remove useless check for NULL t->timer Peter Maydell
2019-10-24 16:27 ` [PULL 31/51] hw/timer/slavio_timer.c: Switch to transaction-based ptimer API Peter Maydell
2019-10-24 16:27 ` [PULL 32/51] hw/timer/grlib_gptimer.c: " Peter Maydell
2019-10-24 16:27 ` [PULL 33/51] hw/m68k/mcf5206.c: " Peter Maydell
2019-10-24 16:27 ` [PULL 34/51] hw/watchdog/milkymist-sysctl.c: " Peter Maydell
2019-10-24 16:27 ` [PULL 35/51] target/arm/monitor: Introduce qmp_query_cpu_model_expansion Peter Maydell
2019-10-24 16:27 ` Peter Maydell [this message]
2019-10-24 16:27 ` [PULL 37/51] target/arm: Allow SVE to be disabled via a CPU property Peter Maydell
2019-10-24 16:27 ` [PULL 38/51] target/arm/cpu64: max cpu: Introduce sve<N> properties Peter Maydell
2019-10-24 16:27 ` [PULL 39/51] target/arm/kvm64: Add kvm_arch_get/put_sve Peter Maydell
2019-10-24 16:27 ` [PULL 40/51] target/arm/kvm64: max cpu: Enable SVE when available Peter Maydell
2019-10-24 16:27 ` [PULL 41/51] target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features Peter Maydell
2019-10-24 16:27 ` [PULL 42/51] target/arm/cpu64: max cpu: Support sve properties with KVM Peter Maydell
2019-10-24 16:27 ` [PULL 43/51] target/arm/kvm: host cpu: Add support for sve<N> properties Peter Maydell
2019-10-24 16:27 ` [PULL 44/51] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor Peter Maydell
2019-10-24 16:27 ` [PULL 45/51] hw/arm/bcm2835_peripherals: Use the thermal sensor block Peter Maydell
2019-10-24 16:27 ` [PULL 46/51] hw/timer/bcm2835: Add the BCM2835 SYS_timer Peter Maydell
2019-10-24 16:27 ` [PULL 47/51] hw/arm/bcm2835_peripherals: Use the SYS_timer Peter Maydell
2019-10-24 16:27 ` [PULL 48/51] hw/arm/bcm2836: Make the SoC code modular Peter Maydell
2019-10-24 16:27 ` [PULL 49/51] hw/arm/bcm2836: Rename cpus[] as cpu[].core Peter Maydell
2019-10-24 16:27 ` [PULL 50/51] hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot Peter Maydell
2019-10-24 16:27 ` [PULL 51/51] hw/arm/highbank: Use AddressSpace when using write_secondary_boot() Peter Maydell
2019-10-24 18:18 ` [PULL 00/51] target-arm queue Philippe Mathieu-Daudé
2019-10-24 19:29   ` Mark Cave-Ayland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191024162724.31675-37-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.