mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
Qtest pull request
- RISCV CSR test - migration recover changed to OOB - removal of dead code in test-x86-cpuid-compat -----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmeKbx4QHGZhcm9zYXNA c3VzZS5kZQAKCRDHmNx0G+wxnRD7D/9v4ovvGn/IwSXjjpOpkjhCSgV8TMi1F61P hqB5TTCY8yejvT7JauplMUHmcJsVCNx+HF36D+YjxBjqrhQE8vzPRXgcLxHL9RX4 Kwgdk24kFKADE3gsiys9gOpwRhmtY0/2CT5LvitfJRMxUNPtm0Mr7qM3Z0Taeusu lxZgIMTBeNakpY5vua8nlLQ4r+/Df6S3TFFAaQ4UYab/T5zHVcjKaySXDlT1QXpp M+Be21jPxuUYJnKCSxMCUtuY9wkSPcITzJW91V+JxL9STSpsKpnQe10JWDRbwLBt /am2Jg5f8iFEblCwr5aQRMwXB+e/Y7K4qKPOUalj+weGnCXh9DmWPXnV6qzdZNO8 sePKoFj1AMtqbVf3iOpDBRkH8dECiDh1jHmflW1grF0BuOwOw8dKYW+i2qz9ZDiW rKWKfRcZZ059aOCQWqpMC9TGQ8osMC/v6GGJwiPBDLapGjnAm5d1683w4Z1l8tAg vf9yti2mpzK15PB6doEj/IuZr8WKWFMklizmMMZpXgHIUpjtm3JFKXX/jGHcD3KU E8F4ns3zPMlq7ncIwc6GADRB3XzEuzzuXAaEO8HMN0fYHevfnFIon749udyBDI/n a1/CTzTmchItwzgpdvcoiKO6gkg6DO9n08QULCMPSVCtl5KAlz5yuwxWGI/rM6u7 ixPi8i24oA== =i4AD -----END PGP SIGNATURE----- Merge tag 'qtest-20250117-pull-request' of https://gitlab.com/farosas/qemu into staging Qtest pull request - RISCV CSR test - migration recover changed to OOB - removal of dead code in test-x86-cpuid-compat # -----BEGIN PGP SIGNATURE----- # # iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmeKbx4QHGZhcm9zYXNA # c3VzZS5kZQAKCRDHmNx0G+wxnRD7D/9v4ovvGn/IwSXjjpOpkjhCSgV8TMi1F61P # hqB5TTCY8yejvT7JauplMUHmcJsVCNx+HF36D+YjxBjqrhQE8vzPRXgcLxHL9RX4 # Kwgdk24kFKADE3gsiys9gOpwRhmtY0/2CT5LvitfJRMxUNPtm0Mr7qM3Z0Taeusu # lxZgIMTBeNakpY5vua8nlLQ4r+/Df6S3TFFAaQ4UYab/T5zHVcjKaySXDlT1QXpp # M+Be21jPxuUYJnKCSxMCUtuY9wkSPcITzJW91V+JxL9STSpsKpnQe10JWDRbwLBt # /am2Jg5f8iFEblCwr5aQRMwXB+e/Y7K4qKPOUalj+weGnCXh9DmWPXnV6qzdZNO8 # sePKoFj1AMtqbVf3iOpDBRkH8dECiDh1jHmflW1grF0BuOwOw8dKYW+i2qz9ZDiW # rKWKfRcZZ059aOCQWqpMC9TGQ8osMC/v6GGJwiPBDLapGjnAm5d1683w4Z1l8tAg # vf9yti2mpzK15PB6doEj/IuZr8WKWFMklizmMMZpXgHIUpjtm3JFKXX/jGHcD3KU # E8F4ns3zPMlq7ncIwc6GADRB3XzEuzzuXAaEO8HMN0fYHevfnFIon749udyBDI/n # a1/CTzTmchItwzgpdvcoiKO6gkg6DO9n08QULCMPSVCtl5KAlz5yuwxWGI/rM6u7 # ixPi8i24oA== # =i4AD # -----END PGP SIGNATURE----- # gpg: Signature made Fri 17 Jan 2025 09:54:22 EST # gpg: using RSA key AA1B48B0A22326A5A4C364CFC798DC741BEC319D # gpg: issuer "farosas@suse.de" # gpg: Good signature from "Fabiano Rosas <farosas@suse.de>" [unknown] # gpg: aka "Fabiano Almeida Rosas <fabiano.rosas@suse.com>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: AA1B 48B0 A223 26A5 A4C3 64CF C798 DC74 1BEC 319D * tag 'qtest-20250117-pull-request' of https://gitlab.com/farosas/qemu: tests/qtest/test-x86-cpuid-compat: Remove tests related to pc-i440fx-2.3 tests/qtest/migration: Use out-of-band execution for migrate-recover tests/qtest: Introduce qtest_init_with_env_and_capabilities() tests/qtest: QTest example for RISC-V CSR register target/riscv: Add RISC-V CSR qtest support Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
20fac491cf
9 changed files with 210 additions and 24 deletions
|
@ -22,6 +22,8 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "system/reset.h"
|
||||
#include "system/qtest.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "target/riscv/cpu.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
|
@ -41,6 +43,55 @@ static void riscv_harts_cpu_reset(void *opaque)
|
|||
cpu_reset(CPU(cpu));
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void csr_call(char *cmd, uint64_t cpu_num, int csrno, uint64_t *val)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(cpu_num));
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
int ret = RISCV_EXCP_NONE;
|
||||
if (strcmp(cmd, "get_csr") == 0) {
|
||||
ret = riscv_csrr(env, csrno, (target_ulong *)val);
|
||||
} else if (strcmp(cmd, "set_csr") == 0) {
|
||||
ret = riscv_csrrw(env, csrno, NULL, *(target_ulong *)val,
|
||||
MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
|
||||
}
|
||||
|
||||
g_assert(ret == RISCV_EXCP_NONE);
|
||||
}
|
||||
|
||||
static bool csr_qtest_callback(CharBackend *chr, gchar **words)
|
||||
{
|
||||
if (strcmp(words[0], "csr") == 0) {
|
||||
|
||||
uint64_t cpu;
|
||||
uint64_t val;
|
||||
int rc, csr;
|
||||
|
||||
rc = qemu_strtou64(words[2], NULL, 0, &cpu);
|
||||
g_assert(rc == 0);
|
||||
rc = qemu_strtoi(words[3], NULL, 0, &csr);
|
||||
g_assert(rc == 0);
|
||||
rc = qemu_strtou64(words[4], NULL, 0, &val);
|
||||
g_assert(rc == 0);
|
||||
csr_call(words[1], cpu, csr, &val);
|
||||
|
||||
qtest_send_prefix(chr);
|
||||
qtest_sendf(chr, "OK 0 "TARGET_FMT_lx"\n", (target_ulong)val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void riscv_cpu_register_csr_qtest_callback(void)
|
||||
{
|
||||
static GOnce once;
|
||||
g_once(&once, (GThreadFunc)qtest_set_command_cb, csr_qtest_callback);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
|
||||
char *cpu_type, Error **errp)
|
||||
{
|
||||
|
@ -58,6 +109,10 @@ static void riscv_harts_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
s->harts = g_new0(RISCVCPU, s->num_harts);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
riscv_cpu_register_csr_qtest_callback();
|
||||
#endif
|
||||
|
||||
for (n = 0; n < s->num_harts; n++) {
|
||||
if (!riscv_hart_realize(s, n, s->cpu_type, errp)) {
|
||||
return;
|
||||
|
|
|
@ -543,7 +543,9 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
|
|||
return qtest_init_internal(qtest_qemu_binary(NULL), extra_args);
|
||||
}
|
||||
|
||||
QTestState *qtest_init_with_env(const char *var, const char *extra_args)
|
||||
QTestState *qtest_init_with_env_and_capabilities(const char *var,
|
||||
const char *extra_args,
|
||||
QList *capabilities)
|
||||
{
|
||||
QTestState *s = qtest_init_internal(qtest_qemu_binary(var), extra_args);
|
||||
QDict *greeting;
|
||||
|
@ -551,11 +553,23 @@ QTestState *qtest_init_with_env(const char *var, const char *extra_args)
|
|||
/* Read the QMP greeting and then do the handshake */
|
||||
greeting = qtest_qmp_receive(s);
|
||||
qobject_unref(greeting);
|
||||
qobject_unref(qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }"));
|
||||
if (capabilities) {
|
||||
qtest_qmp_assert_success(s,
|
||||
"{ 'execute': 'qmp_capabilities', "
|
||||
"'arguments': { 'enable': %p } }",
|
||||
qobject_ref(capabilities));
|
||||
} else {
|
||||
qtest_qmp_assert_success(s, "{ 'execute': 'qmp_capabilities' }");
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
QTestState *qtest_init_with_env(const char *var, const char *extra_args)
|
||||
{
|
||||
return qtest_init_with_env_and_capabilities(var, extra_args, NULL);
|
||||
}
|
||||
|
||||
QTestState *qtest_init(const char *extra_args)
|
||||
{
|
||||
return qtest_init_with_env(NULL, extra_args);
|
||||
|
@ -1218,6 +1232,33 @@ uint64_t qtest_rtas_call(QTestState *s, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void qtest_rsp_csr(QTestState *s, uint64_t *val)
|
||||
{
|
||||
gchar **args;
|
||||
uint64_t ret;
|
||||
int rc;
|
||||
|
||||
args = qtest_rsp_args(s, 3);
|
||||
|
||||
rc = qemu_strtou64(args[1], NULL, 16, &ret);
|
||||
g_assert(rc == 0);
|
||||
rc = qemu_strtou64(args[2], NULL, 16, val);
|
||||
g_assert(rc == 0);
|
||||
|
||||
g_strfreev(args);
|
||||
}
|
||||
|
||||
uint64_t qtest_csr_call(QTestState *s, const char *name,
|
||||
uint64_t cpu, int csr,
|
||||
uint64_t *val)
|
||||
{
|
||||
qtest_sendf(s, "csr %s 0x%"PRIx64" %d 0x%"PRIx64"\n",
|
||||
name, cpu, csr, *val);
|
||||
|
||||
qtest_rsp_csr(s, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qtest_add_func(const char *str, void (*fn)(void))
|
||||
{
|
||||
gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "qapi/qmp/qobject.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
#include "libqmp.h"
|
||||
|
||||
typedef struct QTestState QTestState;
|
||||
|
@ -68,6 +69,22 @@ QTestState *qtest_init(const char *extra_args);
|
|||
*/
|
||||
QTestState *qtest_init_with_env(const char *var, const char *extra_args);
|
||||
|
||||
/**
|
||||
* qtest_init_with_env_and_capabilities:
|
||||
* @var: Environment variable from where to take the QEMU binary
|
||||
* @extra_args: Other arguments to pass to QEMU. CAUTION: these
|
||||
* arguments are subject to word splitting and shell evaluation.
|
||||
* @capabilities: list of QMP capabilities (strings) to enable
|
||||
*
|
||||
* Like qtest_init_with_env(), but enable specified capabilities during
|
||||
* hadshake.
|
||||
*
|
||||
* Returns: #QTestState instance.
|
||||
*/
|
||||
QTestState *qtest_init_with_env_and_capabilities(const char *var,
|
||||
const char *extra_args,
|
||||
QList *capabilities);
|
||||
|
||||
/**
|
||||
* qtest_init_without_qmp_handshake:
|
||||
* @extra_args: other arguments to pass to QEMU. CAUTION: these
|
||||
|
@ -600,6 +617,20 @@ uint64_t qtest_rtas_call(QTestState *s, const char *name,
|
|||
uint32_t nargs, uint64_t args,
|
||||
uint32_t nret, uint64_t ret);
|
||||
|
||||
/**
|
||||
* qtest_csr_call:
|
||||
* @s: #QTestState instance to operate on.
|
||||
* @name: name of the command to call.
|
||||
* @cpu: hart number.
|
||||
* @csr: CSR number.
|
||||
* @val: Value for reading/writing.
|
||||
*
|
||||
* Call an RISC-V CSR read/write function
|
||||
*/
|
||||
uint64_t qtest_csr_call(QTestState *s, const char *name,
|
||||
uint64_t cpu, int csr,
|
||||
uint64_t *val);
|
||||
|
||||
/**
|
||||
* qtest_bufread:
|
||||
* @s: #QTestState instance to operate on.
|
||||
|
|
|
@ -274,7 +274,7 @@ qtests_s390x = \
|
|||
qtests_riscv32 = \
|
||||
(config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? ['sifive-e-aon-watchdog-test'] : [])
|
||||
|
||||
qtests_riscv64 = \
|
||||
qtests_riscv64 = ['riscv-csr-test'] + \
|
||||
(unpack_edk2_blobs ? ['bios-tables-test'] : [])
|
||||
|
||||
qos_test_ss = ss.source_set()
|
||||
|
|
|
@ -194,6 +194,16 @@ static void cleanup(const char *filename)
|
|||
unlink(path);
|
||||
}
|
||||
|
||||
static QList *migrate_start_get_qmp_capabilities(const MigrateStart *args)
|
||||
{
|
||||
QList *capabilities = qlist_new();
|
||||
|
||||
if (args->oob) {
|
||||
qlist_append_str(capabilities, "oob");
|
||||
}
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
int migrate_start(QTestState **from, QTestState **to, const char *uri,
|
||||
MigrateStart *args)
|
||||
{
|
||||
|
@ -210,6 +220,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
|
|||
const char *machine_alias, *machine_opts = "";
|
||||
g_autofree char *machine = NULL;
|
||||
const char *bootpath;
|
||||
g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
|
||||
|
||||
if (args->use_shmem) {
|
||||
if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
|
||||
|
@ -314,7 +325,8 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
|
|||
args->opts_source ? args->opts_source : "",
|
||||
ignore_stderr);
|
||||
if (!args->only_target) {
|
||||
*from = qtest_init_with_env(QEMU_ENV_SRC, cmd_source);
|
||||
*from = qtest_init_with_env_and_capabilities(QEMU_ENV_SRC, cmd_source,
|
||||
capabilities);
|
||||
qtest_qmp_set_event_callback(*from,
|
||||
migrate_watch_for_events,
|
||||
&src_state);
|
||||
|
@ -334,7 +346,8 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
|
|||
shmem_opts ? shmem_opts : "",
|
||||
args->opts_target ? args->opts_target : "",
|
||||
ignore_stderr);
|
||||
*to = qtest_init_with_env(QEMU_ENV_DST, cmd_target);
|
||||
*to = qtest_init_with_env_and_capabilities(QEMU_ENV_DST, cmd_target,
|
||||
capabilities);
|
||||
qtest_qmp_set_event_callback(*to,
|
||||
migrate_watch_for_events,
|
||||
&dst_state);
|
||||
|
@ -601,6 +614,12 @@ void test_postcopy_recovery_common(MigrateCommon *args)
|
|||
QTestState *from, *to;
|
||||
g_autofree char *uri = NULL;
|
||||
|
||||
/*
|
||||
* Always enable OOB QMP capability for recovery tests, migrate-recover is
|
||||
* executed out-of-band
|
||||
*/
|
||||
args->start.oob = true;
|
||||
|
||||
/* Always hide errors for postcopy recover tests since they're expected */
|
||||
args->start.hide_stderr = true;
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ typedef struct {
|
|||
const char *opts_target;
|
||||
/* suspend the src before migrating to dest. */
|
||||
bool suspend_me;
|
||||
/* enable OOB QMP capability */
|
||||
bool oob;
|
||||
} MigrateStart;
|
||||
|
||||
typedef enum PostcopyRecoveryFailStage {
|
||||
|
|
|
@ -464,7 +464,7 @@ void migrate_continue(QTestState *who, const char *state)
|
|||
void migrate_recover(QTestState *who, const char *uri)
|
||||
{
|
||||
qtest_qmp_assert_success(who,
|
||||
"{ 'execute': 'migrate-recover', "
|
||||
"{ 'exec-oob': 'migrate-recover', "
|
||||
" 'id': 'recover-cmd', "
|
||||
" 'arguments': { 'uri': %s } }",
|
||||
uri);
|
||||
|
|
56
tests/qtest/riscv-csr-test.c
Normal file
56
tests/qtest/riscv-csr-test.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* QTest testcase for RISC-V CSRs
|
||||
*
|
||||
* Copyright (c) 2024 Syntacore.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "libqtest.h"
|
||||
|
||||
#define CSR_MVENDORID 0xf11
|
||||
#define CSR_MISELECT 0x350
|
||||
|
||||
static void run_test_csr(void)
|
||||
{
|
||||
uint64_t res;
|
||||
uint64_t val = 0;
|
||||
|
||||
QTestState *qts = qtest_init("-machine virt -cpu veyron-v1");
|
||||
|
||||
res = qtest_csr_call(qts, "get_csr", 0, CSR_MVENDORID, &val);
|
||||
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(val, ==, 0x61f);
|
||||
|
||||
val = 0xff;
|
||||
res = qtest_csr_call(qts, "set_csr", 0, CSR_MISELECT, &val);
|
||||
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
|
||||
val = 0;
|
||||
res = qtest_csr_call(qts, "get_csr", 0, CSR_MISELECT, &val);
|
||||
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert_cmpint(val, ==, 0xff);
|
||||
|
||||
qtest_quit(qts);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
qtest_add_func("/cpu/csr", run_test_csr);
|
||||
|
||||
return g_test_run();
|
||||
}
|
|
@ -357,19 +357,6 @@ int main(int argc, char **argv)
|
|||
"486", "xstore=on", "pc-i440fx-2.7",
|
||||
"xlevel2", 0);
|
||||
}
|
||||
/*
|
||||
* QEMU 2.3.0 had auto-level enabled for CPUID[7], already,
|
||||
* and the compat code that sets default level shouldn't
|
||||
* disable the auto-level=7 code:
|
||||
*/
|
||||
if (qtest_has_machine("pc-i440fx-2.3")) {
|
||||
add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.3/off",
|
||||
"Penryn", NULL, "pc-i440fx-2.3",
|
||||
"level", 4);
|
||||
add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.3/on",
|
||||
"Penryn", "erms=on", "pc-i440fx-2.3",
|
||||
"level", 7);
|
||||
}
|
||||
if (qtest_has_machine("pc-i440fx-2.9")) {
|
||||
add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.9/off",
|
||||
"Conroe", NULL, "pc-i440fx-2.9",
|
||||
|
@ -384,11 +371,6 @@ int main(int argc, char **argv)
|
|||
* code on old machine-types. Just check that the compat code
|
||||
* is working correctly:
|
||||
*/
|
||||
if (qtest_has_machine("pc-i440fx-2.3")) {
|
||||
add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.3",
|
||||
"SandyBridge", NULL, "pc-i440fx-2.3",
|
||||
"xlevel", 0x8000000a);
|
||||
}
|
||||
if (qtest_has_machine("pc-i440fx-2.4")) {
|
||||
add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-off",
|
||||
"SandyBridge", NULL, "pc-i440fx-2.4",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue