2004-03-14 22:38:27 +01:00
|
|
|
/*
|
|
|
|
* QEMU monitor
|
2007-09-16 23:08:06 +02:00
|
|
|
*
|
2004-03-14 22:38:27 +01:00
|
|
|
* Copyright (c) 2003-2004 Fabrice Bellard
|
2007-09-16 23:08:06 +02:00
|
|
|
*
|
2004-03-14 22:38:27 +01:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
2018-02-01 12:18:31 +01:00
|
|
|
|
2016-01-29 18:50:05 +01:00
|
|
|
#include "qemu/osdep.h"
|
2019-06-13 17:33:59 +02:00
|
|
|
#include "monitor-internal.h"
|
2013-02-04 11:37:52 +01:00
|
|
|
#include "monitor/qdev.h"
|
2012-12-17 18:19:49 +01:00
|
|
|
#include "exec/gdbstub.h"
|
2009-11-25 19:48:54 +01:00
|
|
|
#include "net/slirp.h"
|
2012-10-24 11:12:21 +02:00
|
|
|
#include "disas/disas.h"
|
2022-02-07 09:27:56 +01:00
|
|
|
#include "qemu/log.h"
|
2017-01-10 11:59:55 +01:00
|
|
|
#include "sysemu/hw_accel.h"
|
2019-06-19 22:10:44 +02:00
|
|
|
#include "sysemu/sysemu.h"
|
2022-09-26 19:38:40 +02:00
|
|
|
#include "sysemu/device_tree.h"
|
2018-02-01 12:18:39 +01:00
|
|
|
#include "qapi/qmp/qdict.h"
|
2015-03-17 17:22:46 +01:00
|
|
|
#include "qapi/qmp/qerror.h"
|
2015-09-10 17:38:59 +02:00
|
|
|
#include "monitor/hmp-target.h"
|
2019-06-19 22:10:36 +02:00
|
|
|
#include "monitor/hmp.h"
|
2023-01-24 13:19:15 +01:00
|
|
|
#include "exec/address-spaces.h"
|
|
|
|
#include "exec/ioport.h"
|
2020-03-08 10:24:32 +01:00
|
|
|
#include "block/block-hmp-cmds.h"
|
2020-01-29 11:22:37 +01:00
|
|
|
#include "qapi/qapi-commands-control.h"
|
2019-11-20 19:25:48 +01:00
|
|
|
#include "qapi/qapi-commands-misc.h"
|
2021-09-08 11:35:43 +02:00
|
|
|
#include "qapi/qapi-commands-machine.h"
|
2019-11-20 19:25:48 +01:00
|
|
|
#include "qapi/qapi-init-commands.h"
|
2018-02-01 12:18:31 +01:00
|
|
|
#include "qapi/error.h"
|
2016-03-20 18:16:19 +01:00
|
|
|
#include "qemu/cutils.h"
|
2007-12-03 18:05:38 +01:00
|
|
|
|
2015-06-26 20:07:21 +02:00
|
|
|
#if defined(TARGET_S390X)
|
|
|
|
#include "hw/s390x/storage-keys.h"
|
2016-08-15 18:44:04 +02:00
|
|
|
#include "hw/s390x/storage-attributes.h"
|
2015-06-26 20:07:21 +02:00
|
|
|
#endif
|
|
|
|
|
2022-05-11 01:54:39 +02:00
|
|
|
/* Make devices configuration available for use in hmp-commands*.hx templates */
|
|
|
|
#include CONFIG_DEVICES
|
|
|
|
|
2019-06-13 17:33:56 +02:00
|
|
|
static HMPCommand hmp_info_cmds[];
|
2004-03-14 22:38:27 +01:00
|
|
|
|
2011-11-25 20:52:45 +01:00
|
|
|
char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
|
|
|
|
int64_t cpu_index, Error **errp)
|
2010-10-22 14:08:02 +02:00
|
|
|
{
|
2011-11-25 20:52:45 +01:00
|
|
|
char *output = NULL;
|
2019-06-13 17:33:54 +02:00
|
|
|
MonitorHMP hmp = {};
|
2010-10-22 14:08:02 +02:00
|
|
|
|
2019-06-13 17:34:03 +02:00
|
|
|
monitor_data_init(&hmp.common, false, true, false);
|
2010-10-22 14:08:02 +02:00
|
|
|
|
2011-11-25 20:52:45 +01:00
|
|
|
if (has_cpu_index) {
|
2020-10-05 17:58:42 +02:00
|
|
|
int ret = monitor_set_cpu(&hmp.common, cpu_index);
|
2010-10-22 14:08:02 +02:00
|
|
|
if (ret < 0) {
|
2015-03-17 11:54:50 +01:00
|
|
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
|
|
|
|
"a CPU number");
|
2010-10-22 14:08:02 +02:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-06 19:12:36 +01:00
|
|
|
handle_hmp_command(&hmp, command_line);
|
2010-10-22 14:08:02 +02:00
|
|
|
|
2020-09-22 11:57:41 +02:00
|
|
|
WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) {
|
2020-12-11 18:11:34 +01:00
|
|
|
output = g_strdup(hmp.common.outbuf->str);
|
2010-10-22 14:08:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2019-06-13 17:33:54 +02:00
|
|
|
monitor_data_destroy(&hmp.common);
|
2011-11-25 20:52:45 +01:00
|
|
|
return output;
|
2010-10-22 14:08:02 +02:00
|
|
|
}
|
|
|
|
|
2019-06-13 17:34:01 +02:00
|
|
|
/**
|
|
|
|
* Is @name in the '|' separated list of names @list?
|
|
|
|
*/
|
|
|
|
int hmp_compare_cmd(const char *name, const char *list)
|
2004-03-14 22:38:27 +01:00
|
|
|
{
|
|
|
|
const char *p, *pstart;
|
|
|
|
int len;
|
|
|
|
len = strlen(name);
|
|
|
|
p = list;
|
2019-06-13 17:34:01 +02:00
|
|
|
for (;;) {
|
2004-03-14 22:38:27 +01:00
|
|
|
pstart = p;
|
2018-06-29 12:32:10 +02:00
|
|
|
p = qemu_strchrnul(p, '|');
|
2019-06-13 17:34:01 +02:00
|
|
|
if ((p - pstart) == len && !memcmp(pstart, name, len)) {
|
2004-03-14 22:38:27 +01:00
|
|
|
return 1;
|
2013-08-27 14:38:21 +02:00
|
|
|
}
|
|
|
|
if (*p == '\0') {
|
|
|
|
break;
|
|
|
|
}
|
2019-06-13 17:34:01 +02:00
|
|
|
p++;
|
2013-08-27 14:38:21 +02:00
|
|
|
}
|
2013-08-27 14:38:22 +02:00
|
|
|
return 0;
|
2004-03-14 22:38:27 +01:00
|
|
|
}
|
|
|
|
|
2009-08-28 20:27:13 +02:00
|
|
|
static void do_help_cmd(Monitor *mon, const QDict *qdict)
|
2009-08-28 20:27:08 +02:00
|
|
|
{
|
2023-01-24 13:19:21 +01:00
|
|
|
hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
|
2009-08-28 20:27:08 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_info_help(Monitor *mon, const QDict *qdict)
|
2004-03-14 22:38:27 +01:00
|
|
|
{
|
2023-01-24 13:19:21 +01:00
|
|
|
hmp_help_cmd(mon, "info");
|
2004-03-14 22:38:27 +01:00
|
|
|
}
|
|
|
|
|
2018-03-09 09:59:50 +01:00
|
|
|
static void monitor_init_qmp_commands(void)
|
2016-09-12 11:19:00 +02:00
|
|
|
{
|
qmp: Clean up how we enforce capability negotiation
To enforce capability negotiation before normal operation,
handle_qmp_command() inspects every command before it's handed off to
qmp_dispatch(). This is a bit of a layering violation, and results in
duplicated code.
Before capability negotiation (!cur_mon->in_command_mode), we fail
commands other than "qmp_capabilities". This is what enforces
capability negotiation.
Afterwards, we fail command "qmp_capabilities".
Clean this up as follows.
The obvious place to fail a command is the command itself, so move the
"afterwards" check to qmp_qmp_capabilities().
We do the "before" check in every other command, but that would be
bothersome. Instead, start with an alternate list of commands that
contains only "qmp_capabilities". Switch to the full list in
qmp_qmp_capabilities().
Additionally, replace the generic human-readable error message for
CommandNotFound by one that reminds the user to run qmp_capabilities.
Without that, we'd regress commit 2d5a834.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1488544368-30622-8-git-send-email-armbru@redhat.com>
[Mirco-optimization squashed in, commit message typo fixed]
Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-03 13:32:27 +01:00
|
|
|
/*
|
|
|
|
* Two command lists:
|
|
|
|
* - qmp_commands contains all QMP commands
|
|
|
|
* - qmp_cap_negotiation_commands contains just
|
|
|
|
* "qmp_capabilities", to enforce capability negotiation
|
|
|
|
*/
|
|
|
|
|
2017-03-03 13:32:25 +01:00
|
|
|
qmp_init_marshal(&qmp_commands);
|
2017-03-03 13:32:24 +01:00
|
|
|
|
2021-10-28 12:25:17 +02:00
|
|
|
qmp_register_command(&qmp_commands, "device_add",
|
|
|
|
qmp_device_add, 0, 0);
|
2016-09-12 11:19:02 +02:00
|
|
|
|
qmp: Clean up how we enforce capability negotiation
To enforce capability negotiation before normal operation,
handle_qmp_command() inspects every command before it's handed off to
qmp_dispatch(). This is a bit of a layering violation, and results in
duplicated code.
Before capability negotiation (!cur_mon->in_command_mode), we fail
commands other than "qmp_capabilities". This is what enforces
capability negotiation.
Afterwards, we fail command "qmp_capabilities".
Clean this up as follows.
The obvious place to fail a command is the command itself, so move the
"afterwards" check to qmp_qmp_capabilities().
We do the "before" check in every other command, but that would be
bothersome. Instead, start with an alternate list of commands that
contains only "qmp_capabilities". Switch to the full list in
qmp_qmp_capabilities().
Additionally, replace the generic human-readable error message for
CommandNotFound by one that reminds the user to run qmp_capabilities.
Without that, we'd regress commit 2d5a834.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1488544368-30622-8-git-send-email-armbru@redhat.com>
[Mirco-optimization squashed in, commit message typo fixed]
Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-03 13:32:27 +01:00
|
|
|
QTAILQ_INIT(&qmp_cap_negotiation_commands);
|
|
|
|
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
|
2021-10-28 12:25:17 +02:00
|
|
|
qmp_marshal_qmp_capabilities,
|
|
|
|
QCO_ALLOW_PRECONFIG, 0);
|
qmp: Clean up how we enforce capability negotiation
To enforce capability negotiation before normal operation,
handle_qmp_command() inspects every command before it's handed off to
qmp_dispatch(). This is a bit of a layering violation, and results in
duplicated code.
Before capability negotiation (!cur_mon->in_command_mode), we fail
commands other than "qmp_capabilities". This is what enforces
capability negotiation.
Afterwards, we fail command "qmp_capabilities".
Clean this up as follows.
The obvious place to fail a command is the command itself, so move the
"afterwards" check to qmp_qmp_capabilities().
We do the "before" check in every other command, but that would be
bothersome. Instead, start with an alternate list of commands that
contains only "qmp_capabilities". Switch to the full list in
qmp_qmp_capabilities().
Additionally, replace the generic human-readable error message for
CommandNotFound by one that reminds the user to run qmp_capabilities.
Without that, we'd regress commit 2d5a834.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1488544368-30622-8-git-send-email-armbru@redhat.com>
[Mirco-optimization squashed in, commit message typo fixed]
Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-03 13:32:27 +01:00
|
|
|
}
|
|
|
|
|
2018-06-08 05:55:07 +02:00
|
|
|
/* Set the current CPU defined by the user. Callers must hold BQL. */
|
2020-10-05 17:58:42 +02:00
|
|
|
int monitor_set_cpu(Monitor *mon, int cpu_index)
|
2005-11-22 00:25:50 +01:00
|
|
|
{
|
2012-12-17 06:18:02 +01:00
|
|
|
CPUState *cpu;
|
2005-11-22 00:25:50 +01:00
|
|
|
|
2013-02-15 17:01:09 +01:00
|
|
|
cpu = qemu_get_cpu(cpu_index);
|
|
|
|
if (cpu == NULL) {
|
|
|
|
return -1;
|
2005-11-22 00:25:50 +01:00
|
|
|
}
|
2020-10-05 17:58:42 +02:00
|
|
|
g_free(mon->mon_cpu_path);
|
|
|
|
mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
|
2013-02-15 17:01:09 +01:00
|
|
|
return 0;
|
2005-11-22 00:25:50 +01:00
|
|
|
}
|
|
|
|
|
2018-06-08 05:55:07 +02:00
|
|
|
/* Callers must hold BQL. */
|
2020-10-05 17:58:43 +02:00
|
|
|
static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
|
2005-11-22 00:25:50 +01:00
|
|
|
{
|
2019-10-04 13:18:20 +02:00
|
|
|
CPUState *cpu = NULL;
|
2017-10-17 10:16:22 +02:00
|
|
|
|
2020-10-05 17:58:43 +02:00
|
|
|
if (mon->mon_cpu_path) {
|
|
|
|
cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
|
2017-10-17 10:16:22 +02:00
|
|
|
TYPE_CPU, NULL);
|
|
|
|
if (!cpu) {
|
2020-10-05 17:58:43 +02:00
|
|
|
g_free(mon->mon_cpu_path);
|
|
|
|
mon->mon_cpu_path = NULL;
|
2017-10-17 10:16:22 +02:00
|
|
|
}
|
|
|
|
}
|
2020-10-05 17:58:43 +02:00
|
|
|
if (!mon->mon_cpu_path) {
|
2017-01-13 13:12:35 +01:00
|
|
|
if (!first_cpu) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-10-05 17:58:43 +02:00
|
|
|
monitor_set_cpu(mon, first_cpu->cpu_index);
|
2017-10-17 10:16:22 +02:00
|
|
|
cpu = first_cpu;
|
2005-11-22 00:25:50 +01:00
|
|
|
}
|
2019-10-04 13:18:20 +02:00
|
|
|
assert(cpu != NULL);
|
2018-02-16 17:08:41 +01:00
|
|
|
if (synchronize) {
|
|
|
|
cpu_synchronize_state(cpu);
|
|
|
|
}
|
2017-10-17 10:16:22 +02:00
|
|
|
return cpu;
|
2015-05-24 23:20:40 +02:00
|
|
|
}
|
|
|
|
|
2020-11-13 12:43:24 +01:00
|
|
|
CPUState *mon_get_cpu(Monitor *mon)
|
2018-02-16 17:08:41 +01:00
|
|
|
{
|
2020-11-13 12:43:24 +01:00
|
|
|
return mon_get_cpu_sync(mon, true);
|
2018-02-16 17:08:41 +01:00
|
|
|
}
|
|
|
|
|
hmp: Pass monitor to mon_get_cpu_env()
mon_get_cpu_env() is indirectly called monitor_parse_arguments() where
the current monitor isn't set yet. Instead of using monitor_cur_env(),
explicitly pass the Monitor pointer to the function.
Without this fix, an HMP command like "x $pc" crashes like this:
#0 0x0000555555caa01f in mon_get_cpu_sync (mon=0x0, synchronize=true) at ../monitor/misc.c:270
#1 0x0000555555caa141 in mon_get_cpu (mon=0x0) at ../monitor/misc.c:294
#2 0x0000555555caa158 in mon_get_cpu_env () at ../monitor/misc.c:299
#3 0x0000555555b19739 in monitor_get_pc (mon=0x555556ad2de0, md=0x5555565d2d40 <monitor_defs+1152>, val=0) at ../target/i386/monitor.c:607
#4 0x0000555555cadbec in get_monitor_def (mon=0x555556ad2de0, pval=0x7fffffffc208, name=0x7fffffffc220 "pc") at ../monitor/misc.c:1681
#5 0x000055555582ec4f in expr_unary (mon=0x555556ad2de0) at ../monitor/hmp.c:387
#6 0x000055555582edbb in expr_prod (mon=0x555556ad2de0) at ../monitor/hmp.c:421
#7 0x000055555582ee79 in expr_logic (mon=0x555556ad2de0) at ../monitor/hmp.c:455
#8 0x000055555582eefe in expr_sum (mon=0x555556ad2de0) at ../monitor/hmp.c:484
#9 0x000055555582efe8 in get_expr (mon=0x555556ad2de0, pval=0x7fffffffc418, pp=0x7fffffffc408) at ../monitor/hmp.c:511
#10 0x000055555582fcd4 in monitor_parse_arguments (mon=0x555556ad2de0, endp=0x7fffffffc890, cmd=0x555556675b50 <hmp_cmds+7920>) at ../monitor/hmp.c:876
#11 0x00005555558306a8 in handle_hmp_command (mon=0x555556ad2de0, cmdline=0x555556ada452 "$pc") at ../monitor/hmp.c:1087
#12 0x000055555582df14 in monitor_command_cb (opaque=0x555556ad2de0, cmdline=0x555556ada450 "x $pc", readline_opaque=0x0) at ../monitor/hmp.c:47
After this fix, nothing is left in monitor_parse_arguments() that can
indirectly call monitor_cur(), so the fix is complete.
Fixes: ff04108a0e36e822519c517bd3bddbc1c7747c18
Reported-by: lichun <lichun@ruijie.com.cn>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201113114326.97663-4-kwolf@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2020-11-13 12:43:26 +01:00
|
|
|
CPUArchState *mon_get_cpu_env(Monitor *mon)
|
2015-05-24 23:20:40 +02:00
|
|
|
{
|
hmp: Pass monitor to mon_get_cpu_env()
mon_get_cpu_env() is indirectly called monitor_parse_arguments() where
the current monitor isn't set yet. Instead of using monitor_cur_env(),
explicitly pass the Monitor pointer to the function.
Without this fix, an HMP command like "x $pc" crashes like this:
#0 0x0000555555caa01f in mon_get_cpu_sync (mon=0x0, synchronize=true) at ../monitor/misc.c:270
#1 0x0000555555caa141 in mon_get_cpu (mon=0x0) at ../monitor/misc.c:294
#2 0x0000555555caa158 in mon_get_cpu_env () at ../monitor/misc.c:299
#3 0x0000555555b19739 in monitor_get_pc (mon=0x555556ad2de0, md=0x5555565d2d40 <monitor_defs+1152>, val=0) at ../target/i386/monitor.c:607
#4 0x0000555555cadbec in get_monitor_def (mon=0x555556ad2de0, pval=0x7fffffffc208, name=0x7fffffffc220 "pc") at ../monitor/misc.c:1681
#5 0x000055555582ec4f in expr_unary (mon=0x555556ad2de0) at ../monitor/hmp.c:387
#6 0x000055555582edbb in expr_prod (mon=0x555556ad2de0) at ../monitor/hmp.c:421
#7 0x000055555582ee79 in expr_logic (mon=0x555556ad2de0) at ../monitor/hmp.c:455
#8 0x000055555582eefe in expr_sum (mon=0x555556ad2de0) at ../monitor/hmp.c:484
#9 0x000055555582efe8 in get_expr (mon=0x555556ad2de0, pval=0x7fffffffc418, pp=0x7fffffffc408) at ../monitor/hmp.c:511
#10 0x000055555582fcd4 in monitor_parse_arguments (mon=0x555556ad2de0, endp=0x7fffffffc890, cmd=0x555556675b50 <hmp_cmds+7920>) at ../monitor/hmp.c:876
#11 0x00005555558306a8 in handle_hmp_command (mon=0x555556ad2de0, cmdline=0x555556ada452 "$pc") at ../monitor/hmp.c:1087
#12 0x000055555582df14 in monitor_command_cb (opaque=0x555556ad2de0, cmdline=0x555556ada450 "x $pc", readline_opaque=0x0) at ../monitor/hmp.c:47
After this fix, nothing is left in monitor_parse_arguments() that can
indirectly call monitor_cur(), so the fix is complete.
Fixes: ff04108a0e36e822519c517bd3bddbc1c7747c18
Reported-by: lichun <lichun@ruijie.com.cn>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201113114326.97663-4-kwolf@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2020-11-13 12:43:26 +01:00
|
|
|
CPUState *cs = mon_get_cpu(mon);
|
2017-01-13 13:12:35 +01:00
|
|
|
|
|
|
|
return cs ? cs->env_ptr : NULL;
|
2005-11-22 00:25:50 +01:00
|
|
|
}
|
|
|
|
|
2020-10-05 17:58:43 +02:00
|
|
|
int monitor_get_cpu_index(Monitor *mon)
|
2011-10-24 14:53:44 +02:00
|
|
|
{
|
2020-10-05 17:58:43 +02:00
|
|
|
CPUState *cs = mon_get_cpu_sync(mon, false);
|
2017-01-13 13:12:35 +01:00
|
|
|
|
|
|
|
return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
|
2011-10-24 14:53:44 +02:00
|
|
|
}
|
|
|
|
|
2015-02-06 14:18:24 +01:00
|
|
|
static void hmp_info_registers(Monitor *mon, const QDict *qdict)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2017-06-08 07:41:16 +02:00
|
|
|
bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
|
2022-08-02 09:37:20 +02:00
|
|
|
int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
|
2017-06-08 07:41:16 +02:00
|
|
|
CPUState *cs;
|
2017-01-13 13:12:35 +01:00
|
|
|
|
2017-06-08 07:41:16 +02:00
|
|
|
if (all_cpus) {
|
|
|
|
CPU_FOREACH(cs) {
|
|
|
|
monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
|
2019-04-17 21:18:02 +02:00
|
|
|
cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
|
2017-06-08 07:41:16 +02:00
|
|
|
}
|
|
|
|
} else {
|
2022-08-02 09:37:20 +02:00
|
|
|
cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
|
2017-06-08 07:41:16 +02:00
|
|
|
|
|
|
|
if (!cs) {
|
2022-08-02 09:37:20 +02:00
|
|
|
if (vcpu >= 0) {
|
|
|
|
monitor_printf(mon, "CPU#%d not available\n", vcpu);
|
|
|
|
} else {
|
|
|
|
monitor_printf(mon, "No CPU available\n");
|
|
|
|
}
|
2017-06-08 07:41:16 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-02 09:37:20 +02:00
|
|
|
monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
|
2019-04-17 21:18:02 +02:00
|
|
|
cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
|
2017-01-13 13:12:35 +01:00
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
2017-08-08 19:54:42 +02:00
|
|
|
static void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
|
|
|
|
{
|
|
|
|
int64_t max = qdict_get_try_int(qdict, "max", 10);
|
|
|
|
bool mean = qdict_get_try_bool(qdict, "mean", false);
|
|
|
|
bool coalesce = !qdict_get_try_bool(qdict, "no_coalesce", false);
|
|
|
|
enum QSPSortBy sort_by;
|
|
|
|
|
|
|
|
sort_by = mean ? QSP_SORT_BY_AVG_WAIT_TIME : QSP_SORT_BY_TOTAL_WAIT_TIME;
|
2019-04-17 21:17:54 +02:00
|
|
|
qsp_report(max, sort_by, coalesce);
|
2017-08-08 19:54:42 +02:00
|
|
|
}
|
|
|
|
|
2015-02-06 14:18:24 +01:00
|
|
|
static void hmp_info_history(Monitor *mon, const QDict *qdict)
|
2004-04-04 15:07:25 +02:00
|
|
|
{
|
2019-06-13 17:33:54 +02:00
|
|
|
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
|
2004-04-04 15:07:25 +02:00
|
|
|
int i;
|
2004-08-01 23:52:19 +02:00
|
|
|
const char *str;
|
2007-09-17 10:09:54 +02:00
|
|
|
|
2019-06-13 17:33:54 +02:00
|
|
|
if (!hmp_mon->rs) {
|
2009-03-06 00:01:51 +01:00
|
|
|
return;
|
2019-06-13 17:33:54 +02:00
|
|
|
}
|
2004-08-01 23:52:19 +02:00
|
|
|
i = 0;
|
|
|
|
for(;;) {
|
2019-06-13 17:33:54 +02:00
|
|
|
str = readline_get_history(hmp_mon->rs, i);
|
|
|
|
if (!str) {
|
2004-08-01 23:52:19 +02:00
|
|
|
break;
|
2019-06-13 17:33:54 +02:00
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%d: '%s'\n", i, str);
|
2004-10-09 19:32:58 +02:00
|
|
|
i++;
|
2004-04-04 15:07:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_logfile(Monitor *mon, const QDict *qdict)
|
2007-06-30 15:53:24 +02:00
|
|
|
{
|
2016-06-15 19:27:16 +02:00
|
|
|
Error *err = NULL;
|
|
|
|
|
2022-04-17 20:29:43 +02:00
|
|
|
if (!qemu_set_log_filename(qdict_get_str(qdict, "filename"), &err)) {
|
2016-06-15 19:27:16 +02:00
|
|
|
error_report_err(err);
|
|
|
|
}
|
2007-06-30 15:53:24 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_log(Monitor *mon, const QDict *qdict)
|
2004-03-21 18:06:25 +01:00
|
|
|
{
|
|
|
|
int mask;
|
2009-08-28 20:27:13 +02:00
|
|
|
const char *items = qdict_get_str(qdict, "items");
|
2022-04-17 20:29:44 +02:00
|
|
|
Error *err = NULL;
|
2007-09-17 10:09:54 +02:00
|
|
|
|
2004-04-04 14:57:25 +02:00
|
|
|
if (!strcmp(items, "none")) {
|
2004-03-21 18:06:25 +01:00
|
|
|
mask = 0;
|
|
|
|
} else {
|
2013-02-11 17:41:22 +01:00
|
|
|
mask = qemu_str_to_log_mask(items);
|
2004-03-21 18:06:25 +01:00
|
|
|
if (!mask) {
|
2023-01-24 13:19:21 +01:00
|
|
|
hmp_help_cmd(mon, "log");
|
2004-03-21 18:06:25 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2022-04-17 20:29:44 +02:00
|
|
|
|
|
|
|
if (!qemu_set_log(mask, &err)) {
|
|
|
|
error_report_err(err);
|
|
|
|
}
|
2004-03-21 18:06:25 +01:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_gdbserver(Monitor *mon, const QDict *qdict)
|
2009-04-05 20:43:41 +02:00
|
|
|
{
|
2009-08-28 20:27:13 +02:00
|
|
|
const char *device = qdict_get_try_str(qdict, "device");
|
2020-11-25 02:45:13 +01:00
|
|
|
if (!device) {
|
2009-04-05 20:43:41 +02:00
|
|
|
device = "tcp::" DEFAULT_GDBSTUB_PORT;
|
2020-11-25 02:45:13 +01:00
|
|
|
}
|
|
|
|
|
2009-04-05 20:43:41 +02:00
|
|
|
if (gdbserver_start(device) < 0) {
|
|
|
|
monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
|
|
|
|
device);
|
|
|
|
} else if (strcmp(device, "none") == 0) {
|
2009-03-28 19:05:53 +01:00
|
|
|
monitor_printf(mon, "Disabled gdbserver\n");
|
2004-03-31 21:00:16 +02:00
|
|
|
} else {
|
2009-04-05 20:43:41 +02:00
|
|
|
monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
|
|
|
|
device);
|
2004-03-31 21:00:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-06 00:01:23 +01:00
|
|
|
static void monitor_printc(Monitor *mon, int c)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "'");
|
2004-04-04 14:57:25 +02:00
|
|
|
switch(c) {
|
|
|
|
case '\'':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\\'");
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case '\\':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\\\\");
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case '\n':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\\n");
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case '\r':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\\r");
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (c >= 32 && c <= 126) {
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%c", c);
|
2004-04-04 14:57:25 +02:00
|
|
|
} else {
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\\x%02x", c);
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "'");
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
2009-03-06 00:01:23 +01:00
|
|
|
static void memory_dump(Monitor *mon, int count, int format, int wsize,
|
2012-10-23 12:30:10 +02:00
|
|
|
hwaddr addr, int is_physical)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2010-01-12 21:27:43 +01:00
|
|
|
int l, line_size, i, max_digits, len;
|
2004-04-04 14:57:25 +02:00
|
|
|
uint8_t buf[16];
|
|
|
|
uint64_t v;
|
2020-11-13 12:43:24 +01:00
|
|
|
CPUState *cs = mon_get_cpu(mon);
|
2017-01-13 13:12:35 +01:00
|
|
|
|
|
|
|
if (!cs && (format == 'i' || !is_physical)) {
|
|
|
|
monitor_printf(mon, "Can not dump without CPU\n");
|
|
|
|
return;
|
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
|
|
|
|
if (format == 'i') {
|
2017-09-14 17:38:35 +02:00
|
|
|
monitor_disas(mon, cs, addr, count, is_physical);
|
2004-04-04 14:57:25 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = wsize * count;
|
2020-11-25 02:45:13 +01:00
|
|
|
if (wsize == 1) {
|
2004-04-04 14:57:25 +02:00
|
|
|
line_size = 8;
|
2020-11-25 02:45:13 +01:00
|
|
|
} else {
|
2004-04-04 14:57:25 +02:00
|
|
|
line_size = 16;
|
2020-11-25 02:45:13 +01:00
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
max_digits = 0;
|
|
|
|
|
|
|
|
switch(format) {
|
|
|
|
case 'o':
|
2017-06-22 13:04:16 +02:00
|
|
|
max_digits = DIV_ROUND_UP(wsize * 8, 3);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case 'x':
|
|
|
|
max_digits = (wsize * 8) / 4;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
case 'd':
|
2017-06-22 13:04:16 +02:00
|
|
|
max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
wsize = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (len > 0) {
|
2020-11-25 02:45:13 +01:00
|
|
|
if (is_physical) {
|
2023-01-10 22:29:47 +01:00
|
|
|
monitor_printf(mon, HWADDR_FMT_plx ":", addr);
|
2020-11-25 02:45:13 +01:00
|
|
|
} else {
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
|
2020-11-25 02:45:13 +01:00
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
l = len;
|
|
|
|
if (l > line_size)
|
|
|
|
l = line_size;
|
|
|
|
if (is_physical) {
|
2018-12-14 14:30:49 +01:00
|
|
|
AddressSpace *as = cs ? cs->as : &address_space_memory;
|
|
|
|
MemTxResult r = address_space_read(as, addr,
|
|
|
|
MEMTXATTRS_UNSPECIFIED, buf, l);
|
|
|
|
if (r != MEMTX_OK) {
|
|
|
|
monitor_printf(mon, " Cannot access memory\n");
|
|
|
|
break;
|
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
} else {
|
2017-01-13 13:12:35 +01:00
|
|
|
if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, " Cannot access memory\n");
|
2008-08-18 16:00:20 +02:00
|
|
|
break;
|
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
2007-09-16 23:08:06 +02:00
|
|
|
i = 0;
|
2004-04-04 14:57:25 +02:00
|
|
|
while (i < l) {
|
|
|
|
switch(wsize) {
|
|
|
|
default:
|
|
|
|
case 1:
|
2015-01-20 16:19:32 +01:00
|
|
|
v = ldub_p(buf + i);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 2:
|
2015-01-20 16:19:32 +01:00
|
|
|
v = lduw_p(buf + i);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 4:
|
2015-01-20 16:19:32 +01:00
|
|
|
v = (uint32_t)ldl_p(buf + i);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 8:
|
2015-01-20 16:19:32 +01:00
|
|
|
v = ldq_p(buf + i);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, " ");
|
2004-04-04 14:57:25 +02:00
|
|
|
switch(format) {
|
|
|
|
case 'o':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%#*" PRIo64, max_digits, v);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'x':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'u':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%*" PRIu64, max_digits, v);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'd':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%*" PRId64, max_digits, v);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'c':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printc(mon, v);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
i += wsize;
|
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\n");
|
2004-04-04 14:57:25 +02:00
|
|
|
addr += l;
|
|
|
|
len -= l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2009-08-28 20:27:17 +02:00
|
|
|
int count = qdict_get_int(qdict, "count");
|
|
|
|
int format = qdict_get_int(qdict, "format");
|
|
|
|
int size = qdict_get_int(qdict, "size");
|
|
|
|
target_long addr = qdict_get_int(qdict, "addr");
|
|
|
|
|
2009-03-06 00:01:23 +01:00
|
|
|
memory_dump(mon, count, format, size, addr, 0);
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2009-08-28 20:27:17 +02:00
|
|
|
int count = qdict_get_int(qdict, "count");
|
|
|
|
int format = qdict_get_int(qdict, "format");
|
|
|
|
int size = qdict_get_int(qdict, "size");
|
2012-10-23 12:30:10 +02:00
|
|
|
hwaddr addr = qdict_get_int(qdict, "addr");
|
2009-08-28 20:27:17 +02:00
|
|
|
|
2009-03-06 00:01:23 +01:00
|
|
|
memory_dump(mon, count, format, size, addr, 1);
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
2020-10-27 18:03:03 +01:00
|
|
|
void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
|
2017-04-20 15:30:58 +02:00
|
|
|
{
|
2020-10-27 18:03:03 +01:00
|
|
|
Int128 gpa_region_size;
|
2017-04-20 15:30:58 +02:00
|
|
|
MemoryRegionSection mrs = memory_region_find(get_system_memory(),
|
2020-10-27 18:03:03 +01:00
|
|
|
addr, size);
|
2017-04-20 15:30:58 +02:00
|
|
|
|
|
|
|
if (!mrs.mr) {
|
|
|
|
error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
|
|
|
|
error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr);
|
|
|
|
memory_region_unref(mrs.mr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-10-27 18:03:03 +01:00
|
|
|
gpa_region_size = int128_make64(size);
|
|
|
|
if (int128_lt(mrs.size, gpa_region_size)) {
|
|
|
|
error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
|
|
|
|
" exceeded.", addr);
|
|
|
|
memory_region_unref(mrs.mr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-04-20 15:30:58 +02:00
|
|
|
*p_mr = mrs.mr;
|
|
|
|
return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
|
|
|
|
{
|
|
|
|
hwaddr addr = qdict_get_int(qdict, "addr");
|
|
|
|
Error *local_err = NULL;
|
|
|
|
MemoryRegion *mr = NULL;
|
|
|
|
void *ptr;
|
|
|
|
|
2020-10-27 18:03:03 +01:00
|
|
|
ptr = gpa2hva(&mr, addr, 1, &local_err);
|
2017-04-20 15:30:58 +02:00
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx
|
|
|
|
" (%s) is %p\n",
|
|
|
|
addr, mr->name, ptr);
|
|
|
|
|
|
|
|
memory_region_unref(mr);
|
|
|
|
}
|
|
|
|
|
2019-04-12 17:26:52 +02:00
|
|
|
static void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
|
|
|
|
{
|
|
|
|
target_ulong addr = qdict_get_int(qdict, "addr");
|
|
|
|
MemTxAttrs attrs;
|
2020-11-13 12:43:24 +01:00
|
|
|
CPUState *cs = mon_get_cpu(mon);
|
2019-04-12 17:26:52 +02:00
|
|
|
hwaddr gpa;
|
|
|
|
|
|
|
|
if (!cs) {
|
|
|
|
monitor_printf(mon, "No cpu\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-10 20:56:20 +02:00
|
|
|
gpa = cpu_get_phys_page_attrs_debug(cs, addr & TARGET_PAGE_MASK, &attrs);
|
2019-04-12 17:26:52 +02:00
|
|
|
if (gpa == -1) {
|
|
|
|
monitor_printf(mon, "Unmapped\n");
|
|
|
|
} else {
|
|
|
|
monitor_printf(mon, "gpa: %#" HWADDR_PRIx "\n",
|
|
|
|
gpa + (addr & ~TARGET_PAGE_MASK));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-20 15:30:58 +02:00
|
|
|
#ifdef CONFIG_LINUX
|
|
|
|
static uint64_t vtop(void *ptr, Error **errp)
|
|
|
|
{
|
|
|
|
uint64_t pinfo;
|
|
|
|
uint64_t ret = -1;
|
|
|
|
uintptr_t addr = (uintptr_t) ptr;
|
2022-03-23 16:57:22 +01:00
|
|
|
uintptr_t pagesize = qemu_real_host_page_size();
|
2017-04-20 15:30:58 +02:00
|
|
|
off_t offset = addr / pagesize * sizeof(pinfo);
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = open("/proc/self/pagemap", O_RDONLY);
|
|
|
|
if (fd == -1) {
|
|
|
|
error_setg_errno(errp, errno, "Cannot open /proc/self/pagemap");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Force copy-on-write if necessary. */
|
2020-09-23 12:56:46 +02:00
|
|
|
qatomic_add((uint8_t *)ptr, 0);
|
2017-04-20 15:30:58 +02:00
|
|
|
|
|
|
|
if (pread(fd, &pinfo, sizeof(pinfo), offset) != sizeof(pinfo)) {
|
|
|
|
error_setg_errno(errp, errno, "Cannot read pagemap");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if ((pinfo & (1ull << 63)) == 0) {
|
|
|
|
error_setg(errp, "Page not present");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ret = ((pinfo & 0x007fffffffffffffull) * pagesize) | (addr & (pagesize - 1));
|
|
|
|
|
|
|
|
out:
|
|
|
|
close(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hmp_gpa2hpa(Monitor *mon, const QDict *qdict)
|
|
|
|
{
|
|
|
|
hwaddr addr = qdict_get_int(qdict, "addr");
|
|
|
|
Error *local_err = NULL;
|
|
|
|
MemoryRegion *mr = NULL;
|
|
|
|
void *ptr;
|
|
|
|
uint64_t physaddr;
|
|
|
|
|
2020-10-27 18:03:03 +01:00
|
|
|
ptr = gpa2hva(&mr, addr, 1, &local_err);
|
2017-04-20 15:30:58 +02:00
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
physaddr = vtop(ptr, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
} else {
|
|
|
|
monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx
|
|
|
|
" (%s) is 0x%" PRIx64 "\n",
|
|
|
|
addr, mr->name, (uint64_t) physaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
memory_region_unref(mr);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-08-28 20:27:17 +02:00
|
|
|
static void do_print(Monitor *mon, const QDict *qdict)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2009-08-28 20:27:17 +02:00
|
|
|
int format = qdict_get_int(qdict, "format");
|
2012-10-23 12:30:10 +02:00
|
|
|
hwaddr val = qdict_get_int(qdict, "val");
|
2009-08-28 20:27:17 +02:00
|
|
|
|
2004-04-04 14:57:25 +02:00
|
|
|
switch(format) {
|
|
|
|
case 'o':
|
2012-10-23 12:30:10 +02:00
|
|
|
monitor_printf(mon, "%#" HWADDR_PRIo, val);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'x':
|
2012-10-23 12:30:10 +02:00
|
|
|
monitor_printf(mon, "%#" HWADDR_PRIx, val);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'u':
|
2012-10-23 12:30:10 +02:00
|
|
|
monitor_printf(mon, "%" HWADDR_PRIu, val);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case 'd':
|
2012-10-23 12:30:10 +02:00
|
|
|
monitor_printf(mon, "%" HWADDR_PRId, val);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
case 'c':
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printc(mon, val);
|
2004-04-04 14:57:25 +02:00
|
|
|
break;
|
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "\n");
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_sum(Monitor *mon, const QDict *qdict)
|
2005-06-04 22:15:57 +02:00
|
|
|
{
|
|
|
|
uint32_t addr;
|
|
|
|
uint16_t sum;
|
2009-08-28 20:27:14 +02:00
|
|
|
uint32_t start = qdict_get_int(qdict, "start");
|
|
|
|
uint32_t size = qdict_get_int(qdict, "size");
|
2005-06-04 22:15:57 +02:00
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
for(addr = start; addr < (start + size); addr++) {
|
Switch non-CPU callers from ld/st*_phys to address_space_ld/st*
Switch all the uses of ld/st*_phys to address_space_ld/st*,
except for those cases where the address space is the CPU's
(ie cs->as). This was done with the following script which
generates a Coccinelle patch.
A few over-80-columns lines in the result were rewrapped by
hand where Coccinelle failed to do the wrapping automatically,
as well as one location where it didn't put a line-continuation
'\' when wrapping lines on a change made to a match inside
a macro definition.
===begin===
#!/bin/sh -e
# Usage:
# ./ldst-phys.spatch.sh > ldst-phys.spatch
# spatch -sp_file ldst-phys.spatch -dir . | sed -e '/^+/s/\t/ /g' > out.patch
# patch -p1 < out.patch
for FN in ub uw_le uw_be l_le l_be q_le q_be uw l q; do
cat <<EOF
@ cpu_matches_ld_${FN} @
expression E1,E2;
identifier as;
@@
ld${FN}_phys(E1->as,E2)
@ other_matches_ld_${FN} depends on !cpu_matches_ld_${FN} @
expression E1,E2;
@@
-ld${FN}_phys(E1,E2)
+address_space_ld${FN}(E1,E2, MEMTXATTRS_UNSPECIFIED, NULL)
EOF
done
for FN in b w_le w_be l_le l_be q_le q_be w l q; do
cat <<EOF
@ cpu_matches_st_${FN} @
expression E1,E2,E3;
identifier as;
@@
st${FN}_phys(E1->as,E2,E3)
@ other_matches_st_${FN} depends on !cpu_matches_st_${FN} @
expression E1,E2,E3;
@@
-st${FN}_phys(E1,E2,E3)
+address_space_st${FN}(E1,E2,E3, MEMTXATTRS_UNSPECIFIED, NULL)
EOF
done
===endit===
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
2015-04-26 17:49:24 +02:00
|
|
|
uint8_t val = address_space_ldub(&address_space_memory, addr,
|
|
|
|
MEMTXATTRS_UNSPECIFIED, NULL);
|
2005-06-04 22:15:57 +02:00
|
|
|
/* BSD sum algorithm ('sum' Unix command) */
|
|
|
|
sum = (sum >> 1) | (sum << 15);
|
2011-04-10 18:23:39 +02:00
|
|
|
sum += val;
|
2005-06-04 22:15:57 +02:00
|
|
|
}
|
2009-03-06 00:01:23 +01:00
|
|
|
monitor_printf(mon, "%05d\n", sum);
|
2005-06-04 22:15:57 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
|
2004-06-08 02:55:58 +02:00
|
|
|
{
|
2009-08-28 20:27:18 +02:00
|
|
|
int size = qdict_get_int(qdict, "size");
|
|
|
|
int addr = qdict_get_int(qdict, "addr");
|
|
|
|
int has_index = qdict_haskey(qdict, "index");
|
2004-06-08 02:55:58 +02:00
|
|
|
uint32_t val;
|
|
|
|
int suffix;
|
|
|
|
|
|
|
|
if (has_index) {
|
2009-08-28 20:27:18 +02:00
|
|
|
int index = qdict_get_int(qdict, "index");
|
2009-09-20 18:05:47 +02:00
|
|
|
cpu_outb(addr & IOPORTS_MASK, index & 0xff);
|
2004-06-08 02:55:58 +02:00
|
|
|
addr++;
|
|
|
|
}
|
|
|
|
addr &= 0xffff;
|
|
|
|
|
|
|
|
switch(size) {
|
|
|
|
default:
|
|
|
|
case 1:
|
2009-09-20 18:05:47 +02:00
|
|
|
val = cpu_inb(addr);
|
2004-06-08 02:55:58 +02:00
|
|
|
suffix = 'b';
|
|
|
|
break;
|
|
|
|
case 2:
|
2009-09-20 18:05:47 +02:00
|
|
|
val = cpu_inw(addr);
|
2004-06-08 02:55:58 +02:00
|
|
|
suffix = 'w';
|
|
|
|
break;
|
|
|
|
case 4:
|
2009-09-20 18:05:47 +02:00
|
|
|
val = cpu_inl(addr);
|
2004-06-08 02:55:58 +02:00
|
|
|
suffix = 'l';
|
|
|
|
break;
|
|
|
|
}
|
2020-11-25 02:45:14 +01:00
|
|
|
monitor_printf(mon, "port%c[0x%04x] = 0x%0*x\n",
|
2009-03-06 00:01:23 +01:00
|
|
|
suffix, addr, size * 2, val);
|
2004-06-08 02:55:58 +02:00
|
|
|
}
|
2004-06-04 13:06:21 +02:00
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_ioport_write(Monitor *mon, const QDict *qdict)
|
2009-07-14 10:20:11 +02:00
|
|
|
{
|
2009-08-28 20:27:17 +02:00
|
|
|
int size = qdict_get_int(qdict, "size");
|
|
|
|
int addr = qdict_get_int(qdict, "addr");
|
|
|
|
int val = qdict_get_int(qdict, "val");
|
|
|
|
|
2009-07-14 10:20:11 +02:00
|
|
|
addr &= IOPORTS_MASK;
|
|
|
|
|
|
|
|
switch (size) {
|
|
|
|
default:
|
|
|
|
case 1:
|
2009-09-20 18:05:47 +02:00
|
|
|
cpu_outb(addr, val);
|
2009-07-14 10:20:11 +02:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-09-20 18:05:47 +02:00
|
|
|
cpu_outw(addr, val);
|
2009-07-14 10:20:11 +02:00
|
|
|
break;
|
|
|
|
case 4:
|
2009-09-20 18:05:47 +02:00
|
|
|
cpu_outl(addr, val);
|
2009-07-14 10:20:11 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
static void hmp_boot_set(Monitor *mon, const QDict *qdict)
|
2008-05-04 22:11:34 +02:00
|
|
|
{
|
2014-12-03 19:20:58 +01:00
|
|
|
Error *local_err = NULL;
|
2009-08-28 20:27:13 +02:00
|
|
|
const char *bootdevice = qdict_get_str(qdict, "bootdevice");
|
2008-05-04 22:11:34 +02:00
|
|
|
|
2014-12-03 19:20:58 +01:00
|
|
|
qemu_boot_set(bootdevice, &local_err);
|
|
|
|
if (local_err) {
|
error: Use error_report_err() instead of monitor_printf()
Both error_report_err() and monitor_printf() print to the same
destination when monitor_printf() is used correctly, i.e. within an
HMP monitor. Elsewhere, monitor_printf() does nothing, while
error_report_err() reports to stderr.
Most changed functions are HMP command handlers. These should only
run within an HMP monitor. The one exception is bdrv_password_cb(),
which should also only run within an HMP monitor.
Four command handlers prefix the error message with the command name:
balloon, migrate_set_capability, migrate_set_parameter, migrate.
Pointless, drop.
Unlike monitor_printf(), error_report_err() uses the error whole
instead of just its message obtained with error_get_pretty(). This
avoids suppressing its hint (see commit 50b7b00). Example:
(qemu) device_add ivshmem,id=666
Parameter 'id' expects an identifier
Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.
Try "help device_add" for more information
The "Identifiers consist of..." line is new with this patch.
Coccinelle semantic patch:
@@
expression M, E;
@@
- monitor_printf(M, "%s\n", error_get_pretty(E));
- error_free(E);
+ error_report_err(E);
@r1@
expression M, E;
format F;
position p;
@@
- monitor_printf(M, "...%@F@\n", error_get_pretty(E));@p
- error_free(E);
+ error_report_err(E);
@script:python@
p << r1.p;
@@
print "%s:%s:%s: prefix dropped" % (p[0].file, p[0].line, p[0].column)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1450452927-8346-4-git-send-email-armbru@redhat.com>
2015-12-18 16:35:06 +01:00
|
|
|
error_report_err(local_err);
|
2008-05-04 22:11:34 +02:00
|
|
|
} else {
|
2014-12-03 19:20:58 +01:00
|
|
|
monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
|
2008-05-04 22:11:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-06 14:18:24 +01:00
|
|
|
static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
|
2011-09-11 22:22:05 +02:00
|
|
|
{
|
2017-01-16 09:40:05 +01:00
|
|
|
bool flatview = qdict_get_try_bool(qdict, "flatview", false);
|
2017-09-21 10:51:06 +02:00
|
|
|
bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
|
2018-06-04 05:25:11 +02:00
|
|
|
bool owner = qdict_get_try_bool(qdict, "owner", false);
|
memory: Make 'info mtree' not display disabled regions by default
We might have many disabled memory regions, making the 'info mtree'
output too verbose to be useful.
Remove the disabled regions in the default output, but allow the
monitor user to display them using the '-D' option.
Before:
(qemu) info mtree
memory-region: system
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): alias ram-below-4g @pc.ram 0000000000000000-0000000007ffffff
0000000000000000-ffffffffffffffff (prio -1, i/o): pci
00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-ram @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-pci @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-rom @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, i/o): alias pam-pci @pci 00000000000c8000-00000000000cbfff
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-ram @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-pci @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-rom @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, i/o): alias pam-pci @pci 00000000000cc000-00000000000cffff
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, i/o): alias pam-pci @pci 00000000000d0000-00000000000d3fff
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, i/o): alias pam-pci @pci 00000000000d4000-00000000000d7fff
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-ram @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-pci @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-rom @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, i/o): alias pam-pci @pci 00000000000d8000-00000000000dbfff
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-ram @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-pci @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-rom @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, i/o): alias pam-pci @pci 00000000000dc000-00000000000dffff
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, i/o): alias pam-pci @pci 00000000000e0000-00000000000e3fff
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, i/o): alias pam-pci @pci 00000000000e4000-00000000000e7fff
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-ram @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-pci @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-rom @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, i/o): alias pam-pci @pci 00000000000e8000-00000000000ebfff
00000000000ec000-00000000000effff (prio 1, ram): alias pam-ram @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, ram): alias pam-pci @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, ram): alias pam-rom @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, i/o): alias pam-pci @pci 00000000000ec000-00000000000effff
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-ram @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-pci @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-rom @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, i/o): alias pam-pci @pci 00000000000f0000-00000000000fffff
00000000fec00000-00000000fec00fff (prio 0, i/o): ioapic
00000000fed00000-00000000fed003ff (prio 0, i/o): hpet
00000000fee00000-00000000feefffff (prio 4096, i/o): apic-msi
After:
(qemu) info mtree
memory-region: system
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): alias ram-below-4g @pc.ram 0000000000000000-0000000007ffffff
0000000000000000-ffffffffffffffff (prio -1, i/o): pci
00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
00000000000c8000-00000000000cbfff (prio 1, i/o): alias pam-pci @pci 00000000000c8000-00000000000cbfff
00000000000cc000-00000000000cffff (prio 1, i/o): alias pam-pci @pci 00000000000cc000-00000000000cffff
00000000000d0000-00000000000d3fff (prio 1, i/o): alias pam-pci @pci 00000000000d0000-00000000000d3fff
00000000000d4000-00000000000d7fff (prio 1, i/o): alias pam-pci @pci 00000000000d4000-00000000000d7fff
00000000000d8000-00000000000dbfff (prio 1, i/o): alias pam-pci @pci 00000000000d8000-00000000000dbfff
00000000000dc000-00000000000dffff (prio 1, i/o): alias pam-pci @pci 00000000000dc000-00000000000dffff
00000000000e0000-00000000000e3fff (prio 1, i/o): alias pam-pci @pci 00000000000e0000-00000000000e3fff
00000000000e4000-00000000000e7fff (prio 1, i/o): alias pam-pci @pci 00000000000e4000-00000000000e7fff
00000000000e8000-00000000000ebfff (prio 1, i/o): alias pam-pci @pci 00000000000e8000-00000000000ebfff
00000000000ec000-00000000000effff (prio 1, i/o): alias pam-pci @pci 00000000000ec000-00000000000effff
00000000000f0000-00000000000fffff (prio 1, i/o): alias pam-pci @pci 00000000000f0000-00000000000fffff
00000000fec00000-00000000fec00fff (prio 0, i/o): ioapic
00000000fed00000-00000000fed003ff (prio 0, i/o): hpet
00000000fee00000-00000000feefffff (prio 4096, i/o): apic-msi
The old behavior is preserved using 'info mtree -D'.
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-05-29 14:53:25 +02:00
|
|
|
bool disabled = qdict_get_try_bool(qdict, "disabled", false);
|
2017-01-16 09:40:05 +01:00
|
|
|
|
memory: Make 'info mtree' not display disabled regions by default
We might have many disabled memory regions, making the 'info mtree'
output too verbose to be useful.
Remove the disabled regions in the default output, but allow the
monitor user to display them using the '-D' option.
Before:
(qemu) info mtree
memory-region: system
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): alias ram-below-4g @pc.ram 0000000000000000-0000000007ffffff
0000000000000000-ffffffffffffffff (prio -1, i/o): pci
00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000c0000-00000000000c3fff [disabled]
00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000c4000-00000000000c7fff [disabled]
00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-ram @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-pci @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, ram): alias pam-rom @pc.ram 00000000000c8000-00000000000cbfff [disabled]
00000000000c8000-00000000000cbfff (prio 1, i/o): alias pam-pci @pci 00000000000c8000-00000000000cbfff
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-ram @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-pci @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, ram): alias pam-rom @pc.ram 00000000000cc000-00000000000cffff [disabled]
00000000000cc000-00000000000cffff (prio 1, i/o): alias pam-pci @pci 00000000000cc000-00000000000cffff
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000d0000-00000000000d3fff [disabled]
00000000000d0000-00000000000d3fff (prio 1, i/o): alias pam-pci @pci 00000000000d0000-00000000000d3fff
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000d4000-00000000000d7fff [disabled]
00000000000d4000-00000000000d7fff (prio 1, i/o): alias pam-pci @pci 00000000000d4000-00000000000d7fff
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-ram @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-pci @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, ram): alias pam-rom @pc.ram 00000000000d8000-00000000000dbfff [disabled]
00000000000d8000-00000000000dbfff (prio 1, i/o): alias pam-pci @pci 00000000000d8000-00000000000dbfff
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-ram @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-pci @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, ram): alias pam-rom @pc.ram 00000000000dc000-00000000000dffff [disabled]
00000000000dc000-00000000000dffff (prio 1, i/o): alias pam-pci @pci 00000000000dc000-00000000000dffff
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-ram @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-pci @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, ram): alias pam-rom @pc.ram 00000000000e0000-00000000000e3fff [disabled]
00000000000e0000-00000000000e3fff (prio 1, i/o): alias pam-pci @pci 00000000000e0000-00000000000e3fff
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-ram @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-pci @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, ram): alias pam-rom @pc.ram 00000000000e4000-00000000000e7fff [disabled]
00000000000e4000-00000000000e7fff (prio 1, i/o): alias pam-pci @pci 00000000000e4000-00000000000e7fff
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-ram @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-pci @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, ram): alias pam-rom @pc.ram 00000000000e8000-00000000000ebfff [disabled]
00000000000e8000-00000000000ebfff (prio 1, i/o): alias pam-pci @pci 00000000000e8000-00000000000ebfff
00000000000ec000-00000000000effff (prio 1, ram): alias pam-ram @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, ram): alias pam-pci @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, ram): alias pam-rom @pc.ram 00000000000ec000-00000000000effff [disabled]
00000000000ec000-00000000000effff (prio 1, i/o): alias pam-pci @pci 00000000000ec000-00000000000effff
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-ram @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-pci @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, ram): alias pam-rom @pc.ram 00000000000f0000-00000000000fffff [disabled]
00000000000f0000-00000000000fffff (prio 1, i/o): alias pam-pci @pci 00000000000f0000-00000000000fffff
00000000fec00000-00000000fec00fff (prio 0, i/o): ioapic
00000000fed00000-00000000fed003ff (prio 0, i/o): hpet
00000000fee00000-00000000feefffff (prio 4096, i/o): apic-msi
After:
(qemu) info mtree
memory-region: system
0000000000000000-ffffffffffffffff (prio 0, i/o): system
0000000000000000-0000000007ffffff (prio 0, ram): alias ram-below-4g @pc.ram 0000000000000000-0000000007ffffff
0000000000000000-ffffffffffffffff (prio -1, i/o): pci
00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
00000000000e0000-00000000000fffff (prio 1, rom): alias isa-bios @pc.bios 0000000000020000-000000000003ffff
00000000fffc0000-00000000ffffffff (prio 0, rom): pc.bios
00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
00000000000c8000-00000000000cbfff (prio 1, i/o): alias pam-pci @pci 00000000000c8000-00000000000cbfff
00000000000cc000-00000000000cffff (prio 1, i/o): alias pam-pci @pci 00000000000cc000-00000000000cffff
00000000000d0000-00000000000d3fff (prio 1, i/o): alias pam-pci @pci 00000000000d0000-00000000000d3fff
00000000000d4000-00000000000d7fff (prio 1, i/o): alias pam-pci @pci 00000000000d4000-00000000000d7fff
00000000000d8000-00000000000dbfff (prio 1, i/o): alias pam-pci @pci 00000000000d8000-00000000000dbfff
00000000000dc000-00000000000dffff (prio 1, i/o): alias pam-pci @pci 00000000000dc000-00000000000dffff
00000000000e0000-00000000000e3fff (prio 1, i/o): alias pam-pci @pci 00000000000e0000-00000000000e3fff
00000000000e4000-00000000000e7fff (prio 1, i/o): alias pam-pci @pci 00000000000e4000-00000000000e7fff
00000000000e8000-00000000000ebfff (prio 1, i/o): alias pam-pci @pci 00000000000e8000-00000000000ebfff
00000000000ec000-00000000000effff (prio 1, i/o): alias pam-pci @pci 00000000000ec000-00000000000effff
00000000000f0000-00000000000fffff (prio 1, i/o): alias pam-pci @pci 00000000000f0000-00000000000fffff
00000000fec00000-00000000fec00fff (prio 0, i/o): ioapic
00000000fed00000-00000000fed003ff (prio 0, i/o): hpet
00000000fee00000-00000000feefffff (prio 4096, i/o): apic-msi
The old behavior is preserved using 'info mtree -D'.
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-05-29 14:53:25 +02:00
|
|
|
mtree_info(flatview, dispatch_tree, owner, disabled);
|
2011-09-11 22:22:05 +02:00
|
|
|
}
|
|
|
|
|
2010-09-30 21:00:22 +02:00
|
|
|
/* Please update hmp-commands.hx when adding or changing commands */
|
2019-06-13 17:33:56 +02:00
|
|
|
static HMPCommand hmp_info_cmds[] = {
|
2015-09-10 17:38:58 +02:00
|
|
|
#include "hmp-commands-info.h"
|
|
|
|
{ NULL, NULL, },
|
2004-03-14 22:38:27 +01:00
|
|
|
};
|
|
|
|
|
2019-06-13 17:33:56 +02:00
|
|
|
/* hmp_cmds and hmp_info_cmds would be sorted at runtime */
|
2019-06-13 17:34:01 +02:00
|
|
|
HMPCommand hmp_cmds[] = {
|
2013-01-14 07:06:28 +01:00
|
|
|
#include "hmp-commands.h"
|
|
|
|
{ NULL, NULL, },
|
|
|
|
};
|
|
|
|
|
2019-06-13 17:34:01 +02:00
|
|
|
/*
|
|
|
|
* Set @pval to the value in the register identified by @name.
|
|
|
|
* return 0 if OK, -1 if not found
|
|
|
|
*/
|
2020-11-13 12:43:24 +01:00
|
|
|
int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
|
2004-04-04 14:57:25 +02:00
|
|
|
{
|
2015-09-10 17:38:59 +02:00
|
|
|
const MonitorDef *md = target_monitor_defs();
|
2020-11-13 12:43:24 +01:00
|
|
|
CPUState *cs = mon_get_cpu(mon);
|
2005-02-10 23:00:52 +01:00
|
|
|
void *ptr;
|
2015-11-12 04:44:23 +01:00
|
|
|
uint64_t tmp = 0;
|
|
|
|
int ret;
|
2005-02-10 23:00:52 +01:00
|
|
|
|
2017-01-13 13:12:35 +01:00
|
|
|
if (cs == NULL || md == NULL) {
|
2015-09-10 17:38:59 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(; md->name != NULL; md++) {
|
2019-06-13 17:34:01 +02:00
|
|
|
if (hmp_compare_cmd(name, md->name)) {
|
2004-04-04 14:57:25 +02:00
|
|
|
if (md->get_value) {
|
2020-11-13 12:43:25 +01:00
|
|
|
*pval = md->get_value(mon, md, md->offset);
|
2004-04-04 14:57:25 +02:00
|
|
|
} else {
|
hmp: Pass monitor to mon_get_cpu_env()
mon_get_cpu_env() is indirectly called monitor_parse_arguments() where
the current monitor isn't set yet. Instead of using monitor_cur_env(),
explicitly pass the Monitor pointer to the function.
Without this fix, an HMP command like "x $pc" crashes like this:
#0 0x0000555555caa01f in mon_get_cpu_sync (mon=0x0, synchronize=true) at ../monitor/misc.c:270
#1 0x0000555555caa141 in mon_get_cpu (mon=0x0) at ../monitor/misc.c:294
#2 0x0000555555caa158 in mon_get_cpu_env () at ../monitor/misc.c:299
#3 0x0000555555b19739 in monitor_get_pc (mon=0x555556ad2de0, md=0x5555565d2d40 <monitor_defs+1152>, val=0) at ../target/i386/monitor.c:607
#4 0x0000555555cadbec in get_monitor_def (mon=0x555556ad2de0, pval=0x7fffffffc208, name=0x7fffffffc220 "pc") at ../monitor/misc.c:1681
#5 0x000055555582ec4f in expr_unary (mon=0x555556ad2de0) at ../monitor/hmp.c:387
#6 0x000055555582edbb in expr_prod (mon=0x555556ad2de0) at ../monitor/hmp.c:421
#7 0x000055555582ee79 in expr_logic (mon=0x555556ad2de0) at ../monitor/hmp.c:455
#8 0x000055555582eefe in expr_sum (mon=0x555556ad2de0) at ../monitor/hmp.c:484
#9 0x000055555582efe8 in get_expr (mon=0x555556ad2de0, pval=0x7fffffffc418, pp=0x7fffffffc408) at ../monitor/hmp.c:511
#10 0x000055555582fcd4 in monitor_parse_arguments (mon=0x555556ad2de0, endp=0x7fffffffc890, cmd=0x555556675b50 <hmp_cmds+7920>) at ../monitor/hmp.c:876
#11 0x00005555558306a8 in handle_hmp_command (mon=0x555556ad2de0, cmdline=0x555556ada452 "$pc") at ../monitor/hmp.c:1087
#12 0x000055555582df14 in monitor_command_cb (opaque=0x555556ad2de0, cmdline=0x555556ada450 "x $pc", readline_opaque=0x0) at ../monitor/hmp.c:47
After this fix, nothing is left in monitor_parse_arguments() that can
indirectly call monitor_cur(), so the fix is complete.
Fixes: ff04108a0e36e822519c517bd3bddbc1c7747c18
Reported-by: lichun <lichun@ruijie.com.cn>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201113114326.97663-4-kwolf@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2020-11-13 12:43:26 +01:00
|
|
|
CPUArchState *env = mon_get_cpu_env(mon);
|
2005-11-22 00:25:50 +01:00
|
|
|
ptr = (uint8_t *)env + md->offset;
|
2005-02-10 23:00:52 +01:00
|
|
|
switch(md->type) {
|
|
|
|
case MD_I32:
|
|
|
|
*pval = *(int32_t *)ptr;
|
|
|
|
break;
|
|
|
|
case MD_TLONG:
|
|
|
|
*pval = *(target_long *)ptr;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*pval = 0;
|
|
|
|
break;
|
|
|
|
}
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2015-11-12 04:44:23 +01:00
|
|
|
|
2017-01-13 13:12:35 +01:00
|
|
|
ret = target_get_monitor_def(cs, name, &tmp);
|
2015-11-12 04:44:23 +01:00
|
|
|
if (!ret) {
|
|
|
|
*pval = (target_long) tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2004-04-04 14:57:25 +02:00
|
|
|
}
|
|
|
|
|
2011-10-12 05:32:41 +02:00
|
|
|
static int
|
|
|
|
compare_mon_cmd(const void *a, const void *b)
|
|
|
|
{
|
2019-06-13 17:33:56 +02:00
|
|
|
return strcmp(((const HMPCommand *)a)->name,
|
|
|
|
((const HMPCommand *)b)->name);
|
2011-10-12 05:32:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sortcmdlist(void)
|
|
|
|
{
|
2019-06-13 17:33:56 +02:00
|
|
|
qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1,
|
|
|
|
sizeof(*hmp_cmds),
|
|
|
|
compare_mon_cmd);
|
|
|
|
qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1,
|
|
|
|
sizeof(*hmp_info_cmds),
|
|
|
|
compare_mon_cmd);
|
2011-10-12 05:32:41 +02:00
|
|
|
}
|
|
|
|
|
2021-06-24 12:38:32 +02:00
|
|
|
void monitor_register_hmp(const char *name, bool info,
|
|
|
|
void (*cmd)(Monitor *mon, const QDict *qdict))
|
|
|
|
{
|
|
|
|
HMPCommand *table = info ? hmp_info_cmds : hmp_cmds;
|
|
|
|
|
|
|
|
while (table->name != NULL) {
|
|
|
|
if (strcmp(table->name, name) == 0) {
|
2021-10-08 16:09:00 +02:00
|
|
|
g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL);
|
2021-06-24 12:38:32 +02:00
|
|
|
table->cmd = cmd;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
table++;
|
|
|
|
}
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
2021-10-08 16:09:00 +02:00
|
|
|
void monitor_register_hmp_info_hrt(const char *name,
|
|
|
|
HumanReadableText *(*handler)(Error **errp))
|
|
|
|
{
|
|
|
|
HMPCommand *table = hmp_info_cmds;
|
|
|
|
|
|
|
|
while (table->name != NULL) {
|
|
|
|
if (strcmp(table->name, name) == 0) {
|
|
|
|
g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL);
|
|
|
|
table->cmd_info_hrt = handler;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
table++;
|
|
|
|
}
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
2018-03-09 09:59:50 +01:00
|
|
|
void monitor_init_globals(void)
|
|
|
|
{
|
2019-06-13 17:34:02 +02:00
|
|
|
monitor_init_globals_core();
|
2018-03-09 09:59:50 +01:00
|
|
|
monitor_init_qmp_commands();
|
|
|
|
sortcmdlist();
|
2004-04-04 15:07:25 +02:00
|
|
|
}
|